1*1664436fSMatthias Ringwald /* 2*1664436fSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*1664436fSMatthias Ringwald * 4*1664436fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*1664436fSMatthias Ringwald * modification, are permitted provided that the following conditions 6*1664436fSMatthias Ringwald * are met: 7*1664436fSMatthias Ringwald * 8*1664436fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*1664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*1664436fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*1664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*1664436fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*1664436fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*1664436fSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*1664436fSMatthias Ringwald * from this software without specific prior written permission. 16*1664436fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*1664436fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*1664436fSMatthias Ringwald * monetary gain. 19*1664436fSMatthias Ringwald * 20*1664436fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*1664436fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*1664436fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*1664436fSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*1664436fSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*1664436fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*1664436fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*1664436fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*1664436fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*1664436fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*1664436fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*1664436fSMatthias Ringwald * SUCH DAMAGE. 32*1664436fSMatthias Ringwald * 33*1664436fSMatthias Ringwald * Please inquire about commercial licensing options at 34*1664436fSMatthias Ringwald * [email protected] 35*1664436fSMatthias Ringwald * 36*1664436fSMatthias Ringwald */ 37*1664436fSMatthias Ringwald 38*1664436fSMatthias Ringwald // ***************************************************************************** 39*1664436fSMatthias Ringwald // 40*1664436fSMatthias Ringwald // accel_demo 41*1664436fSMatthias Ringwald // 42*1664436fSMatthias Ringwald // ***************************************************************************** 43*1664436fSMatthias Ringwald 44*1664436fSMatthias Ringwald #include <stdint.h> 45*1664436fSMatthias Ringwald #include <stdio.h> 46*1664436fSMatthias Ringwald #include <stdlib.h> 47*1664436fSMatthias Ringwald #include <string.h> 48*1664436fSMatthias Ringwald 49*1664436fSMatthias Ringwald #include <msp430x54x.h> 50*1664436fSMatthias Ringwald 51*1664436fSMatthias Ringwald #include "btstack_chipset_cc256x.h" 52*1664436fSMatthias Ringwald #include "hal_adc.h" 53*1664436fSMatthias Ringwald #include "hal_board.h" 54*1664436fSMatthias Ringwald #include "hal_compat.h" 55*1664436fSMatthias Ringwald #include "hal_usb.h" 56*1664436fSMatthias Ringwald 57*1664436fSMatthias Ringwald #include "hci_cmd.h" 58*1664436fSMatthias Ringwald #include "btstack_run_loop.h" 59*1664436fSMatthias Ringwald #include "classic/sdp_util.h" 60*1664436fSMatthias Ringwald 61*1664436fSMatthias Ringwald #include "hci.h" 62*1664436fSMatthias Ringwald #include "l2cap.h" 63*1664436fSMatthias Ringwald #include "btstack_memory.h" 64*1664436fSMatthias Ringwald #include "classic/btstack_link_key_db.h" 65*1664436fSMatthias Ringwald #include "classic/rfcomm.h" 66*1664436fSMatthias Ringwald #include "classic/sdp_server.h" 67*1664436fSMatthias Ringwald #include "btstack_config.h" 68*1664436fSMatthias Ringwald 69*1664436fSMatthias Ringwald #define HEARTBEAT_PERIOD_MS 1000 70*1664436fSMatthias Ringwald 71*1664436fSMatthias Ringwald #define FONT_HEIGHT 12 // Each character has 13 lines 72*1664436fSMatthias Ringwald #define FONT_WIDTH 8 73*1664436fSMatthias Ringwald static int row = 0; 74*1664436fSMatthias Ringwald char lineBuffer[80]; 75*1664436fSMatthias Ringwald 76*1664436fSMatthias Ringwald static uint8_t rfcomm_channel_nr = 1; 77*1664436fSMatthias Ringwald static uint16_t rfcomm_channel_id; 78*1664436fSMatthias Ringwald static uint8_t spp_service_buffer[150]; 79*1664436fSMatthias Ringwald 80*1664436fSMatthias Ringwald // SPP description 81*1664436fSMatthias Ringwald static uint8_t accel_buffer[6]; 82*1664436fSMatthias Ringwald 83*1664436fSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 84*1664436fSMatthias Ringwald 85*1664436fSMatthias Ringwald static void prepare_accel_packet(void){ 86*1664436fSMatthias Ringwald int16_t accl_x; 87*1664436fSMatthias Ringwald int16_t accl_y; 88*1664436fSMatthias Ringwald int16_t accl_z; 89*1664436fSMatthias Ringwald 90*1664436fSMatthias Ringwald /* read the digital accelerometer x- direction and y - direction output */ 91*1664436fSMatthias Ringwald halAccelerometerRead((int *)&accl_x, (int *)&accl_y, (int *)&accl_z); 92*1664436fSMatthias Ringwald 93*1664436fSMatthias Ringwald accel_buffer[0] = 0x01; // Start of "header" 94*1664436fSMatthias Ringwald accel_buffer[1] = accl_x; 95*1664436fSMatthias Ringwald accel_buffer[2] = (accl_x >> 8); 96*1664436fSMatthias Ringwald accel_buffer[3] = accl_y; 97*1664436fSMatthias Ringwald accel_buffer[4] = (accl_y >> 8); 98*1664436fSMatthias Ringwald int index; 99*1664436fSMatthias Ringwald uint8_t checksum = 0; 100*1664436fSMatthias Ringwald for (index = 0; index < 5; index++) { 101*1664436fSMatthias Ringwald checksum += accel_buffer[index]; 102*1664436fSMatthias Ringwald } 103*1664436fSMatthias Ringwald accel_buffer[5] = checksum; 104*1664436fSMatthias Ringwald 105*1664436fSMatthias Ringwald /* start the ADC to read the next accelerometer output */ 106*1664436fSMatthias Ringwald halAdcStartRead(); 107*1664436fSMatthias Ringwald 108*1664436fSMatthias Ringwald printf("Accel: X: %04d, Y: %04d, Z: %04d\n\r", accl_x, accl_y, accl_z); 109*1664436fSMatthias Ringwald } 110*1664436fSMatthias Ringwald 111*1664436fSMatthias Ringwald static void send_packet(void){ 112*1664436fSMatthias Ringwald int err = rfcomm_send(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); 113*1664436fSMatthias Ringwald switch(err){ 114*1664436fSMatthias Ringwald case 0: 115*1664436fSMatthias Ringwald prepare_accel_packet(); 116*1664436fSMatthias Ringwald break; 117*1664436fSMatthias Ringwald case BTSTACK_ACL_BUFFERS_FULL: 118*1664436fSMatthias Ringwald break; 119*1664436fSMatthias Ringwald default: 120*1664436fSMatthias Ringwald printf("rfcomm_send() -> err %d\n\r", err); 121*1664436fSMatthias Ringwald break; 122*1664436fSMatthias Ringwald } 123*1664436fSMatthias Ringwald } 124*1664436fSMatthias Ringwald 125*1664436fSMatthias Ringwald // Bluetooth logic 126*1664436fSMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 127*1664436fSMatthias Ringwald bd_addr_t event_addr; 128*1664436fSMatthias Ringwald uint8_t rfcomm_channel_nr; 129*1664436fSMatthias Ringwald uint16_t mtu; 130*1664436fSMatthias Ringwald int err; 131*1664436fSMatthias Ringwald 132*1664436fSMatthias Ringwald switch (packet_type) { 133*1664436fSMatthias Ringwald case HCI_EVENT_PACKET: 134*1664436fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 135*1664436fSMatthias Ringwald 136*1664436fSMatthias Ringwald case BTSTACK_EVENT_STATE: 137*1664436fSMatthias Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 138*1664436fSMatthias Ringwald printf("BTstack is up and running.\n"); 139*1664436fSMatthias Ringwald } 140*1664436fSMatthias Ringwald break; 141*1664436fSMatthias Ringwald 142*1664436fSMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 143*1664436fSMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){ 144*1664436fSMatthias Ringwald reverse_bd_addr(&packet[6], event_addr); 145*1664436fSMatthias Ringwald printf("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr)); 146*1664436fSMatthias Ringwald break; 147*1664436fSMatthias Ringwald } 148*1664436fSMatthias Ringwald break; 149*1664436fSMatthias Ringwald 150*1664436fSMatthias Ringwald case HCI_EVENT_LINK_KEY_REQUEST: 151*1664436fSMatthias Ringwald // deny link key request 152*1664436fSMatthias Ringwald printf("Link key request\n\r"); 153*1664436fSMatthias Ringwald hci_event_link_key_request_get_bd_addr(packet, event_addr); 154*1664436fSMatthias Ringwald hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr); 155*1664436fSMatthias Ringwald break; 156*1664436fSMatthias Ringwald 157*1664436fSMatthias Ringwald case HCI_EVENT_PIN_CODE_REQUEST: 158*1664436fSMatthias Ringwald // inform about pin code request 159*1664436fSMatthias Ringwald printf("Pin code request - using '0000'\n\r"); 160*1664436fSMatthias Ringwald hci_event_pin_code_request_get_bd_addr(packet, event_addr); 161*1664436fSMatthias Ringwald hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); 162*1664436fSMatthias Ringwald break; 163*1664436fSMatthias Ringwald 164*1664436fSMatthias Ringwald case RFCOMM_EVENT_INCOMING_CONNECTION: 165*1664436fSMatthias Ringwald // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 166*1664436fSMatthias Ringwald rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 167*1664436fSMatthias Ringwald rfcomm_channel_nr = rfcomm_event_incoming_connection_get_server_channel(packet); 168*1664436fSMatthias Ringwald rfcomm_channel_id = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 169*1664436fSMatthias Ringwald printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr)); 170*1664436fSMatthias Ringwald rfcomm_accept_connection(rfcomm_channel_id); 171*1664436fSMatthias Ringwald break; 172*1664436fSMatthias Ringwald 173*1664436fSMatthias Ringwald case RFCOMM_EVENT_CHANNEL_OPENED: 174*1664436fSMatthias Ringwald // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16) 175*1664436fSMatthias Ringwald if (rfcomm_event_channel_opened_get_status(packet)) { 176*1664436fSMatthias Ringwald printf("RFCOMM channel open failed, status %u\n", rfcomm_event_channel_opened_get_status(packet)); 177*1664436fSMatthias Ringwald } else { 178*1664436fSMatthias Ringwald rfcomm_channel_id = rfcomm_event_channel_opened_get_rfcomm_cid(packet); 179*1664436fSMatthias Ringwald mtu = rfcomm_event_channel_opened_get_max_frame_size(packet); 180*1664436fSMatthias Ringwald printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu); 181*1664436fSMatthias Ringwald } 182*1664436fSMatthias Ringwald break; 183*1664436fSMatthias Ringwald 184*1664436fSMatthias Ringwald case RFCOMM_EVENT_CAN_SEND_NOW: 185*1664436fSMatthias Ringwald if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); 186*1664436fSMatthias Ringwald break; 187*1664436fSMatthias Ringwald 188*1664436fSMatthias Ringwald case RFCOMM_EVENT_CHANNEL_CLOSED: 189*1664436fSMatthias Ringwald rfcomm_channel_id = 0; 190*1664436fSMatthias Ringwald break; 191*1664436fSMatthias Ringwald 192*1664436fSMatthias Ringwald default: 193*1664436fSMatthias Ringwald break; 194*1664436fSMatthias Ringwald } 195*1664436fSMatthias Ringwald break; 196*1664436fSMatthias Ringwald 197*1664436fSMatthias Ringwald default: 198*1664436fSMatthias Ringwald break; 199*1664436fSMatthias Ringwald } 200*1664436fSMatthias Ringwald } 201*1664436fSMatthias Ringwald 202*1664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]); 203*1664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 204*1664436fSMatthias Ringwald 205*1664436fSMatthias Ringwald // Accel 206*1664436fSMatthias Ringwald halAccelerometerInit(); 207*1664436fSMatthias Ringwald prepare_accel_packet(); 208*1664436fSMatthias Ringwald 209*1664436fSMatthias Ringwald // register for HCI events 210*1664436fSMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 211*1664436fSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 212*1664436fSMatthias Ringwald 213*1664436fSMatthias Ringwald // init L2CAP 214*1664436fSMatthias Ringwald l2cap_init(); 215*1664436fSMatthias Ringwald 216*1664436fSMatthias Ringwald // init RFCOMM 217*1664436fSMatthias Ringwald rfcomm_init(); 218*1664436fSMatthias Ringwald rfcomm_register_service(packet_handler, rfcomm_channel_nr, 100); // reserved channel, mtu=100 219*1664436fSMatthias Ringwald 220*1664436fSMatthias Ringwald // init SDP, create record for SPP and register with SDP 221*1664436fSMatthias Ringwald sdp_init(); 222*1664436fSMatthias Ringwald memset(spp_service_buffer, 0, sizeof(spp_service_buffer)); 223*1664436fSMatthias Ringwald spp_create_sdp_record( (uint8_t*) spp_service_buffer, 0x10001, 1, "SPP Accel"); 224*1664436fSMatthias Ringwald printf("SDP service buffer size: %u\n\r", (uint16_t) de_get_len((uint8_t*) spp_service_buffer)); 225*1664436fSMatthias Ringwald sdp_register_service(spp_service_buffer); 226*1664436fSMatthias Ringwald 227*1664436fSMatthias Ringwald // ready - enable irq used in h4 task 228*1664436fSMatthias Ringwald __enable_interrupt(); 229*1664436fSMatthias Ringwald 230*1664436fSMatthias Ringwald // set local name 231*1664436fSMatthias Ringwald gap_set_local_name("BTstack SPP Sensor"); 232*1664436fSMatthias Ringwald // make discoverable 233*1664436fSMatthias Ringwald gap_discoverable_control(1); 234*1664436fSMatthias Ringwald 235*1664436fSMatthias Ringwald // turn on! 236*1664436fSMatthias Ringwald hci_power_control(HCI_POWER_ON); 237*1664436fSMatthias Ringwald return 0; 238*1664436fSMatthias Ringwald } 239*1664436fSMatthias Ringwald 240*1664436fSMatthias Ringwald /* 241*1664436fSMatthias Ringwald 242*1664436fSMatthias Ringwald rfcomm_send gets called before we have credits 243*1664436fSMatthias Ringwald rfcomm_send returns undefined error codes??? 244*1664436fSMatthias Ringwald 245*1664436fSMatthias Ringwald */ 246*1664436fSMatthias Ringwald 247