xref: /btstack/port/arduino/bsp_arduino_em9301.cpp (revision 0f7fd6c19b44e3fae3aaf3caf2c11dd07533fe4c)
1 /**
2  * Arduino + Energia Wrapper for BTstack
3  */
4 
5 #if !defined(ARDUINO)
6 #error "Not compiling for Arduino/Energia"
7 #endif
8 
9 #include <Arduino.h>
10 #ifdef ENERGIA
11 #include <Energia.h>
12 #endif
13 #include <SPI.h>
14 
15 #include "hal_uart_dma.h"
16 
17 #define HAVE_SHUTDOWN
18 
19 #ifdef ENERGIA
20 
21 // CMM 9301 Configuration for TI Launchpad
22 #define PIN_SPI_SCK      7
23 #define PIN_CS       8
24 #define PIN_SHUTDOWN 11
25 #define PIN_IRQ_DATA 13
26 #define PIN_SPI_MISO     14
27 #define PIN_SPI_MOSI     15
28 #else // ARDUINO
29 
30 // CMM 9301 Configuration for Arduino
31 #define PIN_IRQ_DATA 2
32 #define PIN_CS 4
33 #define PIN_SHUTDOWN 5
34 
35 // -- SPI defines for Arduino Mega
36 #ifndef PIN_SPI_MISO
37 #define PIN_SPI_MISO 50
38 #endif
39 #ifndef PIN_SPI_MOSI
40 #define PIN_SPI_MOSI 51
41 #endif
42 #ifndef PIN_SPI_SCK
43 #define PIN_SPI_SCK  52
44 #endif
45 
46 #endif
47 
48 // rx state
49 static uint16_t  bytes_to_read = 0;
50 static uint8_t * rx_buffer_ptr = 0;
51 
52 // tx state
53 static uint16_t  bytes_to_write = 0;
54 static uint8_t * tx_buffer_ptr = 0;
55 
56 // handlers
57 static void dummy_handler(void){};
58 static void (*rx_done_handler)(void) = dummy_handler;
59 static void (*tx_done_handler)(void) = dummy_handler;
60 
61 static void bt_setup(void){
62     pinMode(PIN_CS, OUTPUT);
63     pinMode(PIN_SPI_MOSI, OUTPUT);
64     pinMode(PIN_SPI_SCK, OUTPUT);
65     pinMode(PIN_SHUTDOWN, OUTPUT);
66     pinMode(PIN_IRQ_DATA, INPUT);
67 
68     digitalWrite(PIN_CS, HIGH);
69     digitalWrite(PIN_SPI_MOSI, LOW);
70     digitalWrite(PIN_SHUTDOWN, HIGH);
71 
72     // SPI settings are reset in SPI.begin() - calls hang on Arduino Zero, too.
73     // SPI.setBitOrder(MSBFIRST);
74     // SPI.setDataMode(SPI_MODE0);
75     // SPI.end();
76 }
77 
78 #ifdef HAVE_SHUTDOWN
79 static void bt_power_cycle(void){
80 
81     // power cycle. set CPU outputs to input to not power EM9301 via IOs
82     // pinMode(PIN_SPI_MOSI, INPUT);
83     // pinMode(PIN_CS, INPUT);
84     pinMode(PIN_CS, OUTPUT);
85     pinMode(PIN_SPI_MOSI, OUTPUT);
86     pinMode(PIN_SPI_SCK, OUTPUT);
87     pinMode(PIN_SHUTDOWN, OUTPUT);
88     digitalWrite(PIN_CS, LOW);
89     digitalWrite(PIN_SPI_MOSI, LOW);
90     digitalWrite(PIN_SPI_SCK, LOW);
91     digitalWrite(PIN_SHUTDOWN, HIGH);
92     delay(500);
93 
94     pinMode(PIN_SPI_MOSI, OUTPUT);
95     pinMode(PIN_CS, OUTPUT);
96     digitalWrite(PIN_SPI_MOSI, LOW);
97     digitalWrite(PIN_CS, HIGH);
98     digitalWrite(PIN_SHUTDOWN, LOW);
99     delay(1000);
100 }
101 #endif
102 
103 #ifndef HAVE_SHUTDOWN
104 static void bt_send_illegal(void){
105     digitalWrite(PIN_SPI_MOSI, HIGH);
106     digitalWrite(PIN_CS, LOW);
107     printf("Illegal start\n");
108     SPI.begin();
109     int i;
110     for (i=0;i<255;i++){
111         SPI.transfer(0xff);
112         printf(".");
113     }
114     SPI.end();
115     printf("\nIllegal stop\n");
116     digitalWrite(PIN_CS, HIGH);
117 }
118 
119 static void bt_flush_input(void){
120     digitalWrite(PIN_SPI_MOSI, LOW);
121     digitalWrite(PIN_CS, LOW);
122     SPI.begin();
123     while (digitalRead(PIN_IRQ_DATA) == HIGH){
124         SPI.transfer(0x00);
125     }
126     SPI.end();
127     digitalWrite(PIN_CS, HIGH);
128 }
129 
130 static void bt_send_reset(void){
131       digitalWrite(PIN_SPI_MOSI, HIGH);
132       digitalWrite(PIN_CS, LOW);
133       SPI.begin();
134       SPI.transfer(0x01);
135       SPI.transfer(0x03);
136       SPI.transfer(0x0c);
137       SPI.transfer(0x00);
138       SPI.end();
139       digitalWrite(PIN_CS, HIGH);
140 }
141 #endif
142 
143 
144 static void bt_try_send(void){
145 
146     if (!bytes_to_write) return;
147 
148     // activate module
149     pinMode(PIN_SPI_MOSI, OUTPUT);
150     digitalWrite(PIN_SPI_MOSI, HIGH);
151     digitalWrite(PIN_CS, LOW);
152 
153     // module ready
154     int tx_done = 0;
155     if (digitalRead(PIN_SPI_MISO) == HIGH){
156         // printf("Sending: ");
157 
158         SPI.begin();
159         while (bytes_to_write){
160             // printf("%02x ", *tx_buffer_ptr);
161             SPI.transfer(*tx_buffer_ptr);
162             tx_buffer_ptr++;
163             bytes_to_write--;
164         }
165         SPI.end();
166         // printf(".\n");
167         tx_done = 1;
168     }
169 
170     // deactivate module
171     digitalWrite(PIN_CS, HIGH);
172     digitalWrite(PIN_SPI_MOSI, LOW);
173     pinMode(PIN_SPI_MOSI, OUTPUT);
174 
175     // notify upper layer
176     if (tx_done) {
177         (*tx_done_handler)();
178     }
179 }
180 
181 static int bt_try_read(void){
182 
183     // check if data available and buffer is ready
184     if (digitalRead(PIN_IRQ_DATA) == LOW) return 0;
185     if (bytes_to_read == 0) return 0;
186 
187     int num_bytes_read = 0;
188 
189     // printf("Reading (%u): ", bytes_to_read);
190 
191     // activate module
192     digitalWrite(PIN_SPI_MOSI, LOW);
193     digitalWrite(PIN_CS, LOW);
194     SPI.begin();
195     do {
196         uint8_t byte_read = SPI.transfer(0x00);
197         // printf("%02x ", byte_read);
198         *rx_buffer_ptr = byte_read;
199         rx_buffer_ptr++;
200         bytes_to_read--;
201         num_bytes_read++;
202     } while (bytes_to_read > 0);
203     SPI.end();
204     digitalWrite(PIN_CS, HIGH);
205 
206     // printf("\n");
207 
208     // notify upper layer
209     (*rx_done_handler)();
210 
211     return num_bytes_read;
212 }
213 
214 extern "C" void hal_uart_dma_init(void){
215     bt_setup();
216 
217 #ifdef HAVE_SHUTDOWN
218     bt_power_cycle();
219 #else
220     // bring EM9301 into defined state
221     bt_send_illegal();
222     bt_send_reset();
223     bt_flush_input();
224 #endif
225 }
226 
227 extern "C" void hal_uart_dma_set_block_received( void (*block_handler)(void)){
228     rx_done_handler = block_handler;
229 }
230 extern "C" void hal_uart_dma_set_block_sent( void (*block_handler)(void)){
231     tx_done_handler = block_handler;
232 }
233 
234 extern "C" void hal_uart_dma_set_csr_irq_handler( void (*csr_irq_handler)(void)){
235     // only used for eHCILL
236 }
237 
238 extern "C" int  hal_uart_dma_set_baud(uint32_t baud){
239 	return 0;
240 }
241 
242 extern "C" void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t length){
243     // printf("send_block, bytes %u\n", length);
244     tx_buffer_ptr = (uint8_t *) buffer;
245     bytes_to_write = length;
246 }
247 
248 extern "C" void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t length){
249     rx_buffer_ptr = buffer;
250     bytes_to_read = length;
251 }
252 
253 extern "C" void hal_uart_dma_set_sleep(uint8_t sleep){
254     // not needed for SPI (doesn't need internal clock to work)
255 }
256 
257 extern "C" void hal_uart_dma_process(void){
258     int num_bytes_read = bt_try_read();
259     if (num_bytes_read == 0){
260         bt_try_send();
261     }
262 }
263 
264 extern "C" uint32_t hal_time_ms(void){
265     return millis();
266 }
267 
268