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); }
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(); } }
//***************************************************************************** // //! 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); }
//***************************************************************************** // //! This function enter point for write flow //! //! \param buffer //! //! \return none //! //! \brief ... // //***************************************************************************** long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) { // // workaround for first transaction // ASSERT_CS(); delayMicroseconds(50); // SPI writes first 4 bytes of data SpiWriteDataSynchronous(ucBuf, 4); delayMicroseconds(50); SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); sSpiInformation.ulSpiState = eSPI_STATE_IDLE; DEASSERT_CS(); return(0); }
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); }
static inline eCC3000States SetState(eCC3000States ns, eCSActions cs) { intState save = DISABLE_INT(); eCC3000States os = sSpiInformation.ulSpiState; sSpiInformation.ulSpiState = ns; switch (cs) { case eAssert: ASSERT_CS(); break; case eDeAssert: DEASSERT_CS(); break; } ENABLE_INT(save); return os; }
int spi_Read(Fd_t fd, unsigned char *pBuff, int len) { int i = 0; unsigned long ulBuff; ASSERT_CS(); for(i=0; i< len; i++) { while(SSIDataPutNonBlocking(SPI_BASE, 0xFF) != TRUE); while(SSIDataGetNonBlocking(SPI_BASE, &ulBuff) != TRUE); pBuff[i] = (unsigned char)ulBuff; } DEASSERT_CS(); return len; }
void cc3000_irq_handler_x(void) { if (tSLInformation.usEventOrDataReceived) return; // there's already an interrupt that we haven't handled cc3000_in_interrupt = true; 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(); SpiReadHeader(); sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; // The header was read - continue with the payload read SpiReadDataCont(); // All the data was read - finalize handling by switching to the task // and calling from task Event Handler // Trigger Rx processing SpiPauseSpi(); DEASSERT_CS(); // 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 (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { while (1) ; } sSpiInformation.ulSpiState = eSPI_STATE_IDLE; sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); } cc3000_in_interrupt = false;
int spi_Read(Fd_t fd, unsigned char *pBuff, int len) { int i = 0; ASSERT_CS(); for (i = 0; i < len; i ++) { while (!(UCB0IFG&UCTXIFG)); UCB0TXBUF = 0xFF; while (!(UCB0IFG&UCRXIFG)); pBuff[i] = UCB0RXBUF; } DEASSERT_CS(); return len; }
int spi_Write(Fd_t fd, unsigned char *pBuff, int len) { int len_to_return = len; unsigned long ulDummy; ASSERT_CS(); while(len) { while(SSIDataPutNonBlocking(SPI_BASE, (unsigned long)*pBuff) != TRUE); while(SSIDataGetNonBlocking(SPI_BASE, &ulDummy) != TRUE); pBuff++; len--; } DEASSERT_CS(); return len_to_return; }
int spi_Write(Fd_t fd, unsigned char *pBuff, int len) { int len_to_return = len; ASSERT_CS(); while (len) { while (!(UCB0IFG&UCTXIFG)); UCB0TXBUF = *pBuff; while (!(UCB0IFG&UCRXIFG)); UCB0RXBUF; len --; pBuff++; } DEASSERT_CS(); return len_to_return; }
//***************************************************************************** // //! 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 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; } }
//***************************************************************************** // //! 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); }