Пример #1
0
OSStatus spi_transfer( spi_driver_t* spi_driver, const uint8_t* data_out, uint8_t* data_in, uint32_t size )
{
    uint32_t loop_count = MAX_LOOP_COUNT;

    clear_spi_fifos( spi_driver->spi_peripheral );

	if(spi_driver->use_dma)
	{
		return spi_dma_transfer(data_out,data_in,size);
	}



    while ( size > 0 )
    {
        /* Push frame to TX FIFO */
        //SPI_PUSHR_REG( spi_driver->spi_peripheral ) = (uint32_t) ( *data_out++ | SPI_PUSHR_PCS( 1 << spi_driver->chip_select ) | ( ( size != 1 ) ? SPI_PUSHR_CONT_MASK : 0 ) );
        SPI_PUSHR_REG( spi_driver->spi_peripheral ) = (uint32_t) ( *data_out++);

        /* Wait until RX FIFO is not empty */
        while ( ( SPI_SR_RXCTR_MASK & SPI_SR_REG( spi_driver->spi_peripheral ) ) == 0 && loop_count > 0 )
        {
            loop_count--;
        }

        if ( loop_count == 0 )
        {
            return kTimeoutErr;
        }

        /* Pop frame from RX FIFO */
        *data_in++ = (uint8_t)SPI_POPR_REG( spi_driver->spi_peripheral );

        size--;
    }

    return kNoErr;
}
Пример #2
0
OSStatus MicoSpiTransfer( const mico_spi_device_t* spi, mico_spi_message_segment_t* segments, uint16_t number_of_segments )
{
  OSStatus       result = kNoErr;
  uint16_t       i;
  uint32_t       count = 0;
  
  check_string( (spi != NULL) && (segments != NULL) && (number_of_segments != 0), "Bad args");
  
  MicoMcuPowerSaveConfig(false);
  
  /* If the given SPI device is not the current SPI device, initialise */
  if ( spi != current_spi_device )
  {
    MicoSpiInitialize( spi );
  }
  
  /* Activate chip select */
  MicoGpioOutputLow(spi->chip_select);
  
  for ( i = 0; i < number_of_segments; i++ )
  {
    /* Check if we are using DMA */
    if ( spi->mode & SPI_USE_DMA )
    {
      spi_dma_config( spi, &segments[i] );
      result = spi_dma_transfer( spi );
      if ( result != kNoErr )
      {
        goto cleanup_transfer;
      }
    }
    else
    {
      /* in interrupt-less mode */
      if ( spi->bits == 8 )
      {
        const uint8_t* send_ptr = ( const uint8_t* )segments[i].tx_buffer;
        uint8_t*       rcv_ptr  = ( uint8_t* )segments[i].rx_buffer;
        count = segments[i].length;
        while ( count-- )
        {
          uint16_t data;
          if ( send_ptr != NULL )
          {
            data = *send_ptr;
            send_ptr++;
          }
          else
          {
            data = 0xFF;
          }
          
          /* Wait until the transmit buffer is empty */
          while ( SPI_I2S_GetFlagStatus( spi_mapping[spi->port].spi_regs, SPI_I2S_FLAG_TXE ) == RESET )
          {}
          
          /* Send the byte */
          SPI_I2S_SendData( spi_mapping[spi->port].spi_regs, data );
          
          /* Wait until a data is received */
          while ( SPI_I2S_GetFlagStatus( spi_mapping[spi->port].spi_regs, SPI_I2S_FLAG_RXNE ) == RESET )
          {}
          
          /* Get the received data */
          data = SPI_I2S_ReceiveData( spi_mapping[spi->port].spi_regs );
          
          if ( rcv_ptr != NULL )
          {
            *rcv_ptr++ = (uint8_t)data;
          }
        }
      }
      else if ( spi->bits == 16 )
      {
        const uint16_t* send_ptr = (const uint16_t *) segments[i].tx_buffer;
        uint16_t*       rcv_ptr  = (uint16_t *) segments[i].rx_buffer;
        
        /* Check that the message length is a multiple of 2 */
        if ( ( count % 2 ) == 0 )
        {
          result = kGeneralErr;
          goto cleanup_transfer;
        }
        
        while ( count != 0)
        {
          uint16_t data = 0xFFFF;
          count -= 2;
          
          if ( send_ptr != NULL )
          {
            data = *send_ptr++;
          }
          
          /* Wait until the transmit buffer is empty */
          while ( SPI_I2S_GetFlagStatus( spi_mapping[spi->port].spi_regs, SPI_I2S_FLAG_TXE ) == RESET )
          {}
          
          /* Send the byte */
          SPI_I2S_SendData( spi_mapping[spi->port].spi_regs, data );
          
          /* Wait until a data is received */
          while ( SPI_I2S_GetFlagStatus( spi_mapping[spi->port].spi_regs, SPI_I2S_FLAG_RXNE ) == RESET )
          {}
          
          /* Get the received data */
          data = SPI_I2S_ReceiveData( spi_mapping[spi->port].spi_regs );
          
          if ( rcv_ptr != NULL )
          {
            *rcv_ptr++ = data;
          }
        }
      }
    }
  }
cleanup_transfer:
  MicoGpioOutputHigh(spi->chip_select);
  
  MicoMcuPowerSaveConfig(true);
  
  return result;
}
Пример #3
0
platform_result_t platform_spi_transfer( const platform_spi_t* spi, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
{
    platform_result_t result = PLATFORM_SUCCESS;
    uint32_t          count  = 0;
    uint16_t          i;

    wiced_assert( "bad argument", ( spi != NULL ) && ( config != NULL ) && ( segments != NULL ) && ( number_of_segments != 0 ) );

    platform_mcu_powersave_disable();

    /* Activate chip select */
    platform_gpio_output_low( config->chip_select );

    for ( i = 0; i < number_of_segments; i++ )
    {
        /* Check if we are using DMA */
        if ( config->mode & SPI_USE_DMA )
        {
            spi_dma_config( spi, &segments[ i ] );

            result = spi_dma_transfer( spi, config );
            if ( result != PLATFORM_SUCCESS )
            {
                goto cleanup_transfer;
            }
        }
        else
        {
            count = segments[i].length;

            /* in interrupt-less mode */
            if ( config->bits == 8 )
            {
                const uint8_t* send_ptr = ( const uint8_t* )segments[i].tx_buffer;
                uint8_t*       rcv_ptr  = ( uint8_t* )segments[i].rx_buffer;

                while ( count-- )
                {
                    uint16_t data = 0xFF;

                    if ( send_ptr != NULL )
                    {
                        data = *send_ptr++;
                    }

                    data = spi_transfer( spi, data );

                    if ( rcv_ptr != NULL )
                    {
                        *rcv_ptr++ = (uint8_t)data;
                    }
                }
            }
            else if ( config->bits == 16 )
            {
                const uint16_t* send_ptr = (const uint16_t *) segments[i].tx_buffer;
                uint16_t*       rcv_ptr  = (uint16_t *) segments[i].rx_buffer;

                /* Check that the message length is a multiple of 2 */
                if ( ( count % 2 ) != 0 )
                {
                    result = WICED_ERROR;
                    goto cleanup_transfer;
                }

                /* Transmit/receive data stream, 16-bit at time */
                while ( count != 0 )
                {
                    uint16_t data = 0xFFFF;

                    if ( send_ptr != NULL )
                    {
                        data = *send_ptr++;
                    }

                    data = spi_transfer( spi, data );

                    if ( rcv_ptr != NULL )
                    {
                        *rcv_ptr++ = data;
                    }

                    count -= 2;
                }
            }
        }
    }

cleanup_transfer:
    /* Deassert chip select */
    platform_gpio_output_high( config->chip_select );

    platform_mcu_powersave_enable( );

    return result;
}
Пример #4
0
OSStatus platform_spi_transfer( platform_spi_driver_t* driver, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
{
  OSStatus err    = kNoErr;
  uint32_t count  = 0;
  uint16_t i;
  
  platform_mcu_powersave_disable();
  
  require_action_quiet( ( driver != NULL ) && ( config != NULL ) && ( segments != NULL ) && ( number_of_segments != 0 ), exit, err = kParamErr);
  
  /* Activate chip select */
  platform_gpio_output_low( config->chip_select );
  
  for ( i = 0; i < number_of_segments; i++ )
  {
    /* Check if we are using DMA */
    if ( config->mode & SPI_USE_DMA )
    {
      if( segments[ i ].length != 0){
        //platform_log( "length: %d, i:%d", segments[ i ].length, i );
        
        spi_dma_config( driver->peripheral, &segments[ i ] );
      
        err = spi_dma_transfer( driver->peripheral, config );
        require_noerr(err, cleanup_transfer);
      }
    }
    else
    {
      count = segments[i].length;
      
      /* in interrupt-less mode */
      if ( config->bits == 8 )
      {
        const uint8_t* send_ptr = ( const uint8_t* )segments[i].tx_buffer;
        uint8_t*       rcv_ptr  = ( uint8_t* )segments[i].rx_buffer;
        
        while ( count-- )
        {
          uint16_t data = 0xFF;
          
          if ( send_ptr != NULL )
          {
            data = *send_ptr++;
          }
          
          data = spi_transfer( driver->peripheral, data );
          
          if ( rcv_ptr != NULL )
          {
            *rcv_ptr++ = (uint8_t)data;
          }
        }
      }
      else if ( config->bits == 16 )
      {
        const uint16_t* send_ptr = (const uint16_t *) segments[i].tx_buffer;
        uint16_t*       rcv_ptr  = (uint16_t *) segments[i].rx_buffer;
        
        /* Check that the message length is a multiple of 2 */
        
        require_action_quiet( ( count % 2 ) == 0, cleanup_transfer, err = kSizeErr);
        
        /* Transmit/receive data stream, 16-bit at time */
        while ( count != 0 )
        {
          uint16_t data = 0xFFFF;
          
          if ( send_ptr != NULL )
          {
            data = *send_ptr++;
          }
          
          data = spi_transfer( driver->peripheral, data );
          
          if ( rcv_ptr != NULL )
          {
            *rcv_ptr++ = data;
          }
          
          count -= 2;
        }
      }
    }
  }
  
cleanup_transfer:
  /* Deassert chip select */
  platform_gpio_output_high( config->chip_select );
  
exit:
  platform_mcu_powersave_enable( );
  return err;
}