added debugging

Fork of BLE_nRF8001 by RedBearLab

Committer:
jn80842
Date:
Mon Nov 10 01:24:23 2014 +0000
Revision:
2:7805a5595aab
Parent:
0:075ea2812998
just added debugging

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RedBearLab 0:075ea2812998 1 /* Copyright (c) 2014, Nordic Semiconductor ASA
RedBearLab 0:075ea2812998 2 *
RedBearLab 0:075ea2812998 3 * Permission is hereby granted, free of charge, to any person obtaining a copy
RedBearLab 0:075ea2812998 4 * of this software and associated documentation files (the "Software"), to deal
RedBearLab 0:075ea2812998 5 * in the Software without restriction, including without limitation the rights
RedBearLab 0:075ea2812998 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
RedBearLab 0:075ea2812998 7 * copies of the Software, and to permit persons to whom the Software is
RedBearLab 0:075ea2812998 8 * furnished to do so, subject to the following conditions:
RedBearLab 0:075ea2812998 9 *
RedBearLab 0:075ea2812998 10 * The above copyright notice and this permission notice shall be included in all
RedBearLab 0:075ea2812998 11 * copies or substantial portions of the Software.
RedBearLab 0:075ea2812998 12 *
RedBearLab 0:075ea2812998 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
RedBearLab 0:075ea2812998 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
RedBearLab 0:075ea2812998 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
RedBearLab 0:075ea2812998 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
RedBearLab 0:075ea2812998 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
RedBearLab 0:075ea2812998 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
RedBearLab 0:075ea2812998 19 * SOFTWARE.
RedBearLab 0:075ea2812998 20 */
RedBearLab 0:075ea2812998 21
RedBearLab 0:075ea2812998 22 /** @file
RedBearLab 0:075ea2812998 23 @brief Implementation of the ACI transport layer module
RedBearLab 0:075ea2812998 24 */
RedBearLab 0:075ea2812998 25
RedBearLab 0:075ea2812998 26 #include "hal_platform.h"
RedBearLab 0:075ea2812998 27 #include "hal_aci_tl.h"
RedBearLab 0:075ea2812998 28 #include "aci_queue.h"
RedBearLab 0:075ea2812998 29
RedBearLab 0:075ea2812998 30 /*
RedBearLab 0:075ea2812998 31 PIC32 supports only MSbit transfer on SPI and the nRF8001 uses LSBit
RedBearLab 0:075ea2812998 32 Use the REVERSE_BITS macro to convert from MSBit to LSBit
RedBearLab 0:075ea2812998 33 The outgoing command and the incoming event needs to be converted
RedBearLab 0:075ea2812998 34 */
RedBearLab 0:075ea2812998 35 //For mbed as the transmission has to be reversed, the next definitions have to be added
RedBearLab 0:075ea2812998 36 #define REVERSE_BITS(byte) (((reverse_lookup[(byte & 0x0F)]) << 4) + reverse_lookup[((byte & 0xF0) >> 4)])
RedBearLab 0:075ea2812998 37 static const uint8_t reverse_lookup[] = { 0, 8, 4, 12, 2, 10, 6, 14,1, 9, 5, 13,3, 11, 7, 15 };
RedBearLab 0:075ea2812998 38
RedBearLab 0:075ea2812998 39 static void m_aci_data_print(hal_aci_data_t *p_data);
RedBearLab 0:075ea2812998 40 static void m_aci_event_check(void);
RedBearLab 0:075ea2812998 41 static void m_aci_isr(void);
RedBearLab 0:075ea2812998 42 static void m_aci_pins_set(aci_pins_t *a_pins_ptr);
RedBearLab 0:075ea2812998 43 static inline void m_aci_reqn_disable (void);
RedBearLab 0:075ea2812998 44 static inline void m_aci_reqn_enable (void);
RedBearLab 0:075ea2812998 45 static void m_aci_q_flush(void);
RedBearLab 0:075ea2812998 46 static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data);
RedBearLab 0:075ea2812998 47
RedBearLab 0:075ea2812998 48 static uint8_t spi_readwrite(uint8_t aci_byte);
RedBearLab 0:075ea2812998 49
RedBearLab 0:075ea2812998 50 static bool aci_debug_print = false;
RedBearLab 0:075ea2812998 51
RedBearLab 0:075ea2812998 52 aci_queue_t aci_tx_q;
RedBearLab 0:075ea2812998 53 aci_queue_t aci_rx_q;
RedBearLab 0:075ea2812998 54
RedBearLab 0:075ea2812998 55 static aci_pins_t *a_pins_local_ptr;
RedBearLab 0:075ea2812998 56
RedBearLab 0:075ea2812998 57 void m_aci_data_print(hal_aci_data_t *p_data)
RedBearLab 0:075ea2812998 58 {
RedBearLab 0:075ea2812998 59 const uint8_t length = p_data->buffer[0];
RedBearLab 0:075ea2812998 60 uint8_t i;
RedBearLab 0:075ea2812998 61 serial.printf("%d", length);
RedBearLab 0:075ea2812998 62 serial.printf(" :");
RedBearLab 0:075ea2812998 63 for (i=0; i<=length; i++)
RedBearLab 0:075ea2812998 64 {
RedBearLab 0:075ea2812998 65 serial.printf("%02X", p_data->buffer[i]);
RedBearLab 0:075ea2812998 66 serial.printf(", ");
RedBearLab 0:075ea2812998 67 }
RedBearLab 0:075ea2812998 68 serial.printf("");
RedBearLab 0:075ea2812998 69 }
RedBearLab 0:075ea2812998 70
RedBearLab 0:075ea2812998 71 /*
RedBearLab 0:075ea2812998 72 Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer.
RedBearLab 0:075ea2812998 73 */
RedBearLab 0:075ea2812998 74 static void m_aci_isr(void)
RedBearLab 0:075ea2812998 75 {
RedBearLab 0:075ea2812998 76 hal_aci_data_t data_to_send;
RedBearLab 0:075ea2812998 77 hal_aci_data_t received_data;
RedBearLab 0:075ea2812998 78
RedBearLab 0:075ea2812998 79 // Receive from queue
RedBearLab 0:075ea2812998 80 if (!aci_queue_dequeue_from_isr(&aci_tx_q, &data_to_send))
RedBearLab 0:075ea2812998 81 {
RedBearLab 0:075ea2812998 82 /* queue was empty, nothing to send */
RedBearLab 0:075ea2812998 83 data_to_send.status_byte = 0;
RedBearLab 0:075ea2812998 84 data_to_send.buffer[0] = 0;
RedBearLab 0:075ea2812998 85 }
RedBearLab 0:075ea2812998 86
RedBearLab 0:075ea2812998 87 // Receive and/or transmit data
RedBearLab 0:075ea2812998 88 m_aci_spi_transfer(&data_to_send, &received_data);
RedBearLab 0:075ea2812998 89
RedBearLab 0:075ea2812998 90 if (!aci_queue_is_full_from_isr(&aci_rx_q) && !aci_queue_is_empty_from_isr(&aci_tx_q))
RedBearLab 0:075ea2812998 91 {
RedBearLab 0:075ea2812998 92 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 93 }
RedBearLab 0:075ea2812998 94
RedBearLab 0:075ea2812998 95 // Check if we received data
RedBearLab 0:075ea2812998 96 if (received_data.buffer[0] > 0)
RedBearLab 0:075ea2812998 97 {
RedBearLab 0:075ea2812998 98 if (!aci_queue_enqueue_from_isr(&aci_rx_q, &received_data))
RedBearLab 0:075ea2812998 99 {
RedBearLab 0:075ea2812998 100 /* Receive Buffer full.
RedBearLab 0:075ea2812998 101 Should never happen.
RedBearLab 0:075ea2812998 102 Spin in a while loop.
RedBearLab 0:075ea2812998 103 */
RedBearLab 0:075ea2812998 104 while(1);
RedBearLab 0:075ea2812998 105 }
RedBearLab 0:075ea2812998 106
RedBearLab 0:075ea2812998 107 // Disable ready line interrupt until we have room to store incoming messages
RedBearLab 0:075ea2812998 108 if (aci_queue_is_full_from_isr(&aci_rx_q))
RedBearLab 0:075ea2812998 109 {
RedBearLab 0:075ea2812998 110 //detachInterrupt(a_pins_local_ptr->interrupt_number);
RedBearLab 0:075ea2812998 111 }
RedBearLab 0:075ea2812998 112 }
RedBearLab 0:075ea2812998 113
RedBearLab 0:075ea2812998 114 return;
RedBearLab 0:075ea2812998 115 }
RedBearLab 0:075ea2812998 116
RedBearLab 0:075ea2812998 117 /*
RedBearLab 0:075ea2812998 118 Checks the RDYN line and runs the SPI transfer if required.
RedBearLab 0:075ea2812998 119 */
RedBearLab 0:075ea2812998 120 static void m_aci_event_check(void)
RedBearLab 0:075ea2812998 121 {
RedBearLab 0:075ea2812998 122 hal_aci_data_t data_to_send;
RedBearLab 0:075ea2812998 123 hal_aci_data_t received_data;
RedBearLab 0:075ea2812998 124
RedBearLab 0:075ea2812998 125 // No room to store incoming messages
RedBearLab 0:075ea2812998 126 if (aci_queue_is_full(&aci_rx_q))
RedBearLab 0:075ea2812998 127 {
RedBearLab 0:075ea2812998 128 return;
RedBearLab 0:075ea2812998 129 }
RedBearLab 0:075ea2812998 130
RedBearLab 0:075ea2812998 131 // If the ready line is disabled and we have pending messages outgoing we enable the request line
RedBearLab 0:075ea2812998 132 if (HIGH == digitalRead(a_pins_local_ptr->rdyn_pin))
RedBearLab 0:075ea2812998 133 {
RedBearLab 0:075ea2812998 134 if (!aci_queue_is_empty(&aci_tx_q))
RedBearLab 0:075ea2812998 135 {
RedBearLab 0:075ea2812998 136 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 137 }
RedBearLab 0:075ea2812998 138
RedBearLab 0:075ea2812998 139 return;
RedBearLab 0:075ea2812998 140 }
RedBearLab 0:075ea2812998 141
RedBearLab 0:075ea2812998 142 // Receive from queue
RedBearLab 0:075ea2812998 143 if (!aci_queue_dequeue(&aci_tx_q, &data_to_send))
RedBearLab 0:075ea2812998 144 {
RedBearLab 0:075ea2812998 145 /* queue was empty, nothing to send */
RedBearLab 0:075ea2812998 146 data_to_send.status_byte = 0;
RedBearLab 0:075ea2812998 147 data_to_send.buffer[0] = 0;
RedBearLab 0:075ea2812998 148 }
RedBearLab 0:075ea2812998 149
RedBearLab 0:075ea2812998 150 // Receive and/or transmit data
RedBearLab 0:075ea2812998 151 m_aci_spi_transfer(&data_to_send, &received_data);
RedBearLab 0:075ea2812998 152
RedBearLab 0:075ea2812998 153 /* If there are messages to transmit, and we can store the reply, we request a new transfer */
RedBearLab 0:075ea2812998 154 if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
RedBearLab 0:075ea2812998 155 {
RedBearLab 0:075ea2812998 156 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 157 }
RedBearLab 0:075ea2812998 158
RedBearLab 0:075ea2812998 159 // Check if we received data
RedBearLab 0:075ea2812998 160 if (received_data.buffer[0] > 0)
RedBearLab 0:075ea2812998 161 {
RedBearLab 0:075ea2812998 162 if (!aci_queue_enqueue(&aci_rx_q, &received_data))
RedBearLab 0:075ea2812998 163 {
RedBearLab 0:075ea2812998 164 /* Receive Buffer full.
RedBearLab 0:075ea2812998 165 Should never happen.
RedBearLab 0:075ea2812998 166 Spin in a while loop.
RedBearLab 0:075ea2812998 167 */
RedBearLab 0:075ea2812998 168 while(1);
RedBearLab 0:075ea2812998 169 }
RedBearLab 0:075ea2812998 170 }
RedBearLab 0:075ea2812998 171
RedBearLab 0:075ea2812998 172 return;
RedBearLab 0:075ea2812998 173 }
RedBearLab 0:075ea2812998 174
RedBearLab 0:075ea2812998 175 /** @brief Point the low level library at the ACI pins specified
RedBearLab 0:075ea2812998 176 * @details
RedBearLab 0:075ea2812998 177 * The ACI pins are specified in the application and a pointer is made available for
RedBearLab 0:075ea2812998 178 * the low level library to use
RedBearLab 0:075ea2812998 179 */
RedBearLab 0:075ea2812998 180 static void m_aci_pins_set(aci_pins_t *a_pins_ptr)
RedBearLab 0:075ea2812998 181 {
RedBearLab 0:075ea2812998 182 a_pins_local_ptr = a_pins_ptr;
RedBearLab 0:075ea2812998 183 }
RedBearLab 0:075ea2812998 184
RedBearLab 0:075ea2812998 185 static inline void m_aci_reqn_disable (void)
RedBearLab 0:075ea2812998 186 {
RedBearLab 0:075ea2812998 187 digitalWrite(a_pins_local_ptr->reqn_pin, 1);
RedBearLab 0:075ea2812998 188 }
RedBearLab 0:075ea2812998 189
RedBearLab 0:075ea2812998 190 static inline void m_aci_reqn_enable (void)
RedBearLab 0:075ea2812998 191 {
RedBearLab 0:075ea2812998 192 digitalWrite(a_pins_local_ptr->reqn_pin, 0);
RedBearLab 0:075ea2812998 193 }
RedBearLab 0:075ea2812998 194
RedBearLab 0:075ea2812998 195 static void m_aci_q_flush(void)
RedBearLab 0:075ea2812998 196 {
RedBearLab 0:075ea2812998 197 //noInterrupts();
RedBearLab 0:075ea2812998 198 /* re-initialize aci cmd queue and aci event queue to flush them*/
RedBearLab 0:075ea2812998 199 aci_queue_init(&aci_tx_q);
RedBearLab 0:075ea2812998 200 aci_queue_init(&aci_rx_q);
RedBearLab 0:075ea2812998 201 //interrupts();
RedBearLab 0:075ea2812998 202 }
RedBearLab 0:075ea2812998 203
RedBearLab 0:075ea2812998 204 static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data)
RedBearLab 0:075ea2812998 205 {
RedBearLab 0:075ea2812998 206 uint8_t byte_cnt;
RedBearLab 0:075ea2812998 207 uint8_t byte_sent_cnt;
RedBearLab 0:075ea2812998 208 uint8_t max_bytes;
RedBearLab 0:075ea2812998 209
RedBearLab 0:075ea2812998 210 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 211
RedBearLab 0:075ea2812998 212 // Send length, receive header
RedBearLab 0:075ea2812998 213 byte_sent_cnt = 0;
RedBearLab 0:075ea2812998 214 received_data->status_byte = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
RedBearLab 0:075ea2812998 215 // Send first byte, receive length from slave
RedBearLab 0:075ea2812998 216 received_data->buffer[0] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
RedBearLab 0:075ea2812998 217 if (0 == data_to_send->buffer[0])
RedBearLab 0:075ea2812998 218 {
RedBearLab 0:075ea2812998 219 max_bytes = received_data->buffer[0];
RedBearLab 0:075ea2812998 220 }
RedBearLab 0:075ea2812998 221 else
RedBearLab 0:075ea2812998 222 {
RedBearLab 0:075ea2812998 223 // Set the maximum to the biggest size. One command byte is already sent
RedBearLab 0:075ea2812998 224 max_bytes = (received_data->buffer[0] > (data_to_send->buffer[0] - 1))
RedBearLab 0:075ea2812998 225 ? received_data->buffer[0]
RedBearLab 0:075ea2812998 226 : (data_to_send->buffer[0] - 1);
RedBearLab 0:075ea2812998 227 }
RedBearLab 0:075ea2812998 228
RedBearLab 0:075ea2812998 229 if (max_bytes > HAL_ACI_MAX_LENGTH)
RedBearLab 0:075ea2812998 230 {
RedBearLab 0:075ea2812998 231 max_bytes = HAL_ACI_MAX_LENGTH;
RedBearLab 0:075ea2812998 232 }
RedBearLab 0:075ea2812998 233
RedBearLab 0:075ea2812998 234 // Transmit/receive the rest of the packet
RedBearLab 0:075ea2812998 235 for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
RedBearLab 0:075ea2812998 236 {
RedBearLab 0:075ea2812998 237 received_data->buffer[byte_cnt+1] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
RedBearLab 0:075ea2812998 238 }
RedBearLab 0:075ea2812998 239
RedBearLab 0:075ea2812998 240 // RDYN should follow the REQN line in approx 100ns
RedBearLab 0:075ea2812998 241 m_aci_reqn_disable();
RedBearLab 0:075ea2812998 242
RedBearLab 0:075ea2812998 243 return (max_bytes > 0);
RedBearLab 0:075ea2812998 244 }
RedBearLab 0:075ea2812998 245
RedBearLab 0:075ea2812998 246 void hal_aci_tl_debug_print(bool enable)
RedBearLab 0:075ea2812998 247 {
RedBearLab 0:075ea2812998 248 aci_debug_print = enable;
RedBearLab 0:075ea2812998 249 }
RedBearLab 0:075ea2812998 250
RedBearLab 0:075ea2812998 251 void hal_aci_tl_pin_reset(void)
RedBearLab 0:075ea2812998 252 {
RedBearLab 0:075ea2812998 253 if (NULL != a_pins_local_ptr->reset_pin)
RedBearLab 0:075ea2812998 254 {
RedBearLab 0:075ea2812998 255 pinMode(a_pins_local_ptr->reset_pin, OUTPUT);
RedBearLab 0:075ea2812998 256
RedBearLab 0:075ea2812998 257 if ((REDBEARLAB_SHIELD_V1_1 == a_pins_local_ptr->board_name) ||
RedBearLab 0:075ea2812998 258 (REDBEARLAB_SHIELD_V2012_07 == a_pins_local_ptr->board_name))
RedBearLab 0:075ea2812998 259 {
RedBearLab 0:075ea2812998 260 //The reset for the Redbearlab v1.1 and v2012.07 boards are inverted and has a Power On Reset
RedBearLab 0:075ea2812998 261 //circuit that takes about 100ms to trigger the reset
RedBearLab 0:075ea2812998 262 digitalWrite(a_pins_local_ptr->reset_pin, 1);
RedBearLab 0:075ea2812998 263 delay(100);
RedBearLab 0:075ea2812998 264 digitalWrite(a_pins_local_ptr->reset_pin, 0);
RedBearLab 0:075ea2812998 265 }
RedBearLab 0:075ea2812998 266 else
RedBearLab 0:075ea2812998 267 {
RedBearLab 0:075ea2812998 268 digitalWrite(a_pins_local_ptr->reset_pin, 1);
RedBearLab 0:075ea2812998 269 digitalWrite(a_pins_local_ptr->reset_pin, 0);
RedBearLab 0:075ea2812998 270 digitalWrite(a_pins_local_ptr->reset_pin, 1);
RedBearLab 0:075ea2812998 271 }
RedBearLab 0:075ea2812998 272 }
RedBearLab 0:075ea2812998 273 }
RedBearLab 0:075ea2812998 274
RedBearLab 0:075ea2812998 275 bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data)
RedBearLab 0:075ea2812998 276 {
RedBearLab 0:075ea2812998 277 if (!a_pins_local_ptr->interface_is_interrupt)
RedBearLab 0:075ea2812998 278 {
RedBearLab 0:075ea2812998 279 m_aci_event_check();
RedBearLab 0:075ea2812998 280 }
RedBearLab 0:075ea2812998 281
RedBearLab 0:075ea2812998 282 if (aci_queue_peek(&aci_rx_q, p_aci_data))
RedBearLab 0:075ea2812998 283 {
RedBearLab 0:075ea2812998 284 return true;
RedBearLab 0:075ea2812998 285 }
RedBearLab 0:075ea2812998 286
RedBearLab 0:075ea2812998 287 return false;
RedBearLab 0:075ea2812998 288 }
RedBearLab 0:075ea2812998 289
RedBearLab 0:075ea2812998 290 bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)
RedBearLab 0:075ea2812998 291 {
RedBearLab 0:075ea2812998 292 bool was_full;
RedBearLab 0:075ea2812998 293
RedBearLab 0:075ea2812998 294 if (!a_pins_local_ptr->interface_is_interrupt && !aci_queue_is_full(&aci_rx_q))
RedBearLab 0:075ea2812998 295 {
RedBearLab 0:075ea2812998 296 m_aci_event_check();
RedBearLab 0:075ea2812998 297 }
RedBearLab 0:075ea2812998 298
RedBearLab 0:075ea2812998 299 was_full = aci_queue_is_full(&aci_rx_q);
RedBearLab 0:075ea2812998 300
RedBearLab 0:075ea2812998 301 if (aci_queue_dequeue(&aci_rx_q, p_aci_data))
RedBearLab 0:075ea2812998 302 {
RedBearLab 0:075ea2812998 303 if (aci_debug_print)
RedBearLab 0:075ea2812998 304 {
RedBearLab 0:075ea2812998 305 serial.printf(" E");
RedBearLab 0:075ea2812998 306 m_aci_data_print(p_aci_data);
RedBearLab 0:075ea2812998 307 }
RedBearLab 0:075ea2812998 308
RedBearLab 0:075ea2812998 309 if (was_full && a_pins_local_ptr->interface_is_interrupt)
RedBearLab 0:075ea2812998 310 {
RedBearLab 0:075ea2812998 311 /* Enable RDY line interrupt again */
RedBearLab 0:075ea2812998 312 //attachInterrupt(a_pins_local_ptr->interrupt_number, m_aci_isr, LOW);
RedBearLab 0:075ea2812998 313 }
RedBearLab 0:075ea2812998 314
RedBearLab 0:075ea2812998 315 /* Attempt to pull REQN LOW since we've made room for new messages */
RedBearLab 0:075ea2812998 316 if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
RedBearLab 0:075ea2812998 317 {
RedBearLab 0:075ea2812998 318 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 319 }
RedBearLab 0:075ea2812998 320
RedBearLab 0:075ea2812998 321 return true;
RedBearLab 0:075ea2812998 322 }
RedBearLab 0:075ea2812998 323
RedBearLab 0:075ea2812998 324 return false;
RedBearLab 0:075ea2812998 325 }
RedBearLab 0:075ea2812998 326
RedBearLab 0:075ea2812998 327 void hal_aci_tl_init(aci_pins_t *a_pins, bool debug)
RedBearLab 0:075ea2812998 328 {
RedBearLab 0:075ea2812998 329 aci_debug_print = debug;
RedBearLab 0:075ea2812998 330
RedBearLab 0:075ea2812998 331 /* Needs to be called as the first thing for proper intialization*/
RedBearLab 0:075ea2812998 332 m_aci_pins_set(a_pins);
RedBearLab 0:075ea2812998 333
RedBearLab 0:075ea2812998 334 /*
RedBearLab 0:075ea2812998 335 The SPI lines used are mapped directly to the hardware SPI
RedBearLab 0:075ea2812998 336 MISO MOSI and SCK
RedBearLab 0:075ea2812998 337 Change here if the pins are mapped differently
RedBearLab 0:075ea2812998 338
RedBearLab 0:075ea2812998 339 The SPI library assumes that the hardware pins are used
RedBearLab 0:075ea2812998 340 */
RedBearLab 0:075ea2812998 341 spi.format(8,0);
RedBearLab 0:075ea2812998 342 spi.frequency(2000000);
RedBearLab 0:075ea2812998 343
RedBearLab 0:075ea2812998 344 /* Initialize the ACI Command queue. This must be called after the delay above. */
RedBearLab 0:075ea2812998 345 aci_queue_init(&aci_tx_q);
RedBearLab 0:075ea2812998 346 aci_queue_init(&aci_rx_q);
RedBearLab 0:075ea2812998 347
RedBearLab 0:075ea2812998 348 //Configure the IO lines
RedBearLab 0:075ea2812998 349 pinMode(a_pins->rdyn_pin, INPUT_PULLUP);
RedBearLab 0:075ea2812998 350 pinMode(a_pins->reqn_pin, OUTPUT);
RedBearLab 0:075ea2812998 351
RedBearLab 0:075ea2812998 352 if (NULL != a_pins->active_pin)
RedBearLab 0:075ea2812998 353 {
RedBearLab 0:075ea2812998 354 pinMode(a_pins->active_pin, INPUT);
RedBearLab 0:075ea2812998 355 }
RedBearLab 0:075ea2812998 356 /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */
RedBearLab 0:075ea2812998 357 hal_aci_tl_pin_reset();
RedBearLab 0:075ea2812998 358
RedBearLab 0:075ea2812998 359 /* Set the nRF8001 to a known state as required by the datasheet*/
RedBearLab 0:075ea2812998 360 digitalWrite(a_pins->reqn_pin, 1);
RedBearLab 0:075ea2812998 361
RedBearLab 0:075ea2812998 362 delay(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset
RedBearLab 0:075ea2812998 363
RedBearLab 0:075ea2812998 364 /* Attach the interrupt to the RDYN line as requested by the caller */
RedBearLab 0:075ea2812998 365 if (a_pins->interface_is_interrupt)
RedBearLab 0:075ea2812998 366 {
RedBearLab 0:075ea2812998 367 // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW
RedBearLab 0:075ea2812998 368 //attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW);
RedBearLab 0:075ea2812998 369 }
RedBearLab 0:075ea2812998 370 }
RedBearLab 0:075ea2812998 371
RedBearLab 0:075ea2812998 372 bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd)
RedBearLab 0:075ea2812998 373 {
RedBearLab 0:075ea2812998 374 const uint8_t length = p_aci_cmd->buffer[0];
RedBearLab 0:075ea2812998 375 bool ret_val = false;
RedBearLab 0:075ea2812998 376
RedBearLab 0:075ea2812998 377 if (length > HAL_ACI_MAX_LENGTH)
RedBearLab 0:075ea2812998 378 {
RedBearLab 0:075ea2812998 379 return false;
RedBearLab 0:075ea2812998 380 }
RedBearLab 0:075ea2812998 381
RedBearLab 0:075ea2812998 382 ret_val = aci_queue_enqueue(&aci_tx_q, p_aci_cmd);
RedBearLab 0:075ea2812998 383 if (ret_val)
RedBearLab 0:075ea2812998 384 {
RedBearLab 0:075ea2812998 385 if(!aci_queue_is_full(&aci_rx_q))
RedBearLab 0:075ea2812998 386 {
RedBearLab 0:075ea2812998 387 // Lower the REQN only when successfully enqueued
RedBearLab 0:075ea2812998 388 m_aci_reqn_enable();
RedBearLab 0:075ea2812998 389 }
RedBearLab 0:075ea2812998 390
RedBearLab 0:075ea2812998 391 if (aci_debug_print)
RedBearLab 0:075ea2812998 392 {
RedBearLab 0:075ea2812998 393 serial.printf("C"); //ACI Command
RedBearLab 0:075ea2812998 394 m_aci_data_print(p_aci_cmd);
RedBearLab 0:075ea2812998 395 }
RedBearLab 0:075ea2812998 396 }
RedBearLab 0:075ea2812998 397
RedBearLab 0:075ea2812998 398 return ret_val;
RedBearLab 0:075ea2812998 399 }
RedBearLab 0:075ea2812998 400
RedBearLab 0:075ea2812998 401 static uint8_t spi_readwrite(const uint8_t aci_byte)
RedBearLab 0:075ea2812998 402 {
RedBearLab 0:075ea2812998 403 uint8_t tmp_byte;
RedBearLab 0:075ea2812998 404 tmp_byte = REVERSE_BITS(aci_byte);
RedBearLab 0:075ea2812998 405 tmp_byte = spi.write(tmp_byte);
RedBearLab 0:075ea2812998 406 return REVERSE_BITS(tmp_byte);
RedBearLab 0:075ea2812998 407 }
RedBearLab 0:075ea2812998 408
RedBearLab 0:075ea2812998 409 bool hal_aci_tl_rx_q_empty (void)
RedBearLab 0:075ea2812998 410 {
RedBearLab 0:075ea2812998 411 return aci_queue_is_empty(&aci_rx_q);
RedBearLab 0:075ea2812998 412 }
RedBearLab 0:075ea2812998 413
RedBearLab 0:075ea2812998 414 bool hal_aci_tl_rx_q_full (void)
RedBearLab 0:075ea2812998 415 {
RedBearLab 0:075ea2812998 416 return aci_queue_is_full(&aci_rx_q);
RedBearLab 0:075ea2812998 417 }
RedBearLab 0:075ea2812998 418
RedBearLab 0:075ea2812998 419 bool hal_aci_tl_tx_q_empty (void)
RedBearLab 0:075ea2812998 420 {
RedBearLab 0:075ea2812998 421 return aci_queue_is_empty(&aci_tx_q);
RedBearLab 0:075ea2812998 422 }
RedBearLab 0:075ea2812998 423
RedBearLab 0:075ea2812998 424 bool hal_aci_tl_tx_q_full (void)
RedBearLab 0:075ea2812998 425 {
RedBearLab 0:075ea2812998 426 return aci_queue_is_full(&aci_tx_q);
RedBearLab 0:075ea2812998 427 }
RedBearLab 0:075ea2812998 428
RedBearLab 0:075ea2812998 429 void hal_aci_tl_q_flush (void)
RedBearLab 0:075ea2812998 430 {
RedBearLab 0:075ea2812998 431 m_aci_q_flush();
RedBearLab 0:075ea2812998 432 }