diff --git a/hw/bsp/nordic_pca10056/src/hal_bsp.c b/hw/bsp/nordic_pca10056/src/hal_bsp.c index 9f8ba8da12..827b8fa059 100644 --- a/hw/bsp/nordic_pca10056/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10056/src/hal_bsp.c @@ -27,6 +27,7 @@ #include "hal/hal_flash.h" #include "hal/hal_system.h" #include "mcu/nrf52_hal.h" +#include "mcu/nrf52_hw_id.h" #include "mcu/nrf52_periph.h" #include "bsp/bsp.h" @@ -95,6 +96,63 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri) return cfg_pri; } +static int +prov_data_hw_id(void *data, uint16_t *length) +{ + uint16_t len = nrf52_hw_id_len(); + + if (*length < len) { + *length = len; + return SYS_ENOMEM; + } + + *length = nrf52_hw_id(data, *length); + + return 0; +} + +static int +prov_data_ble_public_addr(void *data, uint16_t *length) +{ + if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { + return SYS_ENOENT; + } + + memcpy(data, (void *)&NRF_FICR->DEVICEADDR[0], 6); + + return 0; +} + +static int +prov_data_ble_static_addr(void *data, uint16_t *length) +{ + uint8_t *addr = data; + + if ((NRF_FICR->DEVICEADDRTYPE & 1) == 0) { + return SYS_ENOENT; + } + + memcpy(data, (void *)&NRF_FICR->DEVICEADDR[0], 6); + addr[5] |= 0xc0; + + return 0; +} + +int +hal_bsp_prov_data_get_int(uint16_t id, void *data, uint16_t *length) +{ + switch (id) { + case HAL_BSP_PROV_HW_ID: + return prov_data_hw_id(data, length); + case HAL_BSP_PROV_BLE_PUBLIC_ADDR: + return prov_data_ble_public_addr(data, length); + case HAL_BSP_PROV_BLE_STATIC_ADDR: + return prov_data_ble_static_addr(data, length); + } + + return SYS_ENOTSUP; +} + void hal_bsp_init(void) { diff --git a/hw/hal/include/hal/hal_bsp.h b/hw/hal/include/hal/hal_bsp.h index d141f28791..b7043223c2 100644 --- a/hw/hal/include/hal/hal_bsp.h +++ b/hw/hal/include/hal/hal_bsp.h @@ -68,6 +68,7 @@ const struct hal_bsp_mem_dump *hal_bsp_core_dump(int *area_cnt); * * @return The length of the hardware ID. */ +__attribute__((deprecated)) int hal_bsp_hw_id_len(void); /** @@ -79,6 +80,7 @@ int hal_bsp_hw_id_len(void); * * @return 0 on success, non-zero error code on failure */ +__attribute__((deprecated)) int hal_bsp_hw_id(uint8_t *id, int max_len); /** Full System On */ @@ -122,6 +124,56 @@ int hal_bsp_power_state(int state); */ uint32_t hal_bsp_get_nvic_priority(int irq_num, uint32_t pri); +/* Provisioned data identifiers */ +#define HAL_BSP_PROV_HW_ID 0x0001 +#define HAL_BSP_PROV_BLE_PUBLIC_ADDR 0x0002 +#define HAL_BSP_PROV_BLE_STATIC_ADDR 0x0003 +#define HAL_BSP_PROV_BLE_IRK 0x0004 +/* First id for user-defined data identifiers */ +#define HAL_BSP_PROV_USER 0x8000 + +/** + * Get provisioned data + * + * \p length input value shall be set to size of buffer pointer by \p data. + * + * If provided buffer is too small, SYS_ENOMEM is returned and \p length is set + * to minimum required buffer size. + * + * On success \p length is is updated to length of data written to buffer. + * + * @param id provisioned data identifier + * @param data output buffer to store data + * @param length length + * + * @return 0 on success + * SYS_EINVAL if \p data or \p length is NULL + * SYS_ENOMEM if provided buffer size it too small + * SYS_ENOENT if requested data is not provisioned + * SYS_ENOTSUP if requested data identifier is not supported + */ +int hal_bsp_prov_data_get(uint16_t id, void *data, uint16_t *length); + +typedef int (* hal_bsp_prov_data_cb)(uint16_t id, void *data, uint16_t *length); + +/** + * Set custom callback to override provisioned data + * + * Sets callback which is called prior to BSP code and can override handling + * for selected data identifiers. + * + * Callback parameters and behavior shall be the same as hal_bsp_prov_data(). + * + * Callback can be registered only once. + * + * @param cb Data callback + * + * @return 0 on success + * SYS_EINVAL if \p cb is NULL + * SYS_EALREADY if callback is already registered + */ +int hal_bsp_prov_data_set_cb(hal_bsp_prov_data_cb cb); + #ifdef __cplusplus } #endif diff --git a/hw/hal/include/hal/hal_bsp_int.h b/hw/hal/include/hal/hal_bsp_int.h new file mode 100644 index 0000000000..9fcd6620e8 --- /dev/null +++ b/hw/hal/include/hal/hal_bsp_int.h @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __HAL_BSP_INT_H_ +#define __HAL_BSP_INT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Below API shall be defined by BSP to provide provisioned data. It will be + * called by generic hal_bsp_prov_data_get(). + */ + +int hal_bsp_prov_data_get_int(uint16_t id, void *data, uint16_t *length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/hal/src/hal_bsp.c b/hw/hal/src/hal_bsp.c new file mode 100644 index 0000000000..a6d3024b98 --- /dev/null +++ b/hw/hal/src/hal_bsp.c @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "hal/hal_bsp.h" +#include "hal/hal_bsp_int.h" +#include "defs/error.h" + +static hal_bsp_prov_data_cb g_hal_bsp_prov_data_cb; + +int +hal_bsp_prov_data_get(uint16_t id, void *data, uint16_t *length) +{ + int rc; + + if (!data || !length) { + return SYS_EINVAL; + } + + /* + * Check length for well-known data. Also adjust length so data providers + * do not need to check this again. + */ + switch (id) { + case HAL_BSP_PROV_BLE_PUBLIC_ADDR: + case HAL_BSP_PROV_BLE_STATIC_ADDR: + if (*length < 6) { + *length = 6; + return SYS_ENOMEM; + } + *length = 6; + break; + case HAL_BSP_PROV_BLE_IRK: + if (*length < 16) { + *length = 16; + return SYS_ENOMEM; + } + *length = 16; + break; + } + + if (g_hal_bsp_prov_data_cb) { + rc = g_hal_bsp_prov_data_cb(id, data, length); + if (rc != SYS_ENOTSUP) { + return rc; + } + } + + return hal_bsp_prov_data_get_int(id, data, length); +} + +int +hal_bsp_prov_data_set_cb(hal_bsp_prov_data_cb cb) +{ + if (!cb) { + return SYS_EINVAL; + } + + if (g_hal_bsp_prov_data_cb) { + return SYS_EALREADY; + } + + g_hal_bsp_prov_data_cb = cb; + + return 0; +} diff --git a/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h new file mode 100644 index 0000000000..58d2110362 --- /dev/null +++ b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_NRF52_HW_ID_ +#define H_NRF52_HW_ID_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int nrf52_hw_id_len(void); +int nrf52_hw_id(uint8_t *id, int max_len); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_HW_ID_ */ diff --git a/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c b/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c index ca916bf22b..95b19e5913 100644 --- a/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c +++ b/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c @@ -20,6 +20,7 @@ #include #include #include +#include "mcu/nrf52_hw_id.h" #include "nrf.h" #ifndef min @@ -27,7 +28,7 @@ #endif int -hal_bsp_hw_id_len(void) +nrf52_hw_id_len(void) { return sizeof(NRF_FICR->DEVICEID) + sizeof(NRF_FICR->DEVICEADDR); } @@ -37,7 +38,7 @@ hal_bsp_hw_id_len(void) * DEVICEID[0-1] and DEVICEADDR[0-1]. */ int -hal_bsp_hw_id(uint8_t *id, int max_len) +nrf52_hw_id(uint8_t *id, int max_len) { int len, cnt; @@ -50,3 +51,15 @@ hal_bsp_hw_id(uint8_t *id, int max_len) return len + cnt; } + +int +hal_bsp_hw_id_len(void) +{ + return nrf52_hw_id_len(); +} + +int +hal_bsp_hw_id(uint8_t *id, int max_len) +{ + return nrf52_hw_id(id, max_len); +}