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