11664436fSMatthias Ringwald /* 21664436fSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 31664436fSMatthias Ringwald * 41664436fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 51664436fSMatthias Ringwald * modification, are permitted provided that the following conditions 61664436fSMatthias Ringwald * are met: 71664436fSMatthias Ringwald * 81664436fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 91664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 101664436fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 111664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 121664436fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 131664436fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 141664436fSMatthias Ringwald * contributors may be used to endorse or promote products derived 151664436fSMatthias Ringwald * from this software without specific prior written permission. 161664436fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 171664436fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 181664436fSMatthias Ringwald * monetary gain. 191664436fSMatthias Ringwald * 201664436fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 211664436fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 221664436fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 251664436fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 261664436fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 271664436fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 281664436fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 291664436fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 301664436fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311664436fSMatthias Ringwald * SUCH DAMAGE. 321664436fSMatthias Ringwald * 331664436fSMatthias Ringwald * Please inquire about commercial licensing options at 341664436fSMatthias Ringwald * [email protected] 351664436fSMatthias Ringwald * 361664436fSMatthias Ringwald */ 371664436fSMatthias Ringwald 381664436fSMatthias Ringwald // ***************************************************************************** 391664436fSMatthias Ringwald // 401664436fSMatthias Ringwald // accel_demo 411664436fSMatthias Ringwald // 421664436fSMatthias Ringwald // ***************************************************************************** 431664436fSMatthias Ringwald 441664436fSMatthias Ringwald #include <stdint.h> 451664436fSMatthias Ringwald #include <stdio.h> 461664436fSMatthias Ringwald #include <stdlib.h> 471664436fSMatthias Ringwald #include <string.h> 481664436fSMatthias Ringwald 491664436fSMatthias Ringwald #include <msp430x54x.h> 501664436fSMatthias Ringwald 511664436fSMatthias Ringwald #include "btstack_chipset_cc256x.h" 521664436fSMatthias Ringwald #include "hal_adc.h" 531664436fSMatthias Ringwald #include "hal_board.h" 541664436fSMatthias Ringwald #include "hal_compat.h" 551664436fSMatthias Ringwald #include "hal_usb.h" 561664436fSMatthias Ringwald 571664436fSMatthias Ringwald #include "hci_cmd.h" 581664436fSMatthias Ringwald #include "btstack_run_loop.h" 591664436fSMatthias Ringwald #include "classic/sdp_util.h" 601664436fSMatthias Ringwald 611664436fSMatthias Ringwald #include "hci.h" 621664436fSMatthias Ringwald #include "l2cap.h" 631664436fSMatthias Ringwald #include "btstack_memory.h" 641664436fSMatthias Ringwald #include "classic/btstack_link_key_db.h" 651664436fSMatthias Ringwald #include "classic/rfcomm.h" 661664436fSMatthias Ringwald #include "classic/sdp_server.h" 671664436fSMatthias Ringwald #include "btstack_config.h" 681664436fSMatthias Ringwald 691664436fSMatthias Ringwald #define HEARTBEAT_PERIOD_MS 1000 701664436fSMatthias Ringwald 711664436fSMatthias Ringwald #define FONT_HEIGHT 12 // Each character has 13 lines 721664436fSMatthias Ringwald #define FONT_WIDTH 8 731664436fSMatthias Ringwald static int row = 0; 741664436fSMatthias Ringwald char lineBuffer[80]; 751664436fSMatthias Ringwald 761664436fSMatthias Ringwald static uint8_t rfcomm_channel_nr = 1; 771664436fSMatthias Ringwald static uint16_t rfcomm_channel_id; 781664436fSMatthias Ringwald static uint8_t spp_service_buffer[150]; 791664436fSMatthias Ringwald 801664436fSMatthias Ringwald // SPP description 811664436fSMatthias Ringwald static uint8_t accel_buffer[6]; 821664436fSMatthias Ringwald 831664436fSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 841664436fSMatthias Ringwald 851664436fSMatthias Ringwald static void prepare_accel_packet(void){ 861664436fSMatthias Ringwald int16_t accl_x; 871664436fSMatthias Ringwald int16_t accl_y; 881664436fSMatthias Ringwald int16_t accl_z; 891664436fSMatthias Ringwald 901664436fSMatthias Ringwald /* read the digital accelerometer x- direction and y - direction output */ 911664436fSMatthias Ringwald halAccelerometerRead((int *)&accl_x, (int *)&accl_y, (int *)&accl_z); 921664436fSMatthias Ringwald 931664436fSMatthias Ringwald accel_buffer[0] = 0x01; // Start of "header" 941664436fSMatthias Ringwald accel_buffer[1] = accl_x; 951664436fSMatthias Ringwald accel_buffer[2] = (accl_x >> 8); 961664436fSMatthias Ringwald accel_buffer[3] = accl_y; 971664436fSMatthias Ringwald accel_buffer[4] = (accl_y >> 8); 981664436fSMatthias Ringwald int index; 991664436fSMatthias Ringwald uint8_t checksum = 0; 1001664436fSMatthias Ringwald for (index = 0; index < 5; index++) { 1011664436fSMatthias Ringwald checksum += accel_buffer[index]; 1021664436fSMatthias Ringwald } 1031664436fSMatthias Ringwald accel_buffer[5] = checksum; 1041664436fSMatthias Ringwald 1051664436fSMatthias Ringwald /* start the ADC to read the next accelerometer output */ 1061664436fSMatthias Ringwald halAdcStartRead(); 1071664436fSMatthias Ringwald 1081664436fSMatthias Ringwald printf("Accel: X: %04d, Y: %04d, Z: %04d\n\r", accl_x, accl_y, accl_z); 1091664436fSMatthias Ringwald } 1101664436fSMatthias Ringwald 1111664436fSMatthias Ringwald static void send_packet(void){ 1121664436fSMatthias Ringwald int err = rfcomm_send(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); 1131664436fSMatthias Ringwald switch(err){ 1141664436fSMatthias Ringwald case 0: 1151664436fSMatthias Ringwald prepare_accel_packet(); 1161664436fSMatthias Ringwald break; 1171664436fSMatthias Ringwald case BTSTACK_ACL_BUFFERS_FULL: 1181664436fSMatthias Ringwald break; 1191664436fSMatthias Ringwald default: 1201664436fSMatthias Ringwald printf("rfcomm_send() -> err %d\n\r", err); 1211664436fSMatthias Ringwald break; 1221664436fSMatthias Ringwald } 1231664436fSMatthias Ringwald } 1241664436fSMatthias Ringwald 1251664436fSMatthias Ringwald // Bluetooth logic 1261664436fSMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1271664436fSMatthias Ringwald bd_addr_t event_addr; 1281664436fSMatthias Ringwald uint8_t rfcomm_channel_nr; 1291664436fSMatthias Ringwald uint16_t mtu; 1301664436fSMatthias Ringwald int err; 1311664436fSMatthias Ringwald 1321664436fSMatthias Ringwald switch (packet_type) { 1331664436fSMatthias Ringwald case HCI_EVENT_PACKET: 1341664436fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 1351664436fSMatthias Ringwald 1361664436fSMatthias Ringwald case BTSTACK_EVENT_STATE: 1371664436fSMatthias Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 1381664436fSMatthias Ringwald printf("BTstack is up and running.\n"); 1391664436fSMatthias Ringwald } 1401664436fSMatthias Ringwald break; 1411664436fSMatthias Ringwald 1421664436fSMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 1431664436fSMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){ 1441664436fSMatthias Ringwald reverse_bd_addr(&packet[6], event_addr); 1451664436fSMatthias Ringwald printf("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr)); 1461664436fSMatthias Ringwald break; 1471664436fSMatthias Ringwald } 1481664436fSMatthias Ringwald break; 1491664436fSMatthias Ringwald 1501664436fSMatthias Ringwald case HCI_EVENT_LINK_KEY_REQUEST: 1511664436fSMatthias Ringwald // deny link key request 1521664436fSMatthias Ringwald printf("Link key request\n\r"); 1531664436fSMatthias Ringwald hci_event_link_key_request_get_bd_addr(packet, event_addr); 1541664436fSMatthias Ringwald hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr); 1551664436fSMatthias Ringwald break; 1561664436fSMatthias Ringwald 1571664436fSMatthias Ringwald case HCI_EVENT_PIN_CODE_REQUEST: 1581664436fSMatthias Ringwald // inform about pin code request 1591664436fSMatthias Ringwald printf("Pin code request - using '0000'\n\r"); 1601664436fSMatthias Ringwald hci_event_pin_code_request_get_bd_addr(packet, event_addr); 1611664436fSMatthias Ringwald hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); 1621664436fSMatthias Ringwald break; 1631664436fSMatthias Ringwald 1641664436fSMatthias Ringwald case RFCOMM_EVENT_INCOMING_CONNECTION: 1651664436fSMatthias Ringwald // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 1661664436fSMatthias Ringwald rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 1671664436fSMatthias Ringwald rfcomm_channel_nr = rfcomm_event_incoming_connection_get_server_channel(packet); 1681664436fSMatthias Ringwald rfcomm_channel_id = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 1691664436fSMatthias Ringwald printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr)); 1701664436fSMatthias Ringwald rfcomm_accept_connection(rfcomm_channel_id); 1711664436fSMatthias Ringwald break; 1721664436fSMatthias Ringwald 1731664436fSMatthias Ringwald case RFCOMM_EVENT_CHANNEL_OPENED: 1741664436fSMatthias Ringwald // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16) 1751664436fSMatthias Ringwald if (rfcomm_event_channel_opened_get_status(packet)) { 1761664436fSMatthias Ringwald printf("RFCOMM channel open failed, status %u\n", rfcomm_event_channel_opened_get_status(packet)); 1771664436fSMatthias Ringwald } else { 1781664436fSMatthias Ringwald rfcomm_channel_id = rfcomm_event_channel_opened_get_rfcomm_cid(packet); 1791664436fSMatthias Ringwald mtu = rfcomm_event_channel_opened_get_max_frame_size(packet); 1801664436fSMatthias Ringwald printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu); 1811664436fSMatthias Ringwald } 1821664436fSMatthias Ringwald break; 1831664436fSMatthias Ringwald 1841664436fSMatthias Ringwald case RFCOMM_EVENT_CAN_SEND_NOW: 1851664436fSMatthias Ringwald if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); 1861664436fSMatthias Ringwald break; 1871664436fSMatthias Ringwald 1881664436fSMatthias Ringwald case RFCOMM_EVENT_CHANNEL_CLOSED: 1891664436fSMatthias Ringwald rfcomm_channel_id = 0; 1901664436fSMatthias Ringwald break; 1911664436fSMatthias Ringwald 1921664436fSMatthias Ringwald default: 1931664436fSMatthias Ringwald break; 1941664436fSMatthias Ringwald } 1951664436fSMatthias Ringwald break; 1961664436fSMatthias Ringwald 1971664436fSMatthias Ringwald default: 1981664436fSMatthias Ringwald break; 1991664436fSMatthias Ringwald } 2001664436fSMatthias Ringwald } 2011664436fSMatthias Ringwald 2021664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]); 2031664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 2041664436fSMatthias Ringwald 2051664436fSMatthias Ringwald // Accel 2061664436fSMatthias Ringwald halAccelerometerInit(); 2071664436fSMatthias Ringwald prepare_accel_packet(); 2081664436fSMatthias Ringwald 2091664436fSMatthias Ringwald // register for HCI events 2101664436fSMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 2111664436fSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 2121664436fSMatthias Ringwald 2131664436fSMatthias Ringwald // init L2CAP 2141664436fSMatthias Ringwald l2cap_init(); 2151664436fSMatthias Ringwald 2161664436fSMatthias Ringwald // init RFCOMM 2171664436fSMatthias Ringwald rfcomm_init(); 2181664436fSMatthias Ringwald rfcomm_register_service(packet_handler, rfcomm_channel_nr, 100); // reserved channel, mtu=100 2191664436fSMatthias Ringwald 2201664436fSMatthias Ringwald // init SDP, create record for SPP and register with SDP 2211664436fSMatthias Ringwald sdp_init(); 2221664436fSMatthias Ringwald memset(spp_service_buffer, 0, sizeof(spp_service_buffer)); 2231664436fSMatthias Ringwald spp_create_sdp_record( (uint8_t*) spp_service_buffer, 0x10001, 1, "SPP Accel"); 2241664436fSMatthias Ringwald printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) spp_service_buffer)); 2251664436fSMatthias Ringwald sdp_register_service(spp_service_buffer); 2261664436fSMatthias Ringwald 2271664436fSMatthias Ringwald // ready - enable irq used in h4 task 2281664436fSMatthias Ringwald __enable_interrupt(); 2291664436fSMatthias Ringwald 2301664436fSMatthias Ringwald // set local name 2311664436fSMatthias Ringwald gap_set_local_name("BTstack SPP Sensor"); 2321664436fSMatthias Ringwald // make discoverable 2331664436fSMatthias Ringwald gap_discoverable_control(1); 2341664436fSMatthias Ringwald 2351664436fSMatthias Ringwald // turn on! 2361664436fSMatthias Ringwald hci_power_control(HCI_POWER_ON); 2371664436fSMatthias Ringwald return 0; 2381664436fSMatthias Ringwald } 2391664436fSMatthias Ringwald 2401664436fSMatthias Ringwald /* 2411664436fSMatthias Ringwald 2421664436fSMatthias Ringwald rfcomm_send gets called before we have credits 2431664436fSMatthias Ringwald rfcomm_send returns undefined error codes??? 2441664436fSMatthias Ringwald 2451664436fSMatthias Ringwald */ 2461664436fSMatthias Ringwald 247