예제 #1
0
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
{
  unsigned char dummy;
  
  DEBUGPRINT_F("\tCC3000: SpiWriteDataSynchronous Start\n\r");

  uint8_t loc;
  for (loc = 0; loc < size; loc ++) 
  {
    dummy = SPI.transfer(data[loc]);
#if (DEBUG_MODE == 1)
      if (!(loc==size-1))
      {
        DEBUGPRINT_F(" ");
        DEBUGPRINT_HEX(data[loc]); 
      }
      else
      {
        DEBUGPRINT_F(" ");
        DEBUGPRINT_HEX(data[loc]);
      }
#endif
  }
  
  DEBUGPRINT_F("\n\r\tCC3000: SpiWriteDataSynchronous End\n\r");
}
예제 #2
0
long ReadWlanInterruptPin(void)
{
  DEBUGPRINT_F("\tCC3000: ReadWlanInterruptPin - ");
  DEBUGPRINT_DEC(digitalRead(g_irqPin));
  DEBUGPRINT_F("\n\r");

  return(digitalRead(g_irqPin));
}
예제 #3
0
void
wlan_start(unsigned short usPatchesAvailableAtHost)
{

    unsigned long ulSpiIRQState;

    tSLInformation.NumberOfSentPackets = 0;
    tSLInformation.NumberOfReleasedPackets = 0;
    tSLInformation.usRxEventOpcode = 0;
    tSLInformation.usNumberOfFreeBuffers = 0;
    tSLInformation.usSlBufferLength = 0;
    tSLInformation.usBufferSize = 0;
    tSLInformation.usRxDataPending = 0;
    tSLInformation.slTransmitDataError = 0;
    tSLInformation.usEventOrDataReceived = 0;
    tSLInformation.pucReceivedData = 0;

    // Allocate the memory for the RX/TX data transactions
    tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer;

    // init spi
    SpiOpen(SpiReceiveHandler);

    // Check the IRQ line
    ulSpiIRQState = tSLInformation.ReadWlanInterruptPin();

    // ASIC 1273 chip enable: toggle WLAN EN line
    tSLInformation.WriteWlanPin( WLAN_ENABLE );

    if (ulSpiIRQState)
    {
        // wait till the IRQ line goes low
        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }
    else
    {
        // wait till the IRQ line goes high and than low
        while(tSLInformation.ReadWlanInterruptPin() == 0)
        {
        }

        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }
    DEBUGPRINT_F("SimpleLink start\n\r");
    SimpleLink_Init_Start(usPatchesAvailableAtHost);

    // Read Buffer's size and finish
    DEBUGPRINT_F("Read buffer\n\r");
    hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0);
    SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0);
}
예제 #4
0
void SpiReadDataSynchronous(unsigned char *data, unsigned short size)
{
  unsigned short i = 0;
  
  DEBUGPRINT_F("\tCC3000: SpiReadDataSynchronous\n\r");
  SPI.setDataMode(SPI_MODE1);
  for (i = 0; i < size; i ++)
  {
    data[i] = SPI.transfer(0x03);
    DEBUGPRINT_F("  ");
    DEBUGPRINT_HEX(data[i]);
  }
  DEBUGPRINT_F("\n\r");
}
예제 #5
0
int init_spi(void)
{

  DEBUGPRINT_F("\tCC3000: init_spi\n\r");
  
  /* Set POWER_EN pin to output and disable the CC3000 by default */
  pinMode(g_vbatPin, OUTPUT);
  digitalWrite(g_vbatPin, 0);
  delay(500);

  /* Set CS pin to output (don't de-assert yet) */
  pinMode(g_csPin, OUTPUT);
  //pinMode(g_csPin - 1, OUTPUT);
  
  /* Set interrupt/gpio pin to input */
//#if defined(INPUT_PULLUP)
//  pinMode(g_irqPin, INPUT_PULLUP);/
//#else
  pinMode(g_irqPin, INPUT);
 // digitalWrite(g_irqPin, HIGH); // w/weak pullup
//#endif

  SpiConfigStoreOld(); // prime ccspi_old* values for DEASSERT

  /* Initialise SPI (Mode 1) */
  
  theCcspi->setDataMode(SPI_MODE1);
  theCcspi->setBitOrder(true);
  //theCcspi->setClockDivider(g_SPIspeed);
  DEBUGPRINT_F("\tCC3000: init_spi1\n\r");
  
  theCcspi->begin();
	
  DEBUGPRINT_F("\tCC3000: init_spi2\n\r");
  
  
  SpiConfigStoreMy(); // prime ccspi_my* values for ASSERT

  // Newly-initialized SPI is in the same state that ASSERT_CS will set it
  // to.  Invoke DEASSERT (which also restores SPI registers) so the next
  // ASSERT call won't clobber the ccspi_old* values -- we need those!
  CC3000_DEASSERT_CS;

  /* ToDo: Configure IRQ interrupt! */

  DEBUGPRINT_F("\tCC3000: Finished init_spi\n\r");
  
  return(ESUCCESS);
}
예제 #6
0
int init_spi(void)
{

  DEBUGPRINT_F("\tCC3000: init_spi\n\r");
  
  /* Set POWER_EN pin to output and disable the CC3000 by default */
  pinMode(g_vbatPin, OUTPUT);
  digitalWrite(g_vbatPin, 0);
  delay(500);

  /* Set CS pin to output (don't de-assert yet) */
  pinMode(g_csPin, OUTPUT);

  /* Set interrupt/gpio pin to input */
#if defined(INPUT_PULLUP)
  pinMode(g_irqPin, INPUT_PULLUP);
#else
  pinMode(g_irqPin, INPUT);
  digitalWrite(g_irqPin, HIGH); // w/weak pullup
#endif

  SpiConfigStoreOld(); // prime ccspi_old* values for DEASSERT

  /* Initialise SPI (Mode 1) */
  SPI.begin();
  SPI.setDataMode(SPI_MODE1);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(g_SPIspeed);
  
  SpiConfigStoreMy(); // prime ccspi_my* values for ASSERT

  // Newly-initialized SPI is in the same state that ASSERT_CS will set it
  // to.  Invoke DEASSERT (which also restores SPI registers) so the next
  // ASSERT call won't clobber the ccspi_old* values -- we need those!
#ifdef SPI_HAS_TRANSACTION
  SPI.usingInterrupt(g_IRQnum);
  digitalWrite(g_csPin, HIGH);  // same as CC3000_DEASSERT_CS, but not
  SpiConfigPop();               // SPI.endTransaction, because none began
#else
  CC3000_DEASSERT_CS;
#endif

  /* ToDo: Configure IRQ interrupt! */

  DEBUGPRINT_F("\tCC3000: Finished init_spi\n\r");
  
  return(ESUCCESS);
}
예제 #7
0
void SpiPauseSpi(void)
{
  DEBUGPRINT_F("\tCC3000: SpiPauseSpi\n\r");

  ccspi_int_enabled = 0;
  detachInterrupt(g_IRQnum);
}
예제 #8
0
void SpiResumeSpi(void)
{
  DEBUGPRINT_F("\tCC3000: SpiResumeSpi\n\r");

  ccspi_int_enabled = 1;
  attachInterrupt(g_IRQnum, SPI_IRQ, FALLING);
}
예제 #9
0
void WlanInterruptEnable()
{
  DEBUGPRINT_F("\tCC3000: WlanInterruptEnable.\n\r");
  // delay(100);
  ccspi_int_enabled = 1;
  attachInterrupt(g_IRQnum, SPI_IRQ, FALLING);
}
예제 #10
0
//*****************************************************************************
//
//!  simple_link_recv
//!
//!  @param sd       socket handle
//!  @param buf      read buffer
//!  @param len      buffer length
//!  @param flags    indicates blocking or non-blocking operation
//!  @param from     pointer to an address structure indicating source address
//!  @param fromlen  source address structure size
//!
//!  @return         Return the number of bytes received, or -1 if an error
//!                  occurred
//!
//!  @brief          Read data from socket
//!                  Return the length of the message on successful completion.
//!                  If a message is too long to fit in the supplied buffer,
//!                  excess bytes may be discarded depending on the type of
//!                  socket the message is received from
//
//*****************************************************************************
int
simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
                socklen_t *fromlen, long opcode)
{
	unsigned char *ptr, *args;
	tBsdReadReturnParams tSocketReadEvent;
	
	ptr = tSLInformation.pucTxCommandBuffer;
	args = (ptr + HEADERS_SIZE_CMD);
	
	// Fill in HCI packet structure
	args = UINT32_TO_STREAM(args, sd);
	args = UINT32_TO_STREAM(args, len);
	args = UINT32_TO_STREAM(args, flags);

	// Generate the read command, and wait for the 
	hci_command_send(opcode,  ptr, SOCKET_RECV_FROM_PARAMS_LEN);
	
	// Since we are in blocking state - wait for event complete
	SimpleLinkWaitEvent(opcode, &tSocketReadEvent);

	DEBUGPRINT_F("\n\r\tRecv'd data... Socket #");
	DEBUGPRINT_DEC(tSocketReadEvent.iSocketDescriptor);
	DEBUGPRINT_F(" Bytes: 0x");
	DEBUGPRINT_HEX(tSocketReadEvent.iNumberOfBytes);
	DEBUGPRINT_F(" Flags: 0x");
	DEBUGPRINT_HEX(tSocketReadEvent.uiFlags);
	DEBUGPRINT_F("\n\r");

	// In case the number of bytes is more then zero - read data
	if (tSocketReadEvent.iNumberOfBytes > 0)
	{
		// Wait for the data in a synchronous way. Here we assume that the bug is 
		// big enough to store also parameters of receive from too....
	  SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen);
	}
	
	errno = tSocketReadEvent.iNumberOfBytes;

#if (DEBUG_MODE == 1)
	for (uint8_t i=0; i<errno; i++) {
	  uart_putchar(((unsigned char *)buf)[i]);
	}
#endif
	
	return(tSocketReadEvent.iNumberOfBytes);
}
예제 #11
0
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
{
  DEBUGPRINT_F("\tCC3000: SpiWriteFirst\n\r");
  
  /* Workaround for the first transaction */
  CC3000_ASSERT_CS;
  DEBUGPRINT_F(digitalRead(g_irqPin));
  /* delay (stay low) for ~50us */
  //delayMicroseconds(50);
	DEBUGPRINT_F(digitalRead(g_irqPin));
  /* SPI writes first 4 bytes of data */
  SpiWriteDataSynchronous(ucBuf, 4);
	DEBUGPRINT_F(digitalRead(g_irqPin));
  //delayMicroseconds(50);
	DEBUGPRINT_F(digitalRead(g_irqPin));
  SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
	DEBUGPRINT_F(digitalRead(g_irqPin));
  /* From this point on - operate in a regular manner */
  sSpiInformation.ulSpiState = eSPI_STATE_IDLE;

  CC3000_DEASSERT_CS;
  delay(1);
  DEBUGPRINT_F(digitalRead(g_irqPin));
  
  SpiResumeSpi();
  
  return(0);
}
예제 #12
0
void WriteWlanPin( unsigned char val )
{  
  if (DEBUG_MODE)
  {
    DEBUGPRINT_F("\tCC3000: WriteWlanPin - ");
    DEBUGPRINT_DEC(val);
    DEBUGPRINT_F("\n\r");
    delay(1);
  }
  if (val)
  {
    digitalWrite(g_vbatPin, HIGH);
  }
  else
  {
    digitalWrite(g_vbatPin, LOW);
  }
}
예제 #13
0
void WlanInterruptDisable()
{
  DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r");
  ccspi_int_enabled = 0;
  detachInterrupt(g_IRQnum);
  
  //finish any pending reads from any previous interrupts
  spiFinishRead();
}
예제 #14
0
long SpiReadDataCont(void)
{
  long data_to_recv;
  unsigned char *evnt_buff, type;

  DEBUGPRINT_F("\tCC3000: SpiReadDataCont\n\r");

  /* Determine what type of packet we have */
  evnt_buff =  sSpiInformation.pRxPacket;
  data_to_recv = 0;
  STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);

  switch(type)
  {
    case HCI_TYPE_DATA:
      {
        /* We need to read the rest of data.. */
        STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
        if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1))
        {
          data_to_recv++;
        }

        if (data_to_recv)
        {
          SpiReadDataSynchronous(evnt_buff + HEADERS_SIZE_EVNT, data_to_recv);
        }
        break;
      }
    case HCI_TYPE_EVNT:
      {
        /* Calculate the rest length of the data */
        STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
        data_to_recv -= 1;

        /* Add padding byte if needed */
        if ((HEADERS_SIZE_EVNT + data_to_recv) & 1)
        {
          data_to_recv++;
        }

        if (data_to_recv)
        {
          SpiReadDataSynchronous(evnt_buff + HEADERS_SIZE_EVNT, data_to_recv);
        }

        sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
        break;
      }
  }

  return (0);
}
예제 #15
0
void SpiClose(void)
{
  DEBUGPRINT_F("\tCC3000: SpiClose");
  
  if (sSpiInformation.pRxPacket)
  {
    sSpiInformation.pRxPacket = 0;
  }

  /*  Disable Interrupt in GPIOA module... */
  tSLInformation.WlanInterruptDisable();
}
예제 #16
0
void SSIContReadOperation(void)
{
  DEBUGPRINT_F("\tCC3000: SpiContReadOperation\n\r");
  
  /* The header was read - continue with  the payload read */
  if (!SpiReadDataCont())
  {
    /* All the data was read - finalize handling by switching to teh task
     *  and calling from task Event Handler */
    //DEBUGPRINT_F("SPItrig\n\r");
    SpiTriggerRxProcessing();
  }
}
예제 #17
0
void SpiTriggerRxProcessing(void)
{
  DEBUGPRINT_F("\tCC3000: SpiTriggerRxProcessing\n\r");

  /* Trigger Rx processing */
  SpiPauseSpi();
  CC3000_DEASSERT_CS;

  //DEBUGPRINT_F("Magic?\n\r");
  /* The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
   * for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
   * occurred - and we will stuck here forever! */
  if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
  {
    /* You've got problems if you're here! */
    DEBUGPRINT_F("\tCC3000: ERROR - magic number missing!\n\r");
    while (1);
  }

  //DEBUGPRINT_F("OK!\n\r");
  sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
  sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
}
예제 #18
0
void SpiOpen(gcSpiHandleRx pfRxHandler)
{
  DEBUGPRINT_F("\tCC3000: SpiOpen");
  
  sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;

  memset(spi_buffer, 0, sizeof(spi_buffer));
  memset(wlan_tx_buffer, 0, sizeof(spi_buffer));

  sSpiInformation.SPIRxHandler      = pfRxHandler;
  sSpiInformation.usTxPacketLength  = 0;
  sSpiInformation.pTxPacket         = NULL;
  sSpiInformation.pRxPacket         = (unsigned char *)spi_buffer;
  sSpiInformation.usRxPacketLength  = 0;
  
  spi_buffer[CC3000_RX_BUFFER_SIZE - 1]     = CC3000_BUFFER_MAGIC_NUMBER;
  wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;

  /* Enable interrupt on the GPIO pin of WLAN IRQ */
  tSLInformation.WlanInterruptEnable();

  DEBUGPRINT_F("\tCC3000: Finished SpiOpen\n\r");
}
예제 #19
0
void SPI_IRQ(void)
{
  ccspi_is_in_irq = 1;

  DEBUGPRINT_F("\tCC3000: Entering SPI_IRQ\n\r");
    
  if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
  {
    /* IRQ line was low ... perform a callback on the HCI Layer */
    sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
  }
  else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
  {
    //DEBUGPRINT_F("IDLE\n\r");
    sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;    
    /* IRQ line goes down - start reception */

    CC3000_ASSERT_CS;

    // Wait for TX/RX Compete which will come as DMA interrupt
    SpiReadHeader();
    sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
    //DEBUGPRINT_F("SSICont\n\r");
    SSIContReadOperation();
  }
  else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
  {
    SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
    sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
    CC3000_DEASSERT_CS;
  }

  DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");

  ccspi_is_in_irq = 0;
  return;
}
예제 #20
0
void SPI_IRQ(void)
{
  ccspi_is_in_irq = 1;
  DEBUGPRINT_F("\tCC3000: Entering SPI_IRQ\n\r");
    
  if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
  {
    /* IRQ line was low ... perform a callback on the HCI Layer */
    sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
  }
  else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
  {
     //Serial.println("STATE_IDLE");
    DEBUGPRINT_F("IDLE\n\r");
    sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;    

    DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");
    return;
  }
  else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
  {
    SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
    sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
    CC3000_DEASSERT_CS;
  }
   else if ( sSpiInformation.ulSpiState == eSPI_STATE_READ_IRQ || 
                sSpiInformation.ulSpiState == eSPI_STATE_READ_EOT   )  
   {
      DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");
      return;
   }
  DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");

  ccspi_is_in_irq = 0;
  return;
}
예제 #21
0
void spiFinishRead()
{
   //Serial.println("READ_IRQ_ENTERED");
   if( sSpiInformation.ulSpiState == eSPI_STATE_READ_IRQ )    
   {
      //Serial.println("READ_IRQ");
       /* IRQ line goes down - start reception */
       CC3000_ASSERT_CS;
       // Wait for TX/RX Compete which will come as DMA interrupt
       SpiReadHeader();
       sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
       DEBUGPRINT_F("SSICont\n\r");
       SSIContReadOperation();
       
       ccspi_is_in_irq = 0;
   }   
}
예제 #22
0
void SpiReadHeader(void)
{
  DEBUGPRINT_F("\tCC3000: SpiReadHeader\n\r");

  SpiReadDataSynchronous(sSpiInformation.pRxPacket, HEADERS_SIZE_EVNT);
}
예제 #23
0
//*****************************************************************************
//
//!  hci_unsol_event_handler
//!
//!  @param  event_hdr   event header
//!
//!  @return             1 if event supported and handled
//!                      0 if event is not supported
//!
//!  @brief              Handle unsolicited events
//
//*****************************************************************************
long
hci_unsol_event_handler(char *event_hdr)
{
	char * data = NULL;
	long event_type;
	unsigned long NumberOfReleasedPackets;
	unsigned long NumberOfSentPackets;

	STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);

	DEBUGPRINT_F("\tHCI_UNSOL_EVT: ");
	DEBUGPRINT_HEX16(event_type);

	if (event_type & HCI_EVNT_UNSOL_BASE)
	{
		switch(event_type)
		{

		case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
			{
				hci_event_unsol_flowcontrol_handler(event_hdr);

				NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
				NumberOfSentPackets = tSLInformation.NumberOfSentPackets;

				if (NumberOfReleasedPackets == NumberOfSentPackets)
				{
					if (tSLInformation.InformHostOnTxComplete)
					{
						tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
					}
				}
				return 1;

			}
		}
	}

	if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
	{
		switch(event_type)
		{
		case HCI_EVNT_WLAN_KEEPALIVE:
		case HCI_EVNT_WLAN_UNSOL_CONNECT:
		case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
		case HCI_EVNT_WLAN_UNSOL_INIT:
		case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:

			if( tSLInformation.sWlanCB )
			{
				tSLInformation.sWlanCB(event_type, 0, 0);
			}
			break;

		case HCI_EVNT_WLAN_UNSOL_DHCP:
			{
				unsigned char	params[NETAPP_IPCONFIG_MAC_OFFSET + 1];	// extra byte is for the status
				unsigned char *recParams = params;

				data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;

				//Read IP address
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read subnet
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read default GW
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read DHCP server
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read DNS server
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				// read the status
				STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);


				if( tSLInformation.sWlanCB )
				{
					tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
				}
			}
			break;

		case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
			{
				netapp_pingreport_args_t params;
				data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
				STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
				STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
				STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);

				if( tSLInformation.sWlanCB )
				{
					tSLInformation.sWlanCB(event_type, (char *)&params, sizeof(params));
				}
			}
			break;
		case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
			{
			  DEBUGPRINT_F("\tTCP Close Wait\n\r");
			  uint8_t socketnum;
			  data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
			  /*
			  printHex(data[0]); PRINT_F("\t");
			  printHex(data[1]); PRINT_F("\t");
			  printHex(data[2]); PRINT_F("\t");
			  printHex(data[3]); PRINT_F("\t");
			  printHex(data[4]); PRINT_F("\t");
			  printHex(data[5]); PRINT_F("\t");
			  */
			  socketnum = data[0];
			  //STREAM_TO_UINT16(data, 0, socketnum);
			  if( tSLInformation.sWlanCB )
			    {
			      tSLInformation.sWlanCB(event_type, (char *)&socketnum, 1);
			    }
			}
			break;

		//'default' case which means "event not supported"
		default:
			return (0);
		}
		return(1);
	}

	if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
			|| (event_type == HCI_EVNT_WRITE))
	{
                char *pArg;
                long status;

		DEBUGPRINT_F("\tSEND event response\n\r");

                pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
                STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);

                if (ERROR_SOCKET_INACTIVE == status)
                {
                    // The only synchronous event that can come from SL device in form of
                    // command complete is "Command Complete" on data sent, in case SL device
                    // was unable to transmit
                    STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
                    update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));

                    return (1);
                }
                else
                    return (0);
	}

	return(0);
}
//*****************************************************************************
//
//!  hci_unsol_event_handler
//!
//!  @param  event_hdr   event header
//!
//!  @return             1 if event supported and handled
//!                      0 if event is not supported
//!
//!  @brief              Handle unsolicited events
//
//*****************************************************************************
INT32 hci_unsol_event_handler(CHAR *event_hdr)
{
	CHAR * data = NULL;
	INT32 event_type;
	UINT32 NumberOfReleasedPackets;
	UINT32 NumberOfSentPackets;

	STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);

	DEBUGPRINT_F("\tHCI_UNSOL_EVT: ");
	DEBUGPRINT_HEX16(event_type);

	if (event_type & HCI_EVNT_UNSOL_BASE)
	{
		switch(event_type)
		{

		case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
			{
				hci_event_unsol_flowcontrol_handler(event_hdr);

				NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
				NumberOfSentPackets = tSLInformation.NumberOfSentPackets;

				if (NumberOfReleasedPackets == NumberOfSentPackets)
				{
					if (tSLInformation.InformHostOnTxComplete)
					{
						tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
					}
				}
				return 1;

			}
		}
	}

	if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
	{
		switch(event_type)
		{
		case HCI_EVNT_WLAN_KEEPALIVE:
		case HCI_EVNT_WLAN_UNSOL_CONNECT:
		case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
		case HCI_EVNT_WLAN_UNSOL_INIT:
		case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:

			if( tSLInformation.sWlanCB )
			{
				tSLInformation.sWlanCB(event_type, 0, 0);
			}
			break;

		case HCI_EVNT_WLAN_UNSOL_DHCP:
			{
				UINT8	params[NETAPP_IPCONFIG_MAC_OFFSET + 1];	// extra byte is for the status
				UINT8 *recParams = params;

				data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE;

				//Read IP address
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read subnet
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read default GW
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read DHCP server
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				data += 4;
				//Read DNS server
				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
				// read the status
				STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);


				if( tSLInformation.sWlanCB )
				{
					tSLInformation.sWlanCB(event_type, (CHAR *)params, sizeof(params));
				}
			}
			break;

		case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
			{
				netapp_pingreport_args_t params;
				data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
				STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
				STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
				STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);

				if( tSLInformation.sWlanCB )
				{
					tSLInformation.sWlanCB(event_type, (CHAR *)&params, sizeof(params));
				}
			}
			break;
		case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
			{
			  DEBUGPRINT_F("\tTCP Close Wait\n\r");
			  data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
			  /*
			  printHex(data[0]); PRINT_F("\t");
			  printHex(data[1]); PRINT_F("\t");
			  printHex(data[2]); PRINT_F("\t");
			  printHex(data[3]); PRINT_F("\t");
			  printHex(data[4]); PRINT_F("\t");
			  printHex(data[5]); PRINT_F("\t");
			  */
			  if( tSLInformation.sWlanCB )
			    {
				  //data[0] represents the socket id, for which FIN was received by remote.
				  //Upon receiving this event, the user can close the socket, or else the 
				  //socket will be closded after inacvitity timeout (by default 60 seconds)
			      tSLInformation.sWlanCB(event_type, data, 1);
			    }
			}
			break;

		//'default' case which means "event not supported"
		default:
			return (0);
		}
		return(1);
	}

	if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
			|| (event_type == HCI_EVNT_WRITE))
	{
                CHAR *pArg;
                INT32 status;

		DEBUGPRINT_F("\tSEND event response\n\r");

                pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
                STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);

                if (ERROR_SOCKET_INACTIVE == status)
                {
                    // The only synchronous event that can come from SL device in form of
                    // command complete is "Command Complete" on data sent, in case SL device
                    // was unable to transmit
                    STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
                    update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));

                    return (1);
                }
                else
                    return (0);
	}

	//handle a case where unsolicited event arrived, but was not handled by any of the cases above
	if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ))
	{
		return(1);
	}

	return(0);
}
예제 #25
0
void WlanInterruptDisable()
{
  DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r");
  ccspi_int_enabled = 0;
  detachInterrupt(g_IRQnum);
}
예제 #26
0
void printIRQ()
{
	DEBUGPRINT_F(digitalRead(g_irqPin));
}
예제 #27
0
long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
{
  unsigned char ucPad = 0;

  DEBUGPRINT_F("\tCC3000: SpiWrite\n\r");
  
  /* Figure out the total length of the packet in order to figure out if there is padding or not */
  if(!(usLength & 0x0001))
  {
    ucPad++;
  }

  pUserBuffer[0] = WRITE;
  pUserBuffer[1] = HI(usLength + ucPad);
  pUserBuffer[2] = LO(usLength + ucPad);
  pUserBuffer[3] = 0;
  pUserBuffer[4] = 0;

  usLength += (SPI_HEADER_SIZE + ucPad);

  /* The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
   * for the purpose of overrun detection. If the magic number is overwritten - buffer overrun
   * occurred - and we will be stuck here forever! */
  if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
  {
    DEBUGPRINT_F("\tCC3000: Error - No magic number found in SpiWrite\n\r");
    while (1);
  }

  if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
  {
    while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED);
  }

  if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED)
  {
    /* This is time for first TX/RX transactions over SPI: the IRQ is down - so need to send read buffer size command */
    SpiFirstWrite(pUserBuffer, usLength);
  }
  else
  {
    /* We need to prevent here race that can occur in case two back to back packets are sent to the
     * device, so the state will move to IDLE and once again to not IDLE due to IRQ */
    tSLInformation.WlanInterruptDisable();

    while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE);

    sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ;
    sSpiInformation.pTxPacket = pUserBuffer;
    sSpiInformation.usTxPacketLength = usLength;

    /* Assert the CS line and wait till SSI IRQ line is active and then initialize write operation */
    CC3000_ASSERT_CS;

    /* Re-enable IRQ - if it was not disabled - this is not a problem... */
    tSLInformation.WlanInterruptEnable();

    /* Check for a missing interrupt between the CS assertion and enabling back the interrupts */
    if (tSLInformation.ReadWlanInterruptPin() == 0)
    {
      SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);

      sSpiInformation.ulSpiState = eSPI_STATE_IDLE;

      CC3000_DEASSERT_CS;
    }
  }

  /* Due to the fact that we are currently implementing a blocking situation
   * here we will wait till end of transaction */
  while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState);

  return(0);
}