Beispiel #1
0
void HCI_Process(void)
{
  uint8_t data_len;
  uint8_t buffer[HCI_READ_PACKET_SIZE];
  tHciDataPacket * hciReadPacket = NULL;
  
  Disable_SPI_IRQ();
  uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);        
  /* process any pending events read */
  while(list_empty == FALSE)
  {
    list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
    Enable_SPI_IRQ();
    HCI_Event_CB(hciReadPacket->dataBuff);
    Disable_SPI_IRQ();
    list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
    list_empty = list_is_empty(&hciReadPktRxQueue);
  }
  if (readPacketListFull) {
    while(BlueNRG_DataPresent()) {
      data_len = BlueNRG_SPI_Read_All(&SpiHandle, buffer, HCI_READ_PACKET_SIZE);
      if(data_len > 0)
        HCI_Event_CB(buffer);
    }
    readPacketListFull = FALSE;
  }
  
  Enable_SPI_IRQ();    
}
Beispiel #2
0
int hci_send_req(struct hci_request *r, BOOL async)
{
  uint8_t *ptr;
  uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
  hci_event_pckt *event_pckt;
  hci_uart_pckt *hci_hdr;
  int to = DEFAULT_TIMEOUT;
  struct timer t;
  tHciDataPacket * hciReadPacket = NULL;
  tListNode hciTempQueue;
  
  list_init_head(&hciTempQueue);
  
  hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
  
  if(async){
    goto done;
  }
  
  /* Minimum timeout is 1. */
  if(to == 0)
    to = 1;
  
  Timer_Set(&t, to);
  
  while(1) {
    evt_cmd_complete *cc;
    evt_cmd_status *cs;
    evt_le_meta_event *me;
    int len;
      
#if ENABLE_MICRO_SLEEP    
    while(1){
      ATOMIC_SECTION_BEGIN();
      if(Timer_Expired(&t)){
        ATOMIC_SECTION_END();
        goto failed;
      }
      if(!HCI_Queue_Empty()){
        ATOMIC_SECTION_END();
        break;
      }
      Enter_Sleep_Mode();
      ATOMIC_SECTION_END();
    }
#else
    while(1){
      if(Timer_Expired(&t)){
        goto failed;
      }
      if(!HCI_Queue_Empty()){
        break;
      }
    }
#endif
    
    /* Extract packet from HCI event queue. */
    Disable_SPI_IRQ();
    list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket);    
    
    hci_hdr = (void *)hciReadPacket->dataBuff;
    if(hci_hdr->type != HCI_EVENT_PKT){
      list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below
      Enable_SPI_IRQ();
      continue;
    }
    
    event_pckt = (void *) (hci_hdr->data);
    
    ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE);
    len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE);
    
    switch (event_pckt->evt) {
      
    case EVT_CMD_STATUS:
      cs = (void *) ptr;
      
      if (cs->opcode != opcode)
        goto failed;
      
      if (r->event != EVT_CMD_STATUS) {
        if (cs->status) {
          goto failed;
        }
        break;
      }
      
      r->rlen = MIN(len, r->rlen);
      Osal_MemCpy(r->rparam, ptr, r->rlen);
      goto done;
      
    case EVT_CMD_COMPLETE:
      cc = (void *) ptr;
      
      if (cc->opcode != opcode)
        goto failed;
      
      ptr += EVT_CMD_COMPLETE_SIZE;
      len -= EVT_CMD_COMPLETE_SIZE;
      
      r->rlen = MIN(len, r->rlen);
      Osal_MemCpy(r->rparam, ptr, r->rlen);
      goto done;
      
    case EVT_LE_META_EVENT:
      me = (void *) ptr;
      
      if (me->subevent != r->event)
        break;
      
      len -= 1;
      r->rlen = MIN(len, r->rlen);
      Osal_MemCpy(r->rparam, me->data, r->rlen);
      goto done;
      
    case EVT_HARDWARE_ERROR:            
      goto failed;
      
    default:      
      break;
    }
    
    /* In the meantime there could be other events from the controller.
    In this case, insert the packet in a different queue. These packets will be
    inserted back in the main queue just before exiting from send_req().
    */
    list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket);
    /* Be sure there is at list one packet in the pool to process the expected event. */
    if(list_is_empty(&hciReadPktPool)){
      pListNode tmp_node;      
      list_remove_head(&hciReadPktRxQueue, &tmp_node);
      list_insert_tail(&hciReadPktPool, tmp_node);      
    }
    
    Enable_SPI_IRQ();
    
  }
  
failed: 
  move_list(&hciReadPktRxQueue, &hciTempQueue);  
  Enable_SPI_IRQ();
  return -1;
  
done:
  // Insert the packet back into the pool.
  list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 
  move_list(&hciReadPktRxQueue, &hciTempQueue);
  
  Enable_SPI_IRQ();
  return 0;
}
/*******************************************************************************
* @brief  Writes data from local buffer to SPI.
*
* @param  hspi     : Handle of the STM32Cube HAL SPI interface
* @param  data1    : First data buffer to be written
* @param  data2    : Second data buffer to be written
* @param  Nb_bytes1: Size of first data buffer to be written
* @param  Nb_bytes2: Size of second data buffer to be written
* @retval Number of read bytes
*
* Called by:  Hal_Write_Serial
*
*
* _All_ those routines call this using a hardcoded pointer to &SpiHandle.
* CALLERs:  aci_write_hal_config -> hci_send_cmd -> hci_write -> Hal_Write_Serial()
*           aci_gatt_init  -> hci_send_cmd -> hci_write -> Hal_Write_Serial()
*           aci_gap_init  -> hci_send_cmd -> hci_write -> Hal_Write_Serial()
*******************************************************************************/
int32_t  BlueNRG_SPI_Write (SPI_HandleTypeDef *hspi, uint8_t* data1,
                            uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
{
    int32_t  result = 0;

    int32_t  spi_fix_enabled = 0;

#ifdef ENABLE_SPI_FIX
    spi_fix_enabled = 1;
#endif //ENABLE_SPI_FIX

  unsigned char  header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
  unsigned char  header_slave[HEADER_SIZE]  = {0xaa, 0x00, 0x00, 0x00, 0x00};

  unsigned char  read_char_buf [MAX_BUFFER_SIZE];

    Disable_SPI_IRQ();

      /*
      ** If the SPI_FIX is enabled, the IRQ is set in Output mode, then it is pulled
      ** high and, after a delay of at least 112us, the CS line is asserted and the
      ** header transmit/receive operations are started.
      ** After these transmit/receive operations the IRQ is reset in input mode.
      */
  if (spi_fix_enabled)
     {
       set_irq_as_output();

// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
// WVD  ??? !!!  CROSS_PLATFORM EXPOSURE - esp for FASTER DEVICES  !!! ???
// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
             /* Wait to Assert CS line until after at least 112us */
       us150Delay();
     }

       /* ASSERT CS line */
////HAL_GPIO_WritePin (BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
    ASSERT_CS_BlueNRG();           // Ensure CS is set to ACTIVE

      /* Exchange header with BlueNRG */
////HAL_SPI_TransmitReceive (hspi, header_master, header_slave, HEADER_SIZE, TIMEOUT_DURATION); // WORKS
    spi_Write_Read (BLE_BLUENRG_SPI_ID, header_master, header_slave,
                    HEADER_SIZE, 0);

  if (spi_fix_enabled)
     {
       set_irq_as_input();
     }

  if (header_slave[0] == 0x02)
     {
             /* SPI is ready */
       if (header_slave[1] >= (Nb_bytes1+Nb_bytes2))
          {
                  /*  ensure Buffer is big enough */
           if (Nb_bytes1 > 0)
              {
////            HAL_SPI_TransmitReceive (hspi, data1, read_char_buf, Nb_bytes1, TIMEOUT_DURATION);
                spi_Write_Read (BLE_BLUENRG_SPI_ID,
                                data1, read_char_buf,
                                Nb_bytes1, 0);

              }
           if (Nb_bytes2 > 0)
              {
////            HAL_SPI_TransmitReceive (hspi, data2, read_char_buf, Nb_bytes2, TIMEOUT_DURATION);
                spi_Write_Read (BLE_BLUENRG_SPI_ID,
                                data2, read_char_buf,
                                Nb_bytes2, 0);
              }
     }
    else {
              /* Buffer is too small */
           result = -2;
         }
    }
   else {
              /* SPI is not ready */
            result = -1;
        }

              /* Release CS line */
////HAL_GPIO_WritePin (BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
    DEASSERT_CS_BlueNRG();                     // Ensure CS is set to NOT active

    Enable_SPI_IRQ();

    return result;
}
Beispiel #4
0
/**
* @brief  Writes data from local buffer to SPI.
* @param  hspi     : Handle of the STM32Cube HAL SPI interface
* @param  data1    : First data buffer to be written
* @param  data2    : Second data buffer to be written
* @param  Nb_bytes1: Size of first data buffer to be written
* @param  Nb_bytes2: Size of second data buffer to be written
* @retval Number of read bytes
*/
int32_t BlueNRG_SPI_Write(SPI_HandleTypeDef * hspi, uint8_t * data1,
			  uint8_t * data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
{
	int32_t result = 0;

	int32_t spi_fix_enabled = 0;

#ifdef ENABLE_SPI_FIX
	spi_fix_enabled = 1;
#endif //ENABLE_SPI_FIX

	unsigned char header_master[HEADER_SIZE] =
	    { 0x0a, 0x00, 0x00, 0x00, 0x00 };
	unsigned char header_slave[HEADER_SIZE] =
	    { 0xaa, 0x00, 0x00, 0x00, 0x00 };

	unsigned char read_char_buf[MAX_BUFFER_SIZE];

	Disable_SPI_IRQ();

	/*
	   If the SPI_FIX is enabled the IRQ is set in Output mode, then it is pulled
	   high and, after a delay of at least 112us, the CS line is asserted and the
	   header transmit/receive operations are started.
	   After these transmit/receive operations the IRQ is reset in input mode.
	 */
	if (spi_fix_enabled) {
		set_irq_as_output();

		/* Assert CS line after at least 112us */
		us150Delay();
	}

	/* CS reset */
	HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);

	/* Exchange header */
	HAL_SPI_TransmitReceive(hspi, header_master, header_slave, HEADER_SIZE,
				TIMEOUT_DURATION);

	if (spi_fix_enabled) {
		set_irq_as_input();
	}

	if (header_slave[0] == 0x02) {
		/* SPI is ready */
		if (header_slave[1] >= (Nb_bytes1 + Nb_bytes2)) {

			/*  Buffer is big enough */
			if (Nb_bytes1 > 0) {
				HAL_SPI_TransmitReceive(hspi, data1,
							read_char_buf,
							Nb_bytes1,
							TIMEOUT_DURATION);
			}
			if (Nb_bytes2 > 0) {
				HAL_SPI_TransmitReceive(hspi, data2,
							read_char_buf,
							Nb_bytes2,
							TIMEOUT_DURATION);
			}

		} else {
			/* Buffer is too small */
			result = -2;
		}
	} else {
		/* SPI is not ready */
		result = -1;
	}

	/* Release CS line */
	HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);

	Enable_SPI_IRQ();

	return result;
}
Beispiel #5
0
void new_hci_event(void *pckt, uint16_t len)
{
	Disable_SPI_IRQ(); /* Must be re-enabled after packet processing. */

	new_packet = TRUE;
}