xref: /btstack/port/archive/msp-exp430f5438-cc2564b/example/spp_accel.c (revision 1664436fd643daf66517dc309e6cc72448e8a86d)
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