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"); }
long ReadWlanInterruptPin(void) { DEBUGPRINT_F("\tCC3000: ReadWlanInterruptPin - "); DEBUGPRINT_DEC(digitalRead(g_irqPin)); DEBUGPRINT_F("\n\r"); return(digitalRead(g_irqPin)); }
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); }
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"); }
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); }
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); }
void SpiPauseSpi(void) { DEBUGPRINT_F("\tCC3000: SpiPauseSpi\n\r"); ccspi_int_enabled = 0; detachInterrupt(g_IRQnum); }
void SpiResumeSpi(void) { DEBUGPRINT_F("\tCC3000: SpiResumeSpi\n\r"); ccspi_int_enabled = 1; attachInterrupt(g_IRQnum, SPI_IRQ, FALLING); }
void WlanInterruptEnable() { DEBUGPRINT_F("\tCC3000: WlanInterruptEnable.\n\r"); // delay(100); ccspi_int_enabled = 1; attachInterrupt(g_IRQnum, SPI_IRQ, FALLING); }
//***************************************************************************** // //! 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); }
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); }
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); } }
void WlanInterruptDisable() { DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r"); ccspi_int_enabled = 0; detachInterrupt(g_IRQnum); //finish any pending reads from any previous interrupts spiFinishRead(); }
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); }
void SpiClose(void) { DEBUGPRINT_F("\tCC3000: SpiClose"); if (sSpiInformation.pRxPacket) { sSpiInformation.pRxPacket = 0; } /* Disable Interrupt in GPIOA module... */ tSLInformation.WlanInterruptDisable(); }
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(); } }
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); }
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"); }
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; }
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; }
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; } }
void SpiReadHeader(void) { DEBUGPRINT_F("\tCC3000: SpiReadHeader\n\r"); SpiReadDataSynchronous(sSpiInformation.pRxPacket, HEADERS_SIZE_EVNT); }
//***************************************************************************** // //! 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 *)¶ms, 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 *)¶ms, 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); }
void WlanInterruptDisable() { DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r"); ccspi_int_enabled = 0; detachInterrupt(g_IRQnum); }
void printIRQ() { DEBUGPRINT_F(digitalRead(g_irqPin)); }
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); }