//*****************************************************************************
//
//! 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);
}
//*****************************************************************************
//
//!  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;
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//!  \param  SpiTriggerRxProcessing
//!
//!  \return none
//!
//!  \brief  The function triggers a user provided callback for
//
//*****************************************************************************
void SpiTriggerRxProcessing(void)
{
  //
  // Trigger Rx processing
  //
  SpiPauseSpi();
  DeassertWlanCS();

  // 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)
    {
      while (1)
        ;
    }

  sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
  sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
}
示例#4
0
void Wlan_Setup(void)
{
  int ret;
  uint32_t regval;

  printf("\nExecuting kl_irq_initialize!\n");

  /* Configure the PIN used to enable the chip */

  kl_configgpio(GPIO_WIFI_EN);

  /* Configure PIN to detect interrupts */

  kl_configgpio(GPIO_WIFI_IRQ);

  /* Configure PIN used as SPI CS */

  kl_configgpio(GPIO_WIFI_CS);

  /* Make sure the chip is OFF before we start */

  WriteWlanEnablePin(false);

  /* Make sure the SPI CS pin is deasserted */

  DeassertWlanCS();

  /* Configure pin to detect interrupt on falling edge */

  regval = getreg32(KL_PORTA_PCR16);
  regval |= PORT_PCR_IRQC_FALLING;
  putreg32(regval, KL_PORTA_PCR16);

  ret = irq_attach(KL_IRQ_PORTA, CC3000InterruptHandler);
  if (ret == OK)
    {
      up_enable_irq(KL_IRQ_PORTA);
    }
}
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength)
{
  uint8_t 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 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)
    {
      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
      //

      AssertWlanCS();

      //
      // 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;

          DeassertWlanCS();
        }
    }


  //
  // 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);
}