Exemple #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();    
}
Exemple #2
0
int HCI_Process(void)
{
  uint8_t data_len;
  
  tHciDataPacket * hciReadPacket = NULL;
  uint8_t retries = 0;
  
  uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);        
  /* process any pending events read */
  //events are added to tail in ISR
  while(list_empty == FALSE)
  {
    list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
 
    HCI_Event_CB(hciReadPacket->dataBuff);
    
    list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
    
    list_empty = list_is_empty(&hciReadPktRxQueue); 
  }
  

    if (readPacketListFull)  //readPacketListFull is set in interrupt context
    {
        while(BlueNRG_DataPresent()) 
        {
            __debug_hci("Data too fast"); 
            
            data_len = BlueNRG_SPI_Read_All(HCI_Process_buffer, HCI_READ_PACKET_SIZE);
      
            if(data_len > 0)
            {
                HCI_Event_CB(hciReadPacket->dataBuff);
    
                retries = 0;
            }
            else
            {
                retries++;
                if(retries > 1)
                {
                    return -1;
                    break;
                }
                
            }
        }
        readPacketListFull = FALSE; //check if we ever get here
    }
    if(ISRDevice_busy == TRUE)
    {
        ISRDevice_busy = FALSE;
        return -2;
    }
    return 1;
}
Exemple #3
0
void HCI_recv_packet(unsigned char* packet_buffer, unsigned int packet_length) {
  tHciDataPacket * hciReadPacket = NULL;

  if (!list_is_empty ((tListNode*)&hciReadPktPool)){
      
    if(packet_length > 0) {
      /* enqueueing a packet for read */
      list_remove_head ((tListNode*)&hciReadPktPool, (tListNode **)&hciReadPacket);
      
      Osal_MemCpy(hciReadPacket->dataBuff, packet_buffer, MIN(HCI_READ_PACKET_SIZE, packet_length));
    
      hciReadPacket->data_len = packet_length;
      switch(HCI_verify(hciReadPacket)) {
        case 0:
          list_insert_tail((tListNode*)&hciReadPktRxQueue, (tListNode *)hciReadPacket);
          break;

        default:
        case 1:
        case 2:
          list_insert_head((tListNode*)&hciReadPktPool, (tListNode *)hciReadPacket);
          break;
      }
    }
  }
  else{
    // HCI Read Packet Pool is empty, wait for a free packet.
    readPacketListFull = TRUE;
    return;
  }

  // process incoming packet

  // don't process when hci_send_req is undergoing
  if (hciAwaitReply) {
    return;
  }

  /* process any pending events read */
  while(!list_is_empty((tListNode*)&hciReadPktRxQueue))
  {
    list_remove_head ((tListNode*)&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
    //Enable_SPI_IRQ();
    HCI_Event_CB(hciReadPacket->dataBuff);
    //Disable_SPI_IRQ();
    list_insert_tail((tListNode*)&hciReadPktPool, (tListNode *)hciReadPacket);
  }
}
Exemple #4
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 = /*1;*/ DEFAULT_TIMEOUT;
  struct timer t;
  tHciDataPacket * hciReadPacket = NULL;
  tListNode hciTempQueue;
  
  list_init_head((tListNode*)&hciTempQueue);

  // cannot be processed, due to reentrancy
  if (hciAwaitReply) {
    return -1;
  }

  hciAwaitReply = TRUE;
  
  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;

    // we're done with the sending, wait for a reply from the bluenrg
    io_seproxyhal_general_status();

    // perform io_event based loop to wait for BLUENRG_RECV_EVENT
    for (;;) {
      io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0);
      // check if event is a ticker event
      unsigned int ticker_event = G_io_seproxyhal_spi_buffer[0] == SEPROXYHAL_TAG_TICKER_EVENT;

      // process IOs, and BLE fetch, ble queue is updated through common code
      io_seproxyhal_handle_event();

      // don't ack the BLUENRG_RECV_EVENT as we would require to reply another command to it.
      if(!list_is_empty((tListNode*)&hciReadPktRxQueue)){
        /* Extract packet from HCI event queue. */
        //Disable_SPI_IRQ();
        list_remove_head((tListNode*)&hciReadPktRxQueue, (tListNode **)&hciReadPacket);    
        list_insert_tail((tListNode*)&hciTempQueue, (tListNode *)hciReadPacket);
        
        hci_hdr = (void *)hciReadPacket->dataBuff;
        if(hci_hdr->type != HCI_EVENT_PKT){
          move_list((tListNode*)&hciReadPktPool, (tListNode*)&hciTempQueue);  
          //list_insert_tail((tListNode*)&hciTempQueue, (tListNode *)hciReadPacket); // See comment below
          //Enable_SPI_IRQ();
          goto case_USER_PROCESS;
        }
        
        event_pckt = (void *) (hci_hdr->data);
        
        ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE);
        len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE);
        
        /* 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().
        */

        event_pckt = (void *) (hci_hdr->data);
        switch (event_pckt->evt) {
          
        case EVT_CMD_STATUS:
          cs = (void *) ptr;
          
          if (cs->opcode != opcode) {
            goto case_USER_PROCESS;
          }
          
          if (r->event != EVT_CMD_STATUS) {
            goto case_USER_PROCESS;
          }
          
          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 case_USER_PROCESS;
          }
          
          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) {
            goto case_USER_PROCESS;
          }
          
          len -= 1;
          r->rlen = MIN(len, r->rlen);
          Osal_MemCpy(r->rparam, me->data, r->rlen);
          goto done;
          
        case EVT_HARDWARE_ERROR:
          return -1;

        default:      
        case_USER_PROCESS:
          HCI_Event_CB(hciReadPacket->dataBuff);
          break;
        }
      }

      // timeout
      if (ticker_event) {
        if (to) {
          to--;
        }
        // don't signal timeout if the event has been closed by handle event to avoid sending commands after a status has been issued
        else if (!io_seproxyhal_spi_is_status_sent()) {
          return -1;
        }
      }

      // ack the received event we have processed
      io_seproxyhal_general_status();
    }
    
    
    //Enable_SPI_IRQ();
    
  }
  
failed: 
  move_list((tListNode*)&hciReadPktPool, (tListNode*)&hciTempQueue);  
  hciAwaitReply = FALSE;
  //Enable_SPI_IRQ();
  return -1;
  
done:
  // Insert the packet back into the pool.
  /*
  if (hciReadPacket) {
    list_insert_head((tListNode*)&hciReadPktPool, (tListNode *)hciReadPacket); 
  }
  */
  move_list((tListNode*)&hciReadPktPool, (tListNode*)&hciTempQueue);
  hciAwaitReply = FALSE;
  //Enable_SPI_IRQ();
  return 0;
}