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);
  }
}
Пример #2
0
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();
}
Пример #3
0
void hal_aci_tl_init(aci_pins_t *a_pins)
{
  received_data.buffer[0] = 0;
  
  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();
  spi.setBitOrder(MSBFIRST); //Use MSBFIRST and REVERSE the bits on the SPI as LSBFIRST is not supported
  spi.setClockDivider(a_pins->spi_clock_divider);
  spi.setDataMode(SPI_MODE0);
   
  /* initialize aci cmd queue */
  m_aci_q_init(&aci_tx_q);  
  m_aci_q_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);  
  }
  

  if (UNUSED != a_pins->reset_pin)
  {
	pinMode(a_pins->reset_pin,	OUTPUT);
	
	if (REDBEARLAB_SHIELD_V1_1 == a_pins->board_name)
	{
		//The reset for this board is inverted and has a Power On Reset
		//circuit that takes about 100ms to trigger the reset
		digitalWrite(a_pins->reset_pin, 1);
		delay(100);
		digitalWrite(a_pins->reset_pin, 0);		
	}
	else
	{
		digitalWrite(a_pins->reset_pin, 1);
		digitalWrite(a_pins->reset_pin, 0);		
		digitalWrite(a_pins->reset_pin, 1);
	}
	
  }
  
  
  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)
  {
	attachInterrupt(a_pins->interrupt_number, m_rdy_line_handle, LOW); // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW  
  }
}
Пример #4
0
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);
    }
}