1765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* Copyright (c) 2014, Nordic Semiconductor ASA
2765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
3765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Permission is hereby granted, free of charge, to any person obtaining a copy
4765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * of this software and associated documentation files (the "Software"), to deal
5765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * in the Software without restriction, including without limitation the rights
6765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * copies of the Software, and to permit persons to whom the Software is
8765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * furnished to do so, subject to the following conditions:
9765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
10765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * The above copyright notice and this permission notice shall be included in all
11765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * copies or substantial portions of the Software.
12765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
13765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * SOFTWARE.
20765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
21765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
22765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/**
23765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @file
24765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @brief Interface for hal_aci_tl.
25765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @ingroup nrf8001
26765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
27765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
28765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/**
29765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang@{
30765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
31765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang@brief Module for the ACI Transport Layer interface
32765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang@details This module is responsible for sending and receiving messages over the ACI interface of the nRF8001 chip.
33765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang The hal_aci_tl_send_cmd() can be called directly to send ACI commands.
34765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
35765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
36765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangThe RDYN line is hooked to an interrupt on the MCU when the level is low.
37765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangThe SPI master clocks in the interrupt context.
38765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangThe ACI Command is taken from the head of the command queue is sent over the SPI
39765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangand the received ACI event is placed in the tail of the event queue.
40765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
41765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang*/
42765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
43765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#ifndef HAL_ACI_TL_H__
44765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HAL_ACI_TL_H__
45765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
46765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include "hal_platform.h"
47765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include "aci.h"
48765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include "boards.h"
49765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
50765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <mraa/aio.h>
51765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <mraa/gpio.h>
52765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <mraa/spi.h>
53765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
54765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#ifndef HAL_ACI_MAX_LENGTH
55765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HAL_ACI_MAX_LENGTH 31
56765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#endif
57765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
58765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/************************************************************************/
59765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* Unused nRF8001 pin                                                    */
60765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/************************************************************************/
61765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define UNUSED          255
62765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
63765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** Data type for ACI commands and events */
64765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangtypedef struct {
65765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang  uint8_t status_byte;
66765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang  uint8_t buffer[HAL_ACI_MAX_LENGTH+1];
67765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} _aci_packed_ hal_aci_data_t;
68765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
69765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangACI_ASSERT_SIZE(hal_aci_data_t, HAL_ACI_MAX_LENGTH + 2);
70765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
71765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** Datatype for ACI pins and interface (polling/interrupt)*/
72765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangtypedef struct aci_pins_t
73765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{
74765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    mraa_spi_context        m_spi;
75765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    mraa_gpio_context       m_rdy_ctx;
76765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    mraa_gpio_context       m_req_ctx;
77765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    mraa_gpio_context       m_rst_ctx;
78765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
79765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t board_name;             //Optional : Use BOARD_DEFAULT if you do not know. See boards.h
80765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t reqn_pin;               //Required
81765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t rdyn_pin;               //Required
82765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t mosi_pin;               //Required
83765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t miso_pin;               //Required
84765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t sck_pin;                //Required
85765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
86765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t spi_clock_divider;      //Required : Clock divider on the SPI clock : nRF8001 supports a maximum clock of 3MHz
87765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
88765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t reset_pin;              //Recommended but optional - Set it to UNUSED when not connected
89765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t active_pin;             //Optional - Set it to UNUSED when not connected
90765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t optional_chip_sel_pin;  //Optional - Used only when the reqn line is required to be separate from the SPI chip select. Eg. Arduino DUE
91765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
92765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    bool    interface_is_interrupt; //Required - true = Uses interrupt on RDYN pin. false - Uses polling on RDYN pin
93765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
94765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    uint8_t interrupt_number;       //Required when using interrupts, otherwise ignored
95765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} aci_pins_t;
96765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
97765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief ACI Transport Layer initialization.
98765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
99765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  This function initializes the transport layer, including configuring the SPI, creating
100765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  message queues for Commands and Events and setting up interrupt if required.
101765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @param a_pins Pins on the MCU used to connect to the nRF8001
102765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @param bool True if debug printing should be enabled on the Serial.
103765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
104765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid hal_aci_tl_init(aci_pins_t *a_pins, bool debug);
105765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
106765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Sends an ACI command to the radio.
107765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
108765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  This function sends an ACI command to the radio. This queue up the message to send and
109765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  lower the request line. When the device lowers the ready line, @ref m_aci_spi_transfer()
110765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  will send the data.
111765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @param aci_buffer Pointer to the message to send.
112765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @return True if the data was successfully queued for sending,
113765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  false if there is no more space to store messages to send.
114765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
115765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool hal_aci_tl_send(hal_aci_data_t *aci_buffer);
116765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
117765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Process pending transactions.
118765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
119765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  The library code takes care of calling this function to check if the nRF8001 RDYN line indicates a
120765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  pending transaction. It will send a pending message if there is one and return any receive message
121765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  that was pending.
122765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @return Points to data buffer for received data. Length byte in buffer is 0 if no data received.
123765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
124765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhanghal_aci_data_t * hal_aci_tl_poll_get(void);
125765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
126765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Get an ACI event from the event queue
127765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
128765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  Call this function from the main context to get an event from the ACI event queue
129765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  This is called by lib_aci_event_get
130765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
131765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);
132765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
133765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Peek an ACI event from the event queue
134765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
135765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  Call this function from the main context to peek an event from the ACI event queue.
136765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  This is called by lib_aci_event_peek
137765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
138765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data);
139765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
140765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Enable debug printing of all ACI commands sent and ACI events received
141765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
142765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  when the enable parameter is true. The debug printing is enabled on the Serial.
143765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  When the enable parameter is false. The debug printing is disabled on the Serial.
144765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  By default the debug printing is disabled.
145765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
146765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid hal_aci_tl_debug_print(bool enable);
147765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
148765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
149765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Pin reset the nRF8001
150765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
151765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  The reset line of the nF8001 needs to kept low for 200 ns.
152765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  Redbearlab shield v1.1 and v2012.07 are exceptions as they
153765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  have a Power ON Reset circuit that works differently.
154765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  The function handles the exceptions based on the board_name in aci_pins_t
155765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
156765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid hal_aci_tl_pin_reset(void);
157765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
158765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Return full status of transmit queue
159765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
160765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
161765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
162765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang bool hal_aci_tl_rx_q_full(void);
163765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
164765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang /** @brief Return empty status of receive queue
165765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
166765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
167765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
168765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang bool hal_aci_tl_rx_q_empty(void);
169765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
170765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Return full status of receive queue
171765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
172765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
173765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
174765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang bool hal_aci_tl_tx_q_full(void);
175765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
176765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang /** @brief Return empty status of transmit queue
177765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
178765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
179765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
180765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang bool hal_aci_tl_tx_q_empty(void);
181765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
182765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @brief Flush the ACI command Queue and the ACI Event Queue
183765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  @details
184765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *  Call this function in the main thread
185765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
186765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid hal_aci_tl_q_flush(void);
187765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
188765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#endif // HAL_ACI_TL_H__
189765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/** @} */
190