/* * mbed Microcontroller Library * Copyright (c) 2017-2017 ARM Limited * Copyright (c) 2017-2018 Future Electronics * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * 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 "hci_api.h" #include "bstream.h" #include "ble/driver/CordioHCIDriver.h" #include "drivers/IPCPipeTransportDriver.h" #include "psoc6_utils.h" using namespace ble::vendor::cordio; using namespace ble::vendor::cypress; const uint16_t HCI_VEND_SET_BD_ADDR = 0xfda0; const uint8_t HCI_VEND_SET_BD_ADDR_LEN = 7; /* MAC address + address type */ class Psoc6HCIDriver : public CordioHCIDriver { public: Psoc6HCIDriver(IPCPipeTransportDriver& transport_driver) : CordioHCIDriver(transport_driver) { } private: struct BdAddress { uint8_t mac_address[6]; uint8_t addr_type; BdAddress() : addr_type(0) {} }; virtual buf_pool_desc_t get_buffer_pool_description(); /** * Initialize the chip. * The transport is up at that time. */ virtual void do_initialize(); /** * Terminate the driver */ virtual void do_terminate() {} virtual void handle_reset_sequence(uint8_t *pMsg); private: BdAddress bd_address; }; buf_pool_desc_t Psoc6HCIDriver::get_buffer_pool_description() { // Use default buffer pool return ble::CordioHCIDriver::get_default_buffer_pool_description(); } void Psoc6HCIDriver::do_initialize() { cy_get_bd_mac_address(bd_address.mac_address); } void Psoc6HCIDriver::handle_reset_sequence(uint8_t *pMsg) { uint16_t opcode; /* if event is a command complete event */ if (*pMsg == HCI_CMD_CMPL_EVT) { /* parse parameters */ uint8_t *pMsg2 = pMsg + HCI_EVT_HDR_LEN; pMsg2++; /* skip num packets */ BSTREAM_TO_UINT16(opcode, pMsg2); pMsg2 -= 2; /* decode opcode */ switch (opcode) { case HCI_OPCODE_RESET: /* send next command in sequence */ HciVendorSpecificCmd(HCI_VEND_SET_BD_ADDR, HCI_VEND_SET_BD_ADDR_LEN, reinterpret_cast(&bd_address)); break; case HCI_VEND_SET_BD_ADDR: /* pretend we have just completed reset */ UINT16_TO_BSTREAM(pMsg2, HCI_OPCODE_RESET); CordioHCIDriver::handle_reset_sequence(pMsg); break; default: /* pass to parent */ CordioHCIDriver::handle_reset_sequence(pMsg); } } } CordioHCIDriver& ble_cordio_get_hci_driver() { static IPCPipeTransportDriver transport_driver; static Psoc6HCIDriver hci_driver( transport_driver /* other hci driver parameters */ ); return hci_driver; }