static void m_aci_q_flush(void) { noInterrupts(); /* re-initialize aci cmd queue and aci event queue to flush them*/ aci_queue_init(&aci_tx_q); aci_queue_init(&aci_rx_q); interrupts(); }
void hal_aci_tl_init(aci_pins_t *a_pins, bool debug) { aci_debug_print = debug; /* Needs to be called as the first thing for proper intialization*/ m_aci_pins_set(a_pins); /* The SPI lines used are mapped directly to the hardware SPI MISO MOSI and SCK Change here if the pins are mapped differently The SPI library assumes that the hardware pins are used */ SPI.begin(); //Board dependent defines #if defined (__AVR__) //For Arduino use the LSB first SPI.setBitOrder(LSBFIRST); #elif defined(__PIC32MX__) //For ChipKit use MSBFIRST and REVERSE the bits on the SPI as LSBFIRST is not supported SPI.setBitOrder(MSBFIRST); #endif SPI.setClockDivider(a_pins->spi_clock_divider); SPI.setDataMode(SPI_MODE0); /* Initialize the ACI Command queue. This must be called after the delay above. */ aci_queue_init(&aci_tx_q); aci_queue_init(&aci_rx_q); //Configure the IO lines pinMode(a_pins->rdyn_pin, INPUT_PULLUP); pinMode(a_pins->reqn_pin, OUTPUT); if (UNUSED != a_pins->active_pin) { pinMode(a_pins->active_pin, INPUT); } /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */ hal_aci_tl_pin_reset(); /* Set the nRF8001 to a known state as required by the datasheet*/ digitalWrite(a_pins->miso_pin, 0); digitalWrite(a_pins->mosi_pin, 0); digitalWrite(a_pins->reqn_pin, 1); digitalWrite(a_pins->sck_pin, 0); delay(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset /* Attach the interrupt to the RDYN line as requested by the caller */ if (a_pins->interface_is_interrupt) { // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW); } }
void hal_aci_tl_init(aci_pins_t *a_pins, bool debug) { aci_debug_print = debug; /* Needs to be called as the first thing for proper intialization*/ m_aci_pins_set(a_pins); /* The SPI lines used are mapped directly to the hardware SPI MISO MOSI and SCK Change here if the pins are mapped differently The SPI library assumes that the hardware pins are used */ spi_master_init(a_pins->spi); struct spi_device spi_device_conf = { .id = a_pins->reqn_pin }; spi_master_setup_device(a_pins->spi, &spi_device_conf, SPI_MODE_0, BLUETOOTH_DATA_RATE, 0); //Board dependent defines #if defined (__AVR__) //For Arduino use the LSB first a_pins->spi->CTRL |= SPI_DORD_bm; #elif defined(__PIC32MX__) //For ChipKit use MSBFIRST and REVERSE the bits on the SPI as LSBFIRST is not supported SPI.setBitOrder(MSBFIRST); #endif /* Initialize the ACI Command queue. This must be called after the delay above. */ aci_queue_init(&aci_tx_q); aci_queue_init(&aci_rx_q); //Configure the IO lines //pinMode(a_pins->rdyn_pin, INPUT_PULLUP); //pinMode(a_pins->reqn_pin, OUTPUT); spi_enable(a_pins->spi); if (UNUSED != a_pins->active_pin) { pinMode(a_pins->active_pin, INPUT); } /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */ hal_aci_tl_pin_reset(); /* Set the nRF8001 to a known state as required by the datasheet*/ digitalWrite(a_pins->miso_pin, 0); digitalWrite(a_pins->mosi_pin, 0); digitalWrite(a_pins->reqn_pin, 1); digitalWrite(a_pins->sck_pin, 0); delay(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset /* Attach the interrupt to the RDYN line as requested by the caller */ if (a_pins->interface_is_interrupt) { // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW); } } bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd) { const uint8_t length = p_aci_cmd->buffer[0]; bool ret_val = false; if (length > HAL_ACI_MAX_LENGTH) { return false; } ret_val = aci_queue_enqueue(&aci_tx_q, p_aci_cmd); if (ret_val) { if(!aci_queue_is_full(&aci_rx_q)) { // Lower the REQN only when successfully enqueued m_aci_reqn_enable(); } if (aci_debug_print) { //Serial.print("C"); //ACI Command m_aci_data_print(p_aci_cmd); } } return ret_val; } static uint8_t spi_readwrite(const uint8_t aci_byte) { //Board dependent defines #if defined (__AVR__) //For Arduino the transmission does not have to be reversed return spi_readwrite_xmega(aci_byte); #elif defined(__PIC32MX__) //For ChipKit the transmission has to be reversed uint8_t tmp_bits; tmp_bits = SPI.transfer(REVERSE_BITS(aci_byte)); return REVERSE_BITS(tmp_bits); #endif } bool hal_aci_tl_rx_q_empty (void) { return aci_queue_is_empty(&aci_rx_q); } bool hal_aci_tl_rx_q_full (void) { return aci_queue_is_full(&aci_rx_q); } bool hal_aci_tl_tx_q_empty (void) { return aci_queue_is_empty(&aci_tx_q); } bool hal_aci_tl_tx_q_full (void) { return aci_queue_is_full(&aci_tx_q); } void hal_aci_tl_q_flush (void) { m_aci_q_flush(); }
void hal_aci_tl_init(aci_pins_t *a_pins, bool debug) { mraa_result_t error = MRAA_SUCCESS; aci_debug_print = debug; /* Needs to be called as the first thing for proper intialization*/ m_aci_pins_set(a_pins); /* * Init SPI */ a_pins->m_spi = mraa_spi_init (0); if (a_pins->m_spi == NULL) { throw std::invalid_argument(std::string(__FUNCTION__) + ": mraa_spi_init() failed"); } mraa_spi_frequency (a_pins->m_spi, 2000000); mraa_spi_mode (a_pins->m_spi, MRAA_SPI_MODE0); /* Initialize the ACI Command queue. This must be called after the delay above. */ aci_queue_init(&aci_tx_q); aci_queue_init(&aci_rx_q); // Configure the IO lines a_pins->m_rdy_ctx = mraa_gpio_init (a_pins->rdyn_pin); if (a_pins->m_rdy_ctx == NULL) { throw std::invalid_argument(std::string(__FUNCTION__) + ": mraa_gpio_init(rdyn) failed, invalid pin?"); } a_pins->m_req_ctx = mraa_gpio_init (a_pins->reqn_pin); if (a_pins->m_req_ctx == NULL) { throw std::invalid_argument(std::string(__FUNCTION__) + ": mraa_gpio_init(reqn) failed, invalid pin?"); } a_pins->m_rst_ctx = mraa_gpio_init (a_pins->reset_pin); if (a_pins->m_rst_ctx == NULL) { throw std::invalid_argument(std::string(__FUNCTION__) + ": mraa_gpio_init(reset) failed, invalid pin?"); } error = mraa_gpio_dir (a_pins->m_rdy_ctx, MRAA_GPIO_IN); if (error != MRAA_SUCCESS) { printf ("[ERROR] GPIO failed to initilize \n"); } error = mraa_gpio_dir (a_pins->m_req_ctx, MRAA_GPIO_OUT); if (error != MRAA_SUCCESS) { printf ("[ERROR] GPIO failed to initilize \n"); } error = mraa_gpio_dir (a_pins->m_rst_ctx, MRAA_GPIO_OUT); if (error != MRAA_SUCCESS) { printf ("[ERROR] GPIO failed to initilize \n"); } if (UNUSED != a_pins->active_pin) { } /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */ hal_aci_tl_pin_reset(); /* Set the nRF8001 to a known state as required by the datasheet*/ mraa_gpio_write (a_pins->m_req_ctx, LOW); usleep(30000); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset /* Attach the interrupt to the RDYN line as requested by the caller */ if (a_pins->interface_is_interrupt) { // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW // attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW); } }