Exemplo n.º 1
0
void platform_wifi_spi_rx_dma_irq(void)
{
  uint8_t junk1;
  uint16_t junk2;
  pdc_packet_t pdc_spi_packet = { 0, 1 };
  Pdc* spi_pdc  = spi_get_pdc_base( wifi_spi.port );
  
  uint32_t status = spi_read_status( wifi_spi.port );
  uint32_t mask = spi_read_interrupt_mask( wifi_spi.port );
  
  if ( ( mask & SPI_IMR_RXBUFF ) && ( status & SPI_SR_RXBUFF ) )
  {
    pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
    pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
    pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
    spi_disable_interrupt( wifi_spi.port, SPI_IER_RXBUFF );
  }
  
  if ( ( mask & SPI_IMR_ENDTX ) && ( status & SPI_SR_ENDTX ) )
  {
    pdc_disable_transfer( spi_pdc, PERIPH_PTCR_TXTDIS );
    pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
    spi_disable_interrupt( wifi_spi.port, SPI_IER_ENDTX );
    /* Clear SPI RX data in a SPI send sequence */
    spi_read( wifi_spi.port, &junk2, &junk1);
  }
  
  mico_rtos_set_semaphore( &spi_transfer_finished_semaphore );
}
Exemplo n.º 2
0
platform_result_t platform_uart_deinit( platform_uart_driver_t* driver )
{

    usart_disable_interrupt( driver->peripheral->peripheral, 0xffffffff );

    NVIC_DisableIRQ( platform_uarts_irq_numbers[driver->peripheral->uart_id] );

    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );

    usart_disable_tx( driver->peripheral->peripheral );
    usart_disable_rx( driver->peripheral->peripheral );

    sysclk_disable_peripheral_clock( driver->peripheral->peripheral_id );

    platform_gpio_deinit( driver->peripheral->tx_pin );
    platform_gpio_deinit( driver->peripheral->rx_pin );

    if ( driver->peripheral->cts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->cts_pin );
    }

    if ( driver->peripheral->rts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->rts_pin );
    }

    host_rtos_deinit_semaphore( &driver->tx_dma_complete );
    host_rtos_deinit_semaphore( &driver->rx_dma_complete );

    driver->peripheral = NULL;
    memset( driver, 0, sizeof(platform_uart_driver_t) );

    return WICED_SUCCESS;
}
Exemplo n.º 3
0
/**
 * \brief Read internal fifo buffer.
 *
 * \param buf the buffer to store the data from the fifo buffer.
 * \param len the amount of data to read.
 */
void ksz8851_fifo_read(uint8_t *buf, uint32_t len)
{
    pdc_packet_t g_pdc_spi_tx_packet;
    pdc_packet_t g_pdc_spi_rx_packet;
    pdc_packet_t g_pdc_spi_tx_npacket;
    pdc_packet_t g_pdc_spi_rx_npacket;

    tmpbuf[0] = FIFO_READ;

    /* Prepare PDC transfer. */
    g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_tx_packet.ul_size = 9;
    g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_rx_packet.ul_size = 9;
    g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
    g_pdc_spi_tx_npacket.ul_size = len;
    g_pdc_spi_rx_npacket.ul_addr = (uint32_t) buf;
    g_pdc_spi_rx_npacket.ul_size = len;
    pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
    pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
    pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);
    pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

    spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_RXBUFF);
}
Exemplo n.º 4
0
/**
 * \brief Read internal fifo buffer.
 *
 * \param buf the buffer to store the data from the fifo buffer.
 * \param len the amount of data to read.
 */
void ksz8851_fifo_read(uint8_t *buf, uint32_t len)
{
	pdc_packet_t g_pdc_spi_tx_packet;
	pdc_packet_t g_pdc_spi_rx_packet;
	pdc_packet_t g_pdc_spi_tx_npacket;
	pdc_packet_t g_pdc_spi_rx_npacket;

	memset( cmdBuf.uc, '\0', sizeof cmdBuf );
	cmdBuf.uc[0] = FIFO_READ;
	spi_clear_ovres();

	/* Prepare PDC transfer. */
	g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
	g_pdc_spi_tx_packet.ul_size = 9;
	g_pdc_spi_rx_packet.ul_addr = (uint32_t) respBuf.uc;
	g_pdc_spi_rx_packet.ul_size = 9;

	g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
	g_pdc_spi_tx_npacket.ul_size = len;
	g_pdc_spi_rx_npacket.ul_addr = (uint32_t) buf;
	g_pdc_spi_rx_npacket.ul_size = len;
	pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
	pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
	pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);

spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_RXBUFF | SPI_IER_OVRES);

	pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
}
Exemplo n.º 5
0
/**
 * \brief Write internal fifo buffer.
 *
 * \param buf the buffer to send to the fifo buffer.
 * \param tot_len the total amount of data to write.
 * \param len the size of the first pbuf to write from the pbuf chain.
 */
void ksz8851_fifo_write(uint8_t *buf, uint32_t tot_len, uint32_t len)
{
    static uint8_t frameID = 0;
    pdc_packet_t g_pdc_spi_tx_packet;
    pdc_packet_t g_pdc_spi_rx_packet;
    pdc_packet_t g_pdc_spi_tx_npacket;
    pdc_packet_t g_pdc_spi_rx_npacket;

    /* Prepare control word and byte count. */
    tmpbuf[0] = FIFO_WRITE;
    tmpbuf[1] = frameID++ & 0x3f;
    tmpbuf[2] = 0;
    tmpbuf[3] = tot_len & 0xff;
    tmpbuf[4] = tot_len >> 8;

    /* Prepare PDC transfer. */
    g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_tx_packet.ul_size = 5;
    g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_rx_packet.ul_size = 5;
    g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
    g_pdc_spi_tx_npacket.ul_size = len;
    g_pdc_spi_rx_npacket.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_rx_npacket.ul_size = len;
    pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
    pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
    pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);
    pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

    spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_ENDRX);
}
Exemplo n.º 6
0
OSStatus host_platform_bus_deinit( void )
{
  platform_mcu_powersave_disable( );
  
  NVIC_DisableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
  pdc_disable_transfer( spi_get_pdc_base( wifi_spi.port ), PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );
  spi_disable(wifi_spi.port);
  
  /* Deinit the SPI lines */
  platform_gpio_peripheral_pin_init(  wifi_spi.mosi_pin,  INPUT_HIGH_IMPEDANCE );
  platform_gpio_peripheral_pin_init(  wifi_spi.miso_pin,  INPUT_HIGH_IMPEDANCE );
  platform_gpio_peripheral_pin_init(  wifi_spi.clock_pin, INPUT_HIGH_IMPEDANCE );
  
  /* Deinit the interrupt input for WLAN_IRQ */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
  platform_gpio_irq_disable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ] );
  
  /* Deinit SPI slave select GPIOs */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], INPUT_HIGH_IMPEDANCE );
  
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], INPUT_HIGH_IMPEDANCE );
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], INPUT_HIGH_IMPEDANCE );
#endif
  
  platform_mcu_powersave_enable( );
  
  return kNoErr;
}
Exemplo n.º 7
0
platform_result_t sam4s_spi_transfer_internal( const platform_spi_t* spi, const uint8_t* data_out, uint8_t* data_in, uint32_t data_length )
{
    Pdc*         spi_pdc  = spi_get_pdc_base( spi->peripheral );
    pdc_packet_t pdc_spi_packet;

    pdc_spi_packet.ul_addr = (uint32_t)data_in;
    pdc_spi_packet.ul_size = (uint32_t)data_length;
    pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );

    pdc_spi_packet.ul_addr = (uint32_t)data_out;
    pdc_spi_packet.ul_size = (uint32_t)data_length;
    pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );

    /* Enable the RX and TX PDC transfer requests */
    pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN );

    /* Waiting transfer done*/
    while ( ( spi_read_status( spi->peripheral ) & SPI_SR_RXBUFF ) == 0 )
    {
    }

    /* Disable the RX and TX PDC transfer requests */
    pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);

    return PLATFORM_SUCCESS;
}
Exemplo n.º 8
0
/** Initialize the SPI peripheral
 *
 * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
 * @param[out] obj  The SPI object to initialize
 * @param[in]  mosi The pin to use for MOSI
 * @param[in]  miso The pin to use for MISO
 * @param[in]  sclk The pin to use for SCLK
 */
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk)
{
	MBED_ASSERT(obj);
	MBED_ASSERT(mosi !=NC && miso!=NC && sclk !=NC );
	
	 if (g_sys_init == 0) {
        sysclk_init();
        system_board_init();
        g_sys_init = 1;
    }
	
	Spi *sercombase = pinmap_find_sercom(mosi,miso,sclk);
	MBED_ASSERT(sercombase!=NC);
	
	pinmap_find_spi_info(sercombase, obj);
	MBED_ASSERT(obj->spi.flexcom!=NC);
	MBED_ASSERT(obj->spi.pdc!=NC);
	
    /* Configure SPI pins */
    pin_function(mosi, pinmap_find_function(mosi, PinMap_SPI_MOSI));
    ioport_disable_pin(mosi);

    pin_function(miso, pinmap_find_function(miso, PinMap_SPI_MISO));
    ioport_disable_pin(miso);

    pin_function(sclk, pinmap_find_function(sclk, PinMap_SPI_SCLK));
    ioport_disable_pin(sclk);
	
	#if (SAMG55)
	/* Enable the peripheral and set SPI mode. */
	flexcom_enable(obj->spi.flexcom);
	flexcom_set_opmode(obj->spi.flexcom, FLEXCOM_SPI);
	#else
	/* Configure an SPI peripheral. */
	spi_enable_clock(sercombase);
	#endif
	spi_disable(sercombase);
	spi_reset(sercombase);
	spi_set_lastxfer(sercombase);
	spi_set_master_mode(sercombase);
	spi_disable_mode_fault_detect(sercombase);
	spi_set_peripheral_chip_select_value(sercombase, SPI_CHIP_SEL);
	spi_set_clock_polarity(sercombase, SPI_CHIP_SEL, SPI_CLK_POLARITY);
	spi_set_clock_phase(sercombase, SPI_CHIP_SEL, SPI_CLK_PHASE);
	spi_set_bits_per_transfer(sercombase, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
	spi_set_baudrate_div(sercombase, SPI_CHIP_SEL,(sysclk_get_cpu_hz() / gSPI_clock));
	spi_set_transfer_delay(sercombase, SPI_CHIP_SEL, SPI_DLYBS,SPI_DLYBCT);
	
	spi_enable(sercombase);

	pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS |	PERIPH_PTCR_TXTDIS);

	obj->spi.spi_base=sercombase;
	obj->spi.cs= SPI_CHIP_SEL;
	obj->spi.polarity=SPI_CLK_POLARITY;
	obj->spi.phase=SPI_CLK_PHASE;
	obj->spi.transferrate=SPI_CSR_BITS_8_BIT;
	obj->spi.is_slave=0;
}
Exemplo n.º 9
0
/**
 * \brief The AES interrupt call back function under PDC mode.
 */
static void aes_pdc_callback(void)
{
	state = true;
	pdc_disable_transfer(g_p_aes_pdc,
			PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
	pdc_tx_init(g_p_aes_pdc, &g_pdc_tx_packet, NULL);
	pdc_rx_init(g_p_aes_pdc, &g_pdc_rx_packet, NULL);
}
Exemplo n.º 10
0
void serial_tx_abort_asynch(serial_t *obj)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    Pdc *pdc_base;
    usart_disable_interrupt(_USART(obj), US_IER_TXBUFE);
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_disable_transfer(pdc_base, PERIPH_PTCR_TXTEN);
    pSERIAL_S(obj)->acttra = false;
}
Exemplo n.º 11
0
void platform_uart_irq( platform_uart_driver_t* driver )
{
    uint32_t status = usart_get_status( driver->peripheral->peripheral );
    uint32_t mask = usart_get_interrupt_mask( driver->peripheral->peripheral );
    Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->peripheral );

    /* ENDTX flag is set when Tx DMA transfer is done
     */
    if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) )
    {
        pdc_packet_t dma_packet;

        /* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively
         * starts another Tx DMA transaction. To work around this, disable Tx before
         * performing a dummy Tx init.
         */
        pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS );

        dma_packet.ul_addr = (uint32_t)0;
        dma_packet.ul_size = (uint32_t)1;

        pdc_tx_init( usart_get_pdc_base( USART1 ), &dma_packet, NULL );

        /* Notifies waiting thread that Tx DMA transfer is complete */
        host_rtos_set_semaphore( &driver->tx_dma_complete, WICED_TRUE );
    }

    /* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into
     * RPR and RCR, respectively, while the Tx tranfer continues. We now need to
     * prepare RNPR and RNCR for the next iteration.
     */
    if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) )
    {
        pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer;
        pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size;
    }

    /* RXRDY interrupt is triggered and flag is set when a new character has been
     * received but not yet read from the US_RHR. When this interrupt executes,
     * the DMA engine already read the character out from the US_RHR and RXRDY flag
     * is no longer asserted. The code below updates the ring buffer parameters
     * to keep them current
     */
    if ( mask & US_CSR_RXRDY )
    {
        driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR;

        // Notify thread if sufficient data are available
        if ( ( driver->rx_transfer_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_transfer_size ) )
        {
            host_rtos_set_semaphore( &driver->rx_dma_complete, WICED_TRUE );
            driver->rx_transfer_size = 0;
        }
    }
}
Exemplo n.º 12
0
/*
 * For internal use only.
 * If is_transmitting is false then configure the PDC to receive len bytes into
 * data.  If is_transmitting is true then configure the PDC to write len bytes
 * from data.
 * If notification_semaphore is not NULL, then the user is passing in their
 * own notification semaphore, and the semaphore is associated with the PDC
 * structure so it can be 'given' when the PDC transfer completes.  If
 * notification_semaphore is NULL then the driver will have its own internal
 * notification semaphore that it will use to only exit the send or receive
 * function when the PDC transfer has completed.
 */
void freertos_start_pdc_transfer(
		freertos_dma_event_control_t *dma_event_control,
		const uint8_t *data, size_t len, void *pdc_base_address,
		SemaphoreHandle_t notification_semaphore, bool is_transmitting)
{
	pdc_packet_t pdc_packet;

	/* Remember which semaphore is to be used to indicate the end of
	transmission.  If notification_semaphore is NULL then either no
	semaphore is being used, or the driver is using an internal notification
	semaphore because it is configured to wait until the transmit has
	completed before returning. */
	if (notification_semaphore != NULL) {
		dma_event_control->transaction_complete_notification_semaphore =
				notification_semaphore;
	}

	/* Ensure the notification semaphore starts in the expected state in case
	the previous PDC transfer didn't complete for any reason. */
	if (dma_event_control->transaction_complete_notification_semaphore !=
			NULL) {
		xSemaphoreTake(
				dma_event_control->transaction_complete_notification_semaphore,
				0);
	}

	/* Configure the PDC to transmit or receive parameters. */
	pdc_packet.ul_addr = (uint32_t) data;
	pdc_packet.ul_size = (uint32_t) len;

	if (is_transmitting == true) {
		pdc_disable_transfer(pdc_base_address, PERIPH_PTCR_TXTDIS);
		pdc_tx_init(pdc_base_address, &pdc_packet, NULL);
		pdc_enable_transfer(pdc_base_address, PERIPH_PTCR_TXTEN);
	} else {
		pdc_disable_transfer(pdc_base_address, PERIPH_PTCR_RXTDIS);
		pdc_rx_init(pdc_base_address, &pdc_packet, NULL);
		pdc_enable_transfer(pdc_base_address, PERIPH_PTCR_RXTEN);
	}
}
Exemplo n.º 13
0
OSStatus host_platform_bus_deinit( void )
{

    platform_mcu_powersave_disable();
#ifdef USE_OWN_SPI_DRV
    pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
	spi_disable(SPI_MASTER_BASE);
#else
    spi_master_vec_disable(&spi_master);
#endif
    platform_mcu_powersave_enable();

    return kNoErr;
}
Exemplo n.º 14
0
void serial_rx_abort_asynch(serial_t *obj)
{
    IRQn_Type irq_n = (IRQn_Type)0;
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    Pdc *pdc_base;
    usart_disable_interrupt(_USART(obj), US_IER_RXBUFF);
    pdc_base = usart_get_pdc_base(_USART(obj));
    pdc_disable_transfer(pdc_base, PERIPH_PTCR_RXTEN);
    irq_n = get_serial_irq_num(obj);
    NVIC_ClearPendingIRQ(irq_n);
    NVIC_DisableIRQ(irq_n);
    pSERIAL_S(obj)->actrec = false;
}
Exemplo n.º 15
0
OSStatus host_platform_bus_deinit( void )
{

    MCU_CLOCKS_NEEDED();
#ifdef USE_OWN_SPI_DRV
    pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
	spi_disable(SPI_MASTER_BASE);
#else
    spi_master_vec_disable(&spi_master);
#endif
    MCU_CLOCKS_NOT_NEEDED();

    return kNoErr;
}
Exemplo n.º 16
0
/** Abort an SPI transfer
 *
 * @param obj The SPI peripheral to stop
 */
void spi_abort_asynch(spi_t *obj)
{
	/* Disable PDC transfers */
	pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
		
	/* Clear PDC buffer receive counter */
	pdc_rx_clear_cnt(obj->spi.pdc);		

	/* Disable SPI IRQ */
	spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE);
	spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF);

	/* Disable SPI interrupt */
	NVIC_DisableIRQ(obj->spi.irq_type);
}
Exemplo n.º 17
0
/**
 * \brief Read a register value.
 *
 * \param reg the register address to modify.
 *
 * \return the register value.
 */
uint16_t ksz8851_reg_read(uint16_t reg)
{
    pdc_packet_t g_pdc_spi_tx_packet;
    pdc_packet_t g_pdc_spi_rx_packet;
    uint16_t cmd = 0;
    uint16_t res = 0;

    gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);

    /* Move register address to cmd bits 9-2, make 32-bit address. */
    cmd = (reg << 2) & REG_ADDR_MASK;

    /* Last 2 bits still under "don't care bits" handled with byte enable. */
    /* Select byte enable for command. */
    if (reg & 2) {
        /* Odd word address writes bytes 2 and 3 */
        cmd |= (0xc << 10);
    } else {
        /* Even word address write bytes 0 and 1 */
        cmd |= (0x3 << 10);
    }

    /* Add command read code. */
    cmd |= CMD_READ;
    tmpbuf[0] = cmd >> 8;
    tmpbuf[1] = cmd & 0xff;
    tmpbuf[2] = CONFIG_SPI_MASTER_DUMMY;
    tmpbuf[3] = CONFIG_SPI_MASTER_DUMMY;

    /* Prepare PDC transfer. */
    g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_tx_packet.ul_size = 4;
    g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_rx_packet.ul_size = 4;
    pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
    pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, 0);
    pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, 0);
    pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
    while (!(spi_read_status(KSZ8851SNL_SPI) & SPI_SR_ENDRX))
        ;

    gpio_set_pin_high(KSZ8851SNL_CSN_GPIO);

    res = (tmpbuf[3] << 8) | tmpbuf[2];
    return res;
}
Exemplo n.º 18
0
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
{
    OSStatus          err = kNoErr;

    platform_mcu_powersave_disable();
    require_action_quiet( ( driver != NULL ), exit, err = kParamErr);

    usart_disable_interrupt( driver->peripheral->port, 0xffffffff );

    NVIC_DisableIRQ( platform_flexcom_irq_numbers[driver->peripheral->uart_id] );

    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS );

    usart_disable_tx( driver->peripheral->port );
    usart_disable_rx( driver->peripheral->port );

    if( pmc_is_periph_clk_enabled( driver->peripheral->peripheral_id ) == 1  ) {
        flexcom_disable( driver->peripheral->flexcom_base );
    }

    platform_gpio_deinit( driver->peripheral->tx_pin );
    platform_gpio_deinit( driver->peripheral->rx_pin );

    if ( driver->peripheral->cts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->cts_pin );
    }

    if ( driver->peripheral->rts_pin != NULL )
    {
        platform_gpio_deinit( driver->peripheral->rts_pin );
    }

#ifndef NO_MICO_RTOS
    mico_rtos_deinit_semaphore(&driver->rx_complete);
    mico_rtos_deinit_semaphore(&driver->tx_complete);
#endif

    driver->peripheral = NULL;
    memset( driver, 0, sizeof(platform_uart_driver_t) );

exit:
    platform_mcu_powersave_enable();
    return err;
}
Exemplo n.º 19
0
/**
 *  \brief Handler for capture function interrupt.
 *
 */
static void capture_handler(Pio *p_pio)
{
	uint8_t uc_i;
	uint32_t dummy_data;

	pio_capture_disable_interrupt(p_pio, (PIO_PCIDR_ENDRX | PIO_PCIDR_RXBUFF));
	/* Disable PDC transfer. */
	pdc_disable_transfer(p_pdc, PERIPH_PTCR_RXTEN);
	/* Clear any unwanted data */
	pio_capture_read(PIOA, &dummy_data);

	printf("End of receive.\r\n");
	for (uc_i = 0; uc_i < SIZE_BUFF_RECEPT; uc_i++) {
		printf("0x%X ", pio_rx_buffer[uc_i]);
	}
	printf("\r\n");
	g_uc_cbk_received = 1;
}
Exemplo n.º 20
0
/**
 * \brief Write dummy data to the internal fifo buffer.
 *
 * \param len the amount of dummy data to write.
 */
void ksz8851_fifo_dummy(uint32_t len)
{
    pdc_packet_t g_pdc_spi_tx_packet;
    pdc_packet_t g_pdc_spi_rx_packet;

    /* Prepare PDC transfer. */
    g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_tx_packet.ul_size = len;
    g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
    g_pdc_spi_rx_packet.ul_size = len;
    pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
    pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, 0);
    pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, 0);
    pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

    while (!(spi_read_status(KSZ8851SNL_SPI) & SPI_SR_ENDRX))
        ;
}
Exemplo n.º 21
0
/**
 * \brief Write internal fifo buffer.
 *
 * \param buf the buffer to send to the fifo buffer.
 * \param ulActualLength the total amount of data to write.
 * \param ulFIFOLength the size of the first pbuf to write from the pbuf chain.
 */
void ksz8851_fifo_write(uint8_t *buf, uint32_t ulActualLength, uint32_t ulFIFOLength)
{
	static uint8_t frameID = 0;

	pdc_packet_t g_pdc_spi_tx_packet;
	pdc_packet_t g_pdc_spi_rx_packet;
	pdc_packet_t g_pdc_spi_tx_npacket;
	pdc_packet_t g_pdc_spi_rx_npacket;

	/* Prepare control word and byte count. */
	cmdBuf.uc[0] = FIFO_WRITE;
	cmdBuf.uc[1] = frameID++ & 0x3f;
	cmdBuf.uc[2] = 0;
	cmdBuf.uc[3] = ulActualLength & 0xff;
	cmdBuf.uc[4] = ulActualLength >> 8;

	spi_clear_ovres();

	/* Prepare PDC transfer. */
	g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
	g_pdc_spi_tx_packet.ul_size = 5;

	g_pdc_spi_rx_packet.ul_addr = (uint32_t) respBuf.uc;
	g_pdc_spi_rx_packet.ul_size = 5;

	g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
	g_pdc_spi_tx_npacket.ul_size = ulFIFOLength;

	g_pdc_spi_rx_npacket.ul_addr = (uint32_t) tmpbuf;
	g_pdc_spi_rx_npacket.ul_size = ulFIFOLength;

	pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
	pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
	#if( TX_USES_RECV == 1 )
		pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);
		spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_ENDRX | SPI_IER_OVRES);
		pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
	#else
		spi_enable_interrupt(KSZ8851SNL_SPI, SPI_SR_TXBUFE | SPI_IER_OVRES);
		pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_TXTEN);
	#endif
}
Exemplo n.º 22
0
/** The asynchronous IRQ handler
 *
 * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
 * conditions, such as buffer overflows or transfer complete.
 * @param[in] obj     The SPI object which holds the transfer information
 * @return event flags if a transfer termination condition was met or 0 otherwise.
 */
uint32_t spi_irq_handler_asynch(spi_t *obj){
uint32_t event=0;

	pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS| PERIPH_PTCR_TXTDIS);
	// Data transferred via DMA
	if((obj->spi.spi_base->SPI_SR & SPI_IER_TXBUFE) || (obj->spi.spi_base->SPI_SR & SPI_IER_RXBUFF)){
		event |=SPI_EVENT_COMPLETE;		
	}

	if(obj->spi.spi_base->SPI_SR & SPI_SR_MODF)
	{
		event |=SPI_EVENT_ERROR;
	}
	
	if(obj->spi.spi_base->SPI_SR & SPI_SR_OVRES)
	{
		event |=SPI_EVENT_RX_OVERFLOW;
	}

	return event;
}
Exemplo n.º 23
0
platform_result_t platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config )
{
    UNUSED_PARAMETER(spi);
    UNUSED_PARAMETER(config);

    platform_mcu_powersave_disable( );

    Pdc* spi_pdc = spi_get_pdc_base( spi->peripheral );

    /* Setup chip select pin */
    platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL );
    platform_gpio_output_high( config->chip_select );

    /* Setup other pins */
    platform_gpio_peripheral_pin_init( spi->mosi_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( spi->miso_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( spi->clk_pin,  ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP )  );

    /* Configure an SPI peripheral. */
    pmc_enable_periph_clk( spi->peripheral_id );
    spi_disable( spi->peripheral );
    spi_reset( spi->peripheral );
    spi_set_lastxfer( spi->peripheral );
    spi_set_master_mode( spi->peripheral );
    spi_disable_mode_fault_detect( spi->peripheral );
    spi_set_peripheral_chip_select_value( spi->peripheral, 0 );

    spi_set_clock_polarity( spi->peripheral, 0, ( ( config->mode && SPI_CLOCK_IDLE_HIGH )   ? (1) : (0) ) );
    spi_set_clock_phase( spi->peripheral, 0,    ( ( config->mode && SPI_CLOCK_RISING_EDGE ) ? (1) : (0) ) );

    spi_set_bits_per_transfer( spi->peripheral, 0, SPI_CSR_BITS_8_BIT );
    spi_set_baudrate_div( spi->peripheral, 0, (uint8_t)( CPU_CLOCK_HZ / config->speed ) );
    spi_set_transfer_delay( spi->peripheral, 0, 0, 0 );
    spi_enable( spi->peripheral );
    pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS );

    platform_mcu_powersave_enable( );

    return PLATFORM_SUCCESS;
}
Exemplo n.º 24
0
/**
 * \brief Initialize SPI as master.
 */
static void spi_master_initialize(void)
{
	uint32_t i;
	
	puts("-I- Initialize SPI as master\r");
	
	for (i = 0; i < COMM_BUFFER_SIZE; i++) {
		gs_uc_spi_m_tbuffer[i] = i;
	}
	
	/* Get pointer to SPI master PDC register base */
	g_p_spim_pdc = spi_get_pdc_base(SPI_MASTER_BASE);

#if (SAMG55)
	/* Enable the peripheral and set SPI mode. */
	flexcom_enable(BOARD_FLEXCOM_SPI);
	flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI);
#else
	/* Configure an SPI peripheral. */
	pmc_enable_periph_clk(SPI_ID);
#endif
	spi_disable(SPI_MASTER_BASE);
	spi_reset(SPI_MASTER_BASE);
	spi_set_lastxfer(SPI_MASTER_BASE);
	spi_set_master_mode(SPI_MASTER_BASE);
	spi_disable_mode_fault_detect(SPI_MASTER_BASE);
	spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL);
	spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
	spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
	spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL,
			SPI_CSR_BITS_8_BIT);
	spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL,
			(sysclk_get_cpu_hz() / gs_ul_spi_clock));
	spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS,
			SPI_DLYBCT);
	spi_enable(SPI_MASTER_BASE);
	
	pdc_disable_transfer(g_p_spim_pdc, PERIPH_PTCR_RXTDIS |
			PERIPH_PTCR_TXTDIS);
}
Exemplo n.º 25
0
/**
 * \brief Perform SPI master transfer.
 *
 * \param pbuf Pointer to buffer to transfer.
 * \param size Size of the buffer. 
 */
static void spi_master_transfer(void *p_tbuf, uint32_t tsize, void *p_rbuf,
		uint32_t rsize)
{
	pdc_packet_t pdc_spi_packet;

	pdc_spi_packet.ul_addr = (uint32_t)p_rbuf;
	pdc_spi_packet.ul_size = rsize;
	pdc_rx_init(g_p_spim_pdc, &pdc_spi_packet, NULL);

	pdc_spi_packet.ul_addr = (uint32_t)p_tbuf;
	pdc_spi_packet.ul_size = tsize;
	pdc_tx_init(g_p_spim_pdc, &pdc_spi_packet, NULL);
	
	/* Enable the RX and TX PDC transfer requests */
	pdc_enable_transfer(g_p_spim_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

	/* Waiting transfer done*/
	while((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RXBUFF) == 0);
	
	/* Disable the RX and TX PDC transfer requests */
	pdc_disable_transfer(g_p_spim_pdc, PERIPH_PTCR_RXTDIS |
			PERIPH_PTCR_TXTDIS);
}
Exemplo n.º 26
0
/**
 * \brief Initialize SPI as slave.
 */
static void spi_slave_initialize(void)
{
	uint32_t i;

	/* Get pointer to SPI slave PDC register base */
	g_p_spis_pdc = spi_get_pdc_base(SPI_MASTER_BASE);
	
	puts("-I- Initialize SPI as slave \r");

	for (i = 0; i < COMM_BUFFER_SIZE; i++) {
		gs_uc_spi_s_tbuffer[i] = i;
	}
#if (SAMG55)
	/* Enable the peripheral and set SPI mode. */
	flexcom_enable(BOARD_FLEXCOM_SPI);
	flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI);
#else
	/* Configure an SPI peripheral. */
	pmc_enable_periph_clk(SPI_ID);
#endif
	spi_disable(SPI_SLAVE_BASE);
	spi_reset(SPI_SLAVE_BASE);
	spi_set_slave_mode(SPI_SLAVE_BASE);
	spi_disable_mode_fault_detect(SPI_SLAVE_BASE);
	spi_set_peripheral_chip_select_value(SPI_SLAVE_BASE, SPI_CHIP_SEL);
	spi_set_clock_polarity(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
	spi_set_clock_phase(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
	spi_set_bits_per_transfer(SPI_SLAVE_BASE, SPI_CHIP_SEL,
			SPI_CSR_BITS_8_BIT);
	spi_enable(SPI_SLAVE_BASE);
	
	pdc_disable_transfer(g_p_spis_pdc, PERIPH_PTCR_RXTDIS |
			PERIPH_PTCR_TXTDIS);
	spi_slave_transfer(gs_uc_spi_s_tbuffer, COMM_BUFFER_SIZE,
			gs_uc_spi_s_rbuffer, COMM_BUFFER_SIZE);
}
Exemplo n.º 27
0
/**
 * \internal
 * \brief Transmit PPLC command to Proxy PLC controller
 *
 *  \param uc_cmd           PPLC command to send
 *  \param us_addr          Address where is the data to apply command
 *  \param us_len           Number of bytes in operation
 *  \param ptr_buf          Pointer to data buffer
 *  \param uc_bytes_rep     Number of repetitions(only use in PPLC_CMD_WRITE_REP
 * command)
 *
 * \retval true if there is no error
 * \retval false if there is an error
 */
static int8_t _pplc_cmd_op(uint8_t uc_cmd, uint16_t us_addr, uint16_t us_len,
		uint8_t *ptr_buf, uint8_t uc_bytes_rep)
{
	uint8_t *ptr_data_buf;
	uint16_t uc_num_tx_bytes;
	uint16_t us_data_len, us_data_len_acc;
	uint16_t us_address;

	Disable_global_interrupt();

	if (!uc_pplc_is_busy) {
		uc_pplc_is_busy = true;
		ptr_data_buf = ptr_buf;
		us_data_len = us_len;
		us_data_len_acc = 0;
		us_address = us_addr;

		while (us_data_len) {
			/* protection to data length */
			if (us_data_len > PDC_PPLC_BUFFER_SIZE) {
				us_data_len = PDC_PPLC_BUFFER_SIZE - 4;
			}

			uc_num_tx_bytes = us_data_len + 4;

			/* Configure PPLC Tx buffer */
			gs_pplc_tx_buffer[0] = uc_cmd;
			gs_pplc_tx_buffer[1] = (uint8_t)(us_address >> 8);
			gs_pplc_tx_buffer[2] = (uint8_t)(us_address);
			if (uc_cmd == PPLC_CMD_WRITE_REP) {
				gs_pplc_tx_buffer[3] = uc_bytes_rep;
			} else {
				gs_pplc_tx_buffer[3] = 0;
			}

			/* Fill data */
			if (uc_cmd == PPLC_CMD_READ) {
				memset(&gs_pplc_tx_buffer[4], 0, us_data_len);
			} else {
				memcpy(&gs_pplc_tx_buffer[4], ptr_data_buf, us_data_len);
			}

			/* Configure DMA channels */
			g_pplc_rx_packet.ul_addr = (uint32_t)gs_pplc_rx_buffer;
			g_pplc_rx_packet.ul_size = uc_num_tx_bytes;
			pdc_rx_init(g_pplc_pdc, &g_pplc_rx_packet, NULL);

			g_pplc_tx_packet.ul_addr = (uint32_t)gs_pplc_tx_buffer;
			g_pplc_tx_packet.ul_size = uc_num_tx_bytes;
			pdc_tx_init(g_pplc_pdc, &g_pplc_tx_packet, NULL);

			/* Enable the RX and TX PDC transfer requests */
			pdc_enable_transfer(g_pplc_pdc,
					PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);

			/* Waiting transfer done*/
			while ((spi_read_status(PPLC_SPI_MODULE) &
					SPI_SR_RXBUFF) == 0) {
			}

			/* Disable the RX and TX PDC transfer requests */
			pdc_disable_transfer(g_pplc_pdc,
					PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);

			/* copy rcv data */
			if (uc_cmd == PPLC_CMD_READ) {
				memcpy(ptr_data_buf, &gs_pplc_rx_buffer[4], us_data_len);
			}

			/* update buffer pointers */
			ptr_data_buf += us_data_len;
			us_address += us_data_len;
			/* update data length */
			us_data_len_acc += us_data_len;
			us_data_len = us_len - us_data_len_acc;
		}

		uc_pplc_is_busy = false;
		Enable_global_interrupt();
		return true;
	} else {
Exemplo n.º 28
0
/**
 * \ingroup freertos_spi_peripheral_control_group
 * \brief Initializes the FreeRTOS ASF SPI master driver for the specified SPI port.
 *
 * freertos_spi_master_init() is an ASF specific FreeRTOS driver function.  It
 * must be called before any other ASF specific FreeRTOS driver functions
 * attempt to access the same SPI port.
 *
 * If freertos_driver_parameters->operation_mode equals SPI_MASTER then
 * freertos_spi_master_init() will configure the SPI port for master mode
 * operation and enable the peripheral.  If
 * freertos_driver_parameters->operation_mode equals any other value then
 * freertos_spi_master_init() will not take any action.
 *
 * Other ASF SPI functions, such as those to set the SPI clock rate and other
 * bus parameters, can be called after freertos_spi_master_init() has completed
 * successfully.
 *
 * The FreeRTOS ASF driver both installs and handles the SPI PDC interrupts.
 * Users do not need to concern themselves with interrupt handling, and must
 * not install their own interrupt handler.
 *
 * This driver is provided with an application note, and an example project that
 * demonstrates the use of this function.
 *
 * \param p_spi    The SPI peripheral being initialized.
 * \param freertos_driver_parameters    Defines the driver behavior.  See the
 *    freertos_peripheral_options_t documentation, and the application note that
 *    accompanies the ASF specific FreeRTOS functions.
 *
 * \return If the initialization completes successfully then a handle that can
 *     be used with FreeRTOS SPI read and write functions is returned.  If
 *     the initialisation fails then NULL is returned.
 */
freertos_spi_if freertos_spi_master_init(Spi *p_spi,
		const freertos_peripheral_options_t *const freertos_driver_parameters)
{
	portBASE_TYPE spi_index;
	bool is_valid_operating_mode;
	freertos_spi_if return_value;
	const enum peripheral_operation_mode valid_operating_modes[] = {SPI_MASTER};

	/* Find the index into the all_spi_definitions array that holds details of
	the p_spi peripheral. */
	spi_index = get_pdc_peripheral_details(all_spi_definitions, MAX_SPIS,
			(void *) p_spi);

	/* Check the requested operating mode is valid for the peripheral. */
	is_valid_operating_mode = check_requested_operating_mode(
			freertos_driver_parameters->operation_mode,
			valid_operating_modes,
			sizeof(valid_operating_modes) /
			sizeof(enum peripheral_operation_mode));

	/* Don't do anything unless a valid p_spi pointer was used, and a valid
	operating mode was requested. */
	if ((spi_index < MAX_SPIS) && (is_valid_operating_mode == true)) {
		/* This function must be called exactly once per supported spi.  Check it
		has not been called	before. */
		configASSERT(memcmp((void *) &(tx_dma_control[spi_index]),
				&null_dma_control,
				sizeof(null_dma_control)) == 0);
		configASSERT(memcmp((void *) &(rx_dma_control[spi_index]),
				&null_dma_control,
				sizeof(null_dma_control)) == 0);

		/* Ensure everything is disabled before configuration. */
		spi_disable(all_spi_definitions[spi_index].peripheral_base_address);
		pdc_disable_transfer(
				all_spi_definitions[spi_index].pdc_base_address,
				(PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS));
		spi_disable_interrupt(
				all_spi_definitions[spi_index].peripheral_base_address,
				MASK_ALL_INTERRUPTS);

		switch (freertos_driver_parameters->operation_mode) {
		case SPI_MASTER:
			/* Call the standard ASF init function. */
			spi_master_init(
					all_spi_definitions[spi_index].peripheral_base_address);
			break;

		default:
			/* No other modes are currently supported. */
			break;
		}

		/* Create any required peripheral access mutexes and transaction complete
		semaphores.  This peripheral is half duplex so only a single access
		mutex is required. */
		create_peripheral_control_semaphores(
				freertos_driver_parameters->options_flags,
				&(tx_dma_control[spi_index]),
				&(rx_dma_control[spi_index]));

		/* Configure and enable the SPI interrupt in the interrupt controller. */
		configure_interrupt_controller(
				all_spi_definitions[spi_index].peripheral_irq,
				freertos_driver_parameters->interrupt_priority);

		/* Error interrupts are always enabled. */
		spi_enable_interrupt(
				all_spi_definitions[spi_index].peripheral_base_address,
				IER_ERROR_INTERRUPTS);

		/* Finally, enable the peripheral. */
		spi_enable(all_spi_definitions[spi_index].peripheral_base_address);

		return_value = (freertos_spi_if)p_spi;
	} else {
		return_value = NULL;
	}

	return return_value;
}
Exemplo n.º 29
0
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length )
{
    OSStatus result;
    uint8_t *junk;

    MCU_CLOCKS_NEEDED();
#ifdef USE_OWN_SPI_DRV
	pdc_packet_t pdc_spi_packet;

	pdc_spi_packet.ul_addr = (uint32_t)buffer;
	pdc_spi_packet.ul_size = buffer_length;
	pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL);

    if ( dir == BUS_READ ) {
	    pdc_spi_packet.ul_addr = (uint32_t)buffer;
	    pdc_spi_packet.ul_size = buffer_length;
    } 
	if ( dir == BUS_WRITE ) {
        junk = malloc(buffer_length);
	    pdc_spi_packet.ul_addr = (uint32_t)junk;
	    pdc_spi_packet.ul_size = buffer_length;
    }
	pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL);
#if 0
	if ( dir == BUS_WRITE ) {
		spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDTX);
	    NVIC_EnableIRQ(SPI_IRQn);
	}
	else {
		spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDRX);
	    NVIC_EnableIRQ(SPI_IRQn);
	}
#endif	
    //platform_log("dir = %d, len = %d",dir, buffer_length);//TBD
#ifndef HARD_CS_NSS0	
	mico_gpio_output_low( MICO_GPIO_15 );
#endif
	/* Enable the RX and TX PDC transfer requests */
    pdc_enable_transfer(spi_m_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);//pdc buffer address increase automatic.
    //platform_log("pdc status = 0x%x",pdc_read_status(spi_m_pdc));

#ifndef NO_MICO_RTOS
    result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 );
#else
    /* Waiting transfer done*/
	while((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RXBUFF) == 0) {
        __asm("wfi");
    }
#endif
	if ( dir == BUS_WRITE ) {
        if (junk) 
            free(junk);
    }
	/* Disable the RX and TX PDC transfer requests */
    pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);

#ifndef HARD_CS_NSS0	
	mico_gpio_output_high( MICO_GPIO_15 );
#endif
#if 1
    //clear PDC Perph Status flags
	pdc_spi_packet.ul_addr = NULL;
	pdc_spi_packet.ul_size = 3;
	pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL);
	pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL);
#endif
#else //spi_master_vec :

    tx_dscr[0].data   = buffer;
    tx_dscr[0].length = buffer_length;
    tx_dscr[1].data   = NULL;
    tx_dscr[1].length = 0;
    
    //if ( dir == BUS_READ ) {
        rx_dscr[0].data   = buffer;
        rx_dscr[0].length = buffer_length;
    //} else {
    //    rx_dscr[0].data   = &junk;
    //    rx_dscr[0].length = 0;
    //}
    rx_dscr[1].data   = NULL;
    rx_dscr[1].length = 0;
#ifndef HARD_CS_NSS0	
    mico_gpio_output_low( MICO_GPIO_15 );
#endif 
    if (spi_master_vec_transceive_buffer_wait(&spi_master, tx_dscr, rx_dscr) != STATUS_OK) {
        platform_log("STATUS = -1");
        return kGeneralErr;
    }
#ifndef HARD_CS_NSS0	   
    mico_gpio_output_high( MICO_GPIO_15 );
#endif
#endif /* USE_OWN_SPI_DR */
    MCU_CLOCKS_NOT_NEEDED();
#ifdef USE_OWN_SPI_DRV
    return result;
#else
    return 0;
#endif
}
Exemplo n.º 30
0
/**
 * \ingroup freertos_spi_peripheral_control_group
 * \brief Initiate a completely asynchronous multi-byte read operation on an SPI
 * peripheral.
 *
 * freertos_spi_read_packet_async() is an ASF specific FreeRTOS driver function.
 * It configures the SPI peripheral DMA controller (PDC) to read data from the
 * SPI port, then returns.  freertos_spi_read_packet_async() does not wait for
 * the reception to complete before returning.
 *
 * The FreeRTOS ASF SPI driver is initialized using a call to
 * freertos_spi_master_init().  The freertos_driver_parameters.options_flags
 * parameter passed into the initialization function defines the driver behavior.
 * freertos_spi_read_packet_async() can only be used if the
 * freertos_driver_parameters.options_flags parameter passed to the initialization
 * function had the WAIT_RX_COMPLETE bit clear.
 *
 * freertos_spi_read_packet_async() is an advanced function and readers are
 * recommended to also reference the application note and examples that
 * accompany the FreeRTOS ASF drivers.  freertos_spi_read_packet() is a version
 * that does not exit until the PDC transfer is complete, but still allows other
 * RTOS tasks to execute while the transmission is in progress.
 *
 * The FreeRTOS ASF driver both installs and handles the SPI PDC interrupts.
 * Users do not need to concern themselves with interrupt handling, and must
 * not install their own interrupt handler.
 *
 * \param p_spi    The handle to the SPI port returned by the
 *     freertos_spi_master_init() call used to initialise the port.
 * \param data    A pointer to the buffer into which received data is to be
 *     written.
 * \param len    The number of bytes to receive.
 * \param block_time_ticks    The FreeRTOS ASF SPI driver is initialized using a
 *     call to freertos_spi_master_init().  The
 *     freertos_driver_parameters.options_flags parameter passed to the
 *     initialization function defines the driver behavior.  If
 *     freertos_driver_parameters.options_flags had the USE_RX_ACCESS_MUTEX bit
 *     set, then the driver will only read from the SPI peripheral if it has
 *     first gained exclusive access to it.  block_time_ticks specifies the
 *     maximum amount of time the driver will wait to get exclusive access
 *     before aborting the read operation.  Other tasks will execute during any
 *     waiting time.  block_time_ticks is specified in RTOS tick periods.  To
 *     specify a block time in milliseconds, divide the milliseconds value by
 *     portTICK_RATE_MS, and pass the result in block_time_ticks.
 *     portTICK_RATE_MS is defined by FreeRTOS.
 * \param notification_semaphore    The RTOS task that calls the receive
 *     function exits the receive function as soon as the reception starts.
 *     The data being received by the PDC cannot normally be processed until
 *     after the reception has completed.  The PDC interrupt (handled internally
 *     by the FreeRTOS ASF driver) 'gives' the semaphore when the PDC transfer
 *     completes.  The notification_semaphore therefore provides a mechanism for
 *     the calling task to know when the PDC has read the requested number of
 *     bytes.  The calling task can call standard FreeRTOS functions to block on
 *     the semaphore until the PDC interrupt occurs.  Other RTOS tasks will
 *     execute while the the calling task is in the Blocked state.  The
 *     semaphore must be created using the FreeRTOS vSemaphoreCreateBinary() API
 *     function before it is used as a parameter.
 *
 * \return     ERR_INVALID_ARG is returned if an input parameter is invalid.
 *     ERR_TIMEOUT is returned if block_time_ticks passed before exclusive
 *     access to the SPI peripheral could be obtained.  STATUS_OK is returned if
 *     the PDC was successfully configured to perform the SPI read operation.
 */
status_code_t freertos_spi_read_packet_async(freertos_spi_if p_spi,
		uint8_t *data, uint32_t len, portTickType block_time_ticks,
		xSemaphoreHandle notification_semaphore)
{
	status_code_t return_value;
	pdc_packet_t pdc_tx_packet;
	portBASE_TYPE spi_index;
	Spi *spi_base;
	volatile uint16_t junk_value;

	spi_base = (Spi *) p_spi;
	spi_index = get_pdc_peripheral_details(all_spi_definitions, MAX_SPIS,
			(void *) spi_base);

	/* Don't do anything unless a valid SPI pointer was used. */
	if (spi_index < MAX_SPIS) {
		/* Because the peripheral is half duplex, there is only one access mutex
		and the rx uses the tx mutex. */
		return_value = freertos_obtain_peripheral_access_mutex(
				&(tx_dma_control[spi_index]), &block_time_ticks);

		if (return_value == STATUS_OK) {
			/* Data must be sent for data to be received.  Set the receive
			buffer to all 0xffs so it can also be used as the send buffer. */
			memset((void *)data, 0xff, (size_t)len);

			/* Ensure Rx is already empty. */
			while(spi_is_rx_full(all_spi_definitions[spi_index].peripheral_base_address) != 0) {
				junk_value = ((Spi*) all_spi_definitions[spi_index].peripheral_base_address)->SPI_RDR;
				(void) junk_value;
			}

			/* Start the PDC reception, although nothing is received until the
			SPI is also transmitting. */
			freertos_start_pdc_rx(&(rx_dma_control[spi_index]),
					data, len,
					all_spi_definitions[spi_index].pdc_base_address,
					notification_semaphore);

			/* Start the transmit so data is also received. */
			pdc_tx_packet.ul_addr = (uint32_t)data;
			pdc_tx_packet.ul_size = (uint32_t)len;
			pdc_disable_transfer(
					all_spi_definitions[spi_index].pdc_base_address,
					PERIPH_PTCR_TXTDIS);
			pdc_tx_init(
					all_spi_definitions[spi_index].pdc_base_address, &pdc_tx_packet,
					NULL);
			pdc_enable_transfer(
					all_spi_definitions[spi_index].pdc_base_address,
					PERIPH_PTCR_TXTEN);

			/* Catch the end of reception so the access mutex can be returned,
			and the task notified (if it supplied a notification semaphore).
			The interrupt can be enabled here because the ENDRX	signal from the
			PDC to the peripheral will have been de-asserted when the next
			transfer was configured. */
			spi_enable_interrupt(spi_base, SPI_IER_ENDRX);

			return_value = freertos_optionally_wait_transfer_completion(
					&(rx_dma_control[spi_index]),
					notification_semaphore,
					block_time_ticks);
		}
	} else {
		return_value = ERR_INVALID_ARG;
	}

	return return_value;
}