//***************************************************************************** // //! This function enter point for write flow //! //! \param buffer //! //! \return none //! //! \brief ... // //***************************************************************************** long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { // // workaround for first transaction // Set_CC3000_CS_Active(); delayMicroseconds(50); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); delayMicroseconds(50); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; Set_CC3000_CS_NotActive(); return(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); }
//***************************************************************************** // //! This function enter point for write flow //! //! \param buffer //! //! \return none //! //! \brief ... // //***************************************************************************** long SpiFirstWrite(uint8_t *ucBuf, uint16_t usLength) { // // workaround for first transaction // AssertWlanCS(); usleep(70); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); usleep(70); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DeassertWlanCS(); //printf("Executed SpiFirstWrite!\n"); return(0); }
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { // workaround for first transaction ASSERT_CS(); // 50 microsecond delay jshDelayMicroseconds(50); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); jshDelayMicroseconds(50); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); // From this point on - operate in a regular way sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); jshDelayMicroseconds(10000); return(0); }
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { // // workaround for first transaction // TM_DEBUG("SpiFirstWrite\n\r"); // digitalWrite(HOST_nCS, LOW); csn(LOW); delayMicroseconds(80); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); delayMicroseconds(80); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); // SpiWriteDataSynchronous(testData, usLength - 4); // From this point on - operate in a regular way sSpiInformation.ulSpiState = eSPI_STATE_IDLE; // digitalWrite(HOST_nCS, HIGH); csn(HIGH); return(0); }
//***************************************************************************** // //! SpiFirstWrite //! //! @param ucBuf buffer to write //! @param usLength buffer's length //! //! @return none //! //! @brief enter point for first write flow // //***************************************************************************** long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { volatile int i; // workaround for first transaction ASSERT_CS(); // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles; for (i = 0; i < 4000; i++) ; // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); for (i = 0; i < 4000; i++) ; SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); // From this point on - operate in a regular way sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); return (0); }
void SpiIntGPIOHandler(void) { if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { //This means IRQ line was low call a callback of HCI Layer to inform //on event sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - we are start reception */ ASSERT_CS(); // Wait for TX/RX Compete which will come as DMA interrupt SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); } }
STATIC mp_obj_t irq_callback(mp_obj_t line) { DEBUG_printf("<< IRQ; state=%lu >>\n", sSpiInformation.ulSpiState); switch (sSpiInformation.ulSpiState) { case eSPI_STATE_POWERUP: /* This means IRQ line was low call a callback of HCI Layer to inform on event */ DEBUG_printf(" - POWERUP\n"); sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; break; case eSPI_STATE_IDLE: DEBUG_printf(" - IDLE\n"); sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - we are start reception */ CS_LOW(); // Wait for TX/RX Compete which will come as DMA interrupt SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); break; case eSPI_STATE_WRITE_IRQ: DEBUG_printf(" - WRITE IRQ\n"); SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; CS_HIGH(); break; } return mp_const_none; }
long cc3000_spi_write(unsigned char *pUserBuffer, unsigned short usLength) { cc3000_irq_disable(); unsigned char ucPad = 0; // 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 detection of the overrun. If the // magic number is overwritten - buffer overrun occurred - and we will stuck // here forever! if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { 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 { // Assert the CS line and wait till SSI IRQ line is active and then // initialize write operation ASSERT_CS(); while (cc3000_read_irq_pin()) ; // wait for the IRQ line to go low SpiWriteDataSynchronous(pUserBuffer, usLength); DEASSERT_CS(); } cc3000_irq_enable(); return(0); }
//***************************************************************************** // //! The IntSpiGPIOHandler interrupt handler //! //! \param none //! //! \return none //! //! \brief GPIO A interrupt handler. When the external SSI WLAN device is //! ready to interact with Host CPU it generates an interrupt signal. //! After that Host CPU has registrated this interrupt request //! it set the corresponding /CS in active state. // //***************************************************************************** //#pragma vector=PORT2_VECTOR //__interrupt void IntSpiGPIOHandler(void) int CC3000InterruptHandler(int irq, void *context) { uint32_t regval = 0; regval = getreg32(KL_PORTA_ISFR); if (regval & (1 << PIN4)) { if(spiEnabled) printf("Receive an Interrupt!\n"); if (!SPIInterruptsEnabled) { if(spiEnabled) printf("SPIInterrupt was disabled!\n"); goto out; } if(spiEnabled) printf("SPIInterrupt was enabled!\n"); if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { /* This means IRQ line was low call a callback of HCI Layer to inform on event */ sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - start reception */ AssertWlanCS(); // // Wait for TX/RX Complete which will come as DMA interrupt // SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DeassertWlanCS(); } else { } out: regval = (1 << PIN4); putreg32(regval, KL_PORTA_ISFR); } return 0; }
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { /* Workaround for the first transaction */ CC3000_ASSERT_CS; /* Delay (stay low) for ~50us */ dwtDelay((SystemCoreClock / 1000000) * 50); /* SPI writes first 4 bytes of data */ SpiWriteDataSynchronous(ucBuf, 4); dwtDelay((SystemCoreClock / 1000000) * 50); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); /* From this point on - operate in a regular manner */ sSpiInformation.ulSpiState = eSPI_STATE_IDLE; CC3000_DEASSERT_CS; return(0); }
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { DEBUG_printf("SpiFirstWrite %lu\n", sSpiInformation.ulSpiState); CS_LOW(); // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles; __delay_cycles(1200); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); __delay_cycles(1200); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); // From this point on - operate in a regular way sSpiInformation.ulSpiState = eSPI_STATE_IDLE; CS_HIGH(); return(0); }
void PIN_INT2_IRQHandler(void) #else #error "CC3000 spi.c: No MCU defined" #endif { /* Make sure the right flag is set in the int status register */ if ( LPC_GPIO_PIN_INT->IST & (0x1 << 2) ) { /* Falling Edge */ if ( ( LPC_GPIO_PIN_INT->FALL & (0x1 << 2) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1 << 2) ) ) { if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { /* This means IRQ line was low call a callback of HCI Layer to inform on event */ sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { 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; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; CC3000_DEASSERT_CS; } LPC_GPIO_PIN_INT->FALL = 0x1 << 2; } /* Clear the FLEX/PIN interrupt */ LPC_GPIO_PIN_INT->IST = 0x1 << 2; } return; }
//***************************************************************************** // //! The IntSpiGPIOHandler interrupt handler //! //! \param none //! //! \return none //! //! \brief GPIO A interrupt handler. When the external SSI WLAN device is //! ready to interact with Host CPU it generates an interrupt signal. //! After that Host CPU has registrated this interrupt request //! it set the corresponding /CS in active state. // //***************************************************************************** void CC3000InterruptHandler(void) { if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { /* This means IRQ line was low call a callback of HCI Layer to inform on event */ sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - start reception */ assert_cs(); SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; negate_cs(); } }
//***************************************************************************** // //! The IntSpiGPIOHandler interrupt handler //! //! \param none //! //! \return none //! //! \brief GPIO A interrupt handler. When the external SSI WLAN device is //! ready to interact with Host CPU it generates an interrupt signal. //! After that Host CPU has registrated this interrupt request //! it set the corresponding /CS in active state. // //***************************************************************************** //#pragma vector=PORT2_VECTOR //__interrupt void IntSpiGPIOHandler(void) void CC3000InterruptHandler(void) { if (!SPIInterruptsEnabled) { return; } if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { /* This means IRQ line was low call a callback of HCI Layer to inform on event */ sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - start reception */ Set_CC3000_CS_Active(); // // Wait for TX/RX Compete which will come as DMA interrupt // SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; Set_CC3000_CS_NotActive(); } else { } }
void SPI_IRQ(void) { if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { //This means IRQ line was low call a callback of HCI Layer to inform on event sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; //IRQ line goes down - we are start reception csn(LOW); // // Wait for TX/RX Compete which will come as DMA interrupt // SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; csn(HIGH); } return; }
void cc3k_int_poll(void) { if ((GPIO_ReadInputDataBit(IRQ_BASE, IRQ_PIN) == 0) &&(ccspi_is_in_irq == 0) && (ccspi_int_enabled != 0)) { ccspi_is_in_irq = 1; // ulCC3000IRQDelayFlags = 1; if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { //This means IRQ line was low call a callback of HCI Layer to inform //on event sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - we are start reception */ ASSERT_CS(); // Wait for TX/RX Compete which will come as DMA interrupt SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); } ccspi_is_in_irq = 0; } }
//***************************************************************************** // //! EXTI11_IRQHandler //! //! @param none //! //! @return none //! //! @brief Interrupt handler. When the external SSI WLAN device is //! ready to interact with Host CPU it generates an interrupt signal. //! After that Host CPU has registered this interrupt request //! it set the corresponding /CS in active state. // //***************************************************************************** void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(IRQ_INT_LINE) != RESET) { ccspi_is_in_irq = 1; if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { //This means IRQ line was low call a callback of HCI Layer to inform //on event sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; } else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) { sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; /* IRQ line goes down - we are start reception */ ASSERT_CS(); // Wait for TX/RX Compete which will come as DMA interrupt SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; SSIContReadOperation(); } else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) { SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); } ccspi_is_in_irq = 0; EXTI_ClearITPendingBit(IRQ_INT_LINE); } }
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; }
//***************************************************************************** // //! SpiWrite //! //! @param pUserBuffer buffer to write //! @param usLength buffer's length //! //! @return none //! //! @brief Spi write operation // //***************************************************************************** long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) { unsigned char ucPad = 0; // 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 detection of the overrun. If the // magic number is overwritten - buffer overrun occurred - and we will stuck // here forever! if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { 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 2 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 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; 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); }
long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) { unsigned char ucPad = 0; // // 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 detection of the overrun. If the magic number is overriten - buffer overrun // occurred - and we will stuck here forever! if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { while (1) ; } // Serial.println("Checking for state"); // print_spi_state(); 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 2 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 CS //digitalWrite(HOST_nCS, LOW); csn(LOW); // reenable IRQ tSLInformation.WlanInterruptEnable(); } // check for a missing interrupt between the CS assertion and enabling back the interrupts if (tSLInformation.ReadWlanInterruptPin() == 0) { // Serial.println("writing synchronous data"); SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; //deassert CS csn(HIGH); } // // 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) ; //Serial.println("done with spi write"); return(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; #ifdef SPI_HAS_TRANSACTION WlanInterruptEnable(); #endif } } /* 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); }