xref: /btstack/chipset/cc256x/ant_cmd.c (revision 75a994c4ca66bdd844ab093e82c3abfacd81828f)
1*75a994c4SMatthias Ringwald /*
2*75a994c4SMatthias Ringwald  * Copyright (C) 2009-2012 by Matthias Ringwald
3*75a994c4SMatthias Ringwald  *
4*75a994c4SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*75a994c4SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*75a994c4SMatthias Ringwald  * are met:
7*75a994c4SMatthias Ringwald  *
8*75a994c4SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*75a994c4SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*75a994c4SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*75a994c4SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*75a994c4SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*75a994c4SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*75a994c4SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*75a994c4SMatthias Ringwald  *    from this software without specific prior written permission.
16*75a994c4SMatthias Ringwald  *
17*75a994c4SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
18*75a994c4SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*75a994c4SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20*75a994c4SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
21*75a994c4SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22*75a994c4SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23*75a994c4SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24*75a994c4SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25*75a994c4SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26*75a994c4SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27*75a994c4SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*75a994c4SMatthias Ringwald  * SUCH DAMAGE.
29*75a994c4SMatthias Ringwald  *
30*75a994c4SMatthias Ringwald  */
31*75a994c4SMatthias Ringwald 
32*75a994c4SMatthias Ringwald /*
33*75a994c4SMatthias Ringwald  *  ant_cmds.c
34*75a994c4SMatthias Ringwald  *
35*75a994c4SMatthias Ringwald  *  See http://www.thisisant.com/ for more info on ANT(tm)
36*75a994c4SMatthias Ringwald  *
37*75a994c4SMatthias Ringwald  *  Created by Matthias Ringwald on 2012-11-06.
38*75a994c4SMatthias Ringwald  */
39*75a994c4SMatthias Ringwald 
40*75a994c4SMatthias Ringwald 
41*75a994c4SMatthias Ringwald #include <string.h>
42*75a994c4SMatthias Ringwald 
43*75a994c4SMatthias Ringwald #include "ant_cmds.h"
44*75a994c4SMatthias Ringwald #include "classic/sdp_util.h"
45*75a994c4SMatthias Ringwald #include "btstack-config.h"
46*75a994c4SMatthias Ringwald #include "hci.h"
47*75a994c4SMatthias Ringwald 
48*75a994c4SMatthias Ringwald /**
49*75a994c4SMatthias Ringwald  * construct ANT HCI Command based on template
50*75a994c4SMatthias Ringwald  *
51*75a994c4SMatthias Ringwald  * Format:
52*75a994c4SMatthias Ringwald  *   0: adds a zero byte
53*75a994c4SMatthias Ringwald  *   1,2,3,4: one to four byte value
54*75a994c4SMatthias Ringwald  *   D: pointer to 8 bytes of ANT data
55*75a994c4SMatthias Ringwald  */
56*75a994c4SMatthias Ringwald static uint16_t ant_cmd_create_from_template(uint8_t *hci_cmd_buffer, const ant_cmd_t *cmd, va_list argptr){
57*75a994c4SMatthias Ringwald 
58*75a994c4SMatthias Ringwald     hci_cmd_buffer[0] = 0xd1;
59*75a994c4SMatthias Ringwald     hci_cmd_buffer[1] = 0xfd;
60*75a994c4SMatthias Ringwald     // hci packet lengh 2
61*75a994c4SMatthias Ringwald     // ant packet length 3
62*75a994c4SMatthias Ringwald     hci_cmd_buffer[4] = 0x00;
63*75a994c4SMatthias Ringwald     hci_cmd_buffer[6] = cmd->message_id;
64*75a994c4SMatthias Ringwald     int pos = 7;
65*75a994c4SMatthias Ringwald 
66*75a994c4SMatthias Ringwald     const char *format = cmd->format;
67*75a994c4SMatthias Ringwald     uint16_t word;
68*75a994c4SMatthias Ringwald     uint32_t longword;
69*75a994c4SMatthias Ringwald     uint8_t * ptr;
70*75a994c4SMatthias Ringwald     while (*format) {
71*75a994c4SMatthias Ringwald         switch(*format) {
72*75a994c4SMatthias Ringwald             case '0': // dummy
73*75a994c4SMatthias Ringwald                 hci_cmd_buffer[pos++] = 0;
74*75a994c4SMatthias Ringwald                 break;
75*75a994c4SMatthias Ringwald             case '1': //  8 bit value
76*75a994c4SMatthias Ringwald             case '2': // 16 bit value
77*75a994c4SMatthias Ringwald                 word = va_arg(argptr, int);  // minimal va_arg is int: 2 bytes on 8+16 bit CPUs
78*75a994c4SMatthias Ringwald                 hci_cmd_buffer[pos++] = word & 0xff;
79*75a994c4SMatthias Ringwald                 if (*format == '2') {
80*75a994c4SMatthias Ringwald                     hci_cmd_buffer[pos++] = word >> 8;
81*75a994c4SMatthias Ringwald                 } else if (*format == 'H') {
82*75a994c4SMatthias Ringwald                     // TODO implement opaque client connection handles
83*75a994c4SMatthias Ringwald                     //      pass module handle for now
84*75a994c4SMatthias Ringwald                     hci_cmd_buffer[pos++] = word >> 8;
85*75a994c4SMatthias Ringwald                 }
86*75a994c4SMatthias Ringwald                 break;
87*75a994c4SMatthias Ringwald             case '3':
88*75a994c4SMatthias Ringwald             case '4':
89*75a994c4SMatthias Ringwald                 longword = va_arg(argptr, uint32_t);
90*75a994c4SMatthias Ringwald                 // longword = va_arg(argptr, int);
91*75a994c4SMatthias Ringwald                 hci_cmd_buffer[pos++] = longword;
92*75a994c4SMatthias Ringwald                 hci_cmd_buffer[pos++] = longword >> 8;
93*75a994c4SMatthias Ringwald                 hci_cmd_buffer[pos++] = longword >> 16;
94*75a994c4SMatthias Ringwald                 if (*format == '4'){
95*75a994c4SMatthias Ringwald                     hci_cmd_buffer[pos++] = longword >> 24;
96*75a994c4SMatthias Ringwald                 }
97*75a994c4SMatthias Ringwald                 break;
98*75a994c4SMatthias Ringwald             case 'D': // 8 byte data block
99*75a994c4SMatthias Ringwald                 ptr = va_arg(argptr, uint8_t *);
100*75a994c4SMatthias Ringwald                 memcpy(&hci_cmd_buffer[pos], ptr, 8);
101*75a994c4SMatthias Ringwald                 pos += 8;
102*75a994c4SMatthias Ringwald                 break;
103*75a994c4SMatthias Ringwald 
104*75a994c4SMatthias Ringwald             default:
105*75a994c4SMatthias Ringwald                 break;
106*75a994c4SMatthias Ringwald         }
107*75a994c4SMatthias Ringwald         format++;
108*75a994c4SMatthias Ringwald     };
109*75a994c4SMatthias Ringwald 
110*75a994c4SMatthias Ringwald     hci_cmd_buffer[2] = pos - 3;
111*75a994c4SMatthias Ringwald     hci_cmd_buffer[3] = pos - 5;
112*75a994c4SMatthias Ringwald     hci_cmd_buffer[5] = pos - 7;
113*75a994c4SMatthias Ringwald     return pos;
114*75a994c4SMatthias Ringwald }
115*75a994c4SMatthias Ringwald 
116*75a994c4SMatthias Ringwald /**
117*75a994c4SMatthias Ringwald  * construct ANT HCI Command based on template
118*75a994c4SMatthias Ringwald  *
119*75a994c4SMatthias Ringwald  * mainly calls ant_cmd_create_from_template
120*75a994c4SMatthias Ringwald  */
121*75a994c4SMatthias Ringwald uint16_t ant_create_cmd(uint8_t *hci_cmd_buffer, const ant_cmd_t *cmd, ...){
122*75a994c4SMatthias Ringwald     va_list argptr;
123*75a994c4SMatthias Ringwald     va_start(argptr, cmd);
124*75a994c4SMatthias Ringwald     uint16_t len = ant_cmd_create_from_template(hci_cmd_buffer, cmd, argptr);
125*75a994c4SMatthias Ringwald     va_end(argptr);
126*75a994c4SMatthias Ringwald     return len;
127*75a994c4SMatthias Ringwald }
128*75a994c4SMatthias Ringwald 
129*75a994c4SMatthias Ringwald /**
130*75a994c4SMatthias Ringwald  * pre: numcmds >= 0 - it's allowed to send a command to the controller
131*75a994c4SMatthias Ringwald  */
132*75a994c4SMatthias Ringwald uint8_t ant_packet_buffer[30];
133*75a994c4SMatthias Ringwald int ant_send_cmd(const ant_cmd_t *cmd, ...){
134*75a994c4SMatthias Ringwald     va_list argptr;
135*75a994c4SMatthias Ringwald     va_start(argptr, cmd);
136*75a994c4SMatthias Ringwald     uint16_t size = ant_cmd_create_from_template(ant_packet_buffer, cmd, argptr);
137*75a994c4SMatthias Ringwald     va_end(argptr);
138*75a994c4SMatthias Ringwald     return hci_send_cmd_packet(ant_packet_buffer, size);
139*75a994c4SMatthias Ringwald }
140*75a994c4SMatthias Ringwald 
141*75a994c4SMatthias Ringwald /**
142*75a994c4SMatthias Ringwald  *  ANT commands as found in http://www.thisisant.com/resources/ant-message-protocol-and-usage/
143*75a994c4SMatthias Ringwald  */
144*75a994c4SMatthias Ringwald 
145*75a994c4SMatthias Ringwald const ant_cmd_t ant_reset = {
146*75a994c4SMatthias Ringwald MESG_SYSTEM_RESET_ID, "0"
147*75a994c4SMatthias Ringwald };
148*75a994c4SMatthias Ringwald 
149*75a994c4SMatthias Ringwald const ant_cmd_t ant_assign_channel = {
150*75a994c4SMatthias Ringwald MESG_ASSIGN_CHANNEL_ID, "111"
151*75a994c4SMatthias Ringwald // channel number, channel type, network number
152*75a994c4SMatthias Ringwald };
153*75a994c4SMatthias Ringwald 
154*75a994c4SMatthias Ringwald const ant_cmd_t ant_un_assign_channel = {
155*75a994c4SMatthias Ringwald MESG_UNASSIGN_CHANNEL_ID, "1"
156*75a994c4SMatthias Ringwald // channel number
157*75a994c4SMatthias Ringwald };
158*75a994c4SMatthias Ringwald 
159*75a994c4SMatthias Ringwald const ant_cmd_t ant_search_timeout = {
160*75a994c4SMatthias Ringwald MESG_CHANNEL_SEARCH_TIMEOUT_ID, "11"
161*75a994c4SMatthias Ringwald // channel number, timeout
162*75a994c4SMatthias Ringwald };
163*75a994c4SMatthias Ringwald 
164*75a994c4SMatthias Ringwald const ant_cmd_t ant_lp_search_timeout = {
165*75a994c4SMatthias Ringwald MESG_SET_LP_SEARCH_TIMEOUT_ID, "11"
166*75a994c4SMatthias Ringwald // channel number, timeout
167*75a994c4SMatthias Ringwald };
168*75a994c4SMatthias Ringwald 
169*75a994c4SMatthias Ringwald const ant_cmd_t ant_network_key = {
170*75a994c4SMatthias Ringwald MESG_NETWORK_KEY_ID, "1D"
171*75a994c4SMatthias Ringwald // network number, pointer to 8 byte network key
172*75a994c4SMatthias Ringwald };
173*75a994c4SMatthias Ringwald 
174*75a994c4SMatthias Ringwald const ant_cmd_t ant_channel_id = {
175*75a994c4SMatthias Ringwald MESG_CHANNEL_ID_ID, "1211"
176*75a994c4SMatthias Ringwald // channel number, device number, device type, transmit type
177*75a994c4SMatthias Ringwald };
178*75a994c4SMatthias Ringwald 
179*75a994c4SMatthias Ringwald const ant_cmd_t ant_channel_power = {
180*75a994c4SMatthias Ringwald MESG_RADIO_TX_POWER_ID, "11"
181*75a994c4SMatthias Ringwald // channel number, power
182*75a994c4SMatthias Ringwald };
183*75a994c4SMatthias Ringwald 
184*75a994c4SMatthias Ringwald const ant_cmd_t ant_channel_period = {
185*75a994c4SMatthias Ringwald MESG_CHANNEL_MESG_PERIOD_ID, "12"
186*75a994c4SMatthias Ringwald // channel number, period
187*75a994c4SMatthias Ringwald };
188*75a994c4SMatthias Ringwald 
189*75a994c4SMatthias Ringwald const ant_cmd_t ant_prox_search_config = {
190*75a994c4SMatthias Ringwald MESG_PROX_SEARCH_CONFIG_ID, "11"
191*75a994c4SMatthias Ringwald // channel number, prox level
192*75a994c4SMatthias Ringwald };
193*75a994c4SMatthias Ringwald 
194*75a994c4SMatthias Ringwald const ant_cmd_t ant_broadcast = {
195*75a994c4SMatthias Ringwald MESG_BROADCAST_DATA_ID, "1D"
196*75a994c4SMatthias Ringwald // channel number, pointer to 8 byte data
197*75a994c4SMatthias Ringwald };
198*75a994c4SMatthias Ringwald 
199*75a994c4SMatthias Ringwald const ant_cmd_t ant_acknowledged = {
200*75a994c4SMatthias Ringwald MESG_ACKNOWLEDGED_DATA_ID, "1D"
201*75a994c4SMatthias Ringwald // channel number, pointer to 8 byte data
202*75a994c4SMatthias Ringwald };
203*75a994c4SMatthias Ringwald 
204*75a994c4SMatthias Ringwald const ant_cmd_t ant_burst_packet = {
205*75a994c4SMatthias Ringwald MESG_BURST_DATA_ID, "1D"
206*75a994c4SMatthias Ringwald // channel number, pointer to 8 byte data
207*75a994c4SMatthias Ringwald };
208*75a994c4SMatthias Ringwald 
209*75a994c4SMatthias Ringwald const ant_cmd_t ant_open_channel = {
210*75a994c4SMatthias Ringwald MESG_OPEN_CHANNEL_ID, "1"
211*75a994c4SMatthias Ringwald // channel number
212*75a994c4SMatthias Ringwald };
213*75a994c4SMatthias Ringwald 
214*75a994c4SMatthias Ringwald const ant_cmd_t ant_close_channel = {
215*75a994c4SMatthias Ringwald MESG_CLOSE_CHANNEL_ID, "1"
216*75a994c4SMatthias Ringwald // channel number
217*75a994c4SMatthias Ringwald };
218*75a994c4SMatthias Ringwald 
219*75a994c4SMatthias Ringwald const ant_cmd_t ant_request_message = {
220*75a994c4SMatthias Ringwald MESG_REQUEST_ID, "11"
221*75a994c4SMatthias Ringwald // channel number, requested message
222*75a994c4SMatthias Ringwald };
223