Example #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 );
}
Example #2
0
/**
 * \brief Test SPI interrupt handler.
 */
void CONF_TEST_SPI_HANDLER(void)
{
	uint32_t status = spi_read_status(CONF_TEST_SPI);

	if (status & SPI_SR_TDRE) {
		g_b_spi_interrupt_tx_ready = true;
		spi_disable_interrupt(CONF_TEST_SPI, SPI_IDR_TDRE);
	}

	if (status & SPI_SR_RDRF) {
		g_b_spi_interrupt_rx_ready = true;
		spi_disable_interrupt(CONF_TEST_SPI, SPI_IDR_RDRF);
	}
}
Example #3
0
/**
 * SPI interrupt service routine
 */
void AJ_WSL_SPI_ISR(void)
{
    uint32_t status = spi_read_status(AJ_WSL_SPI_DEVICE);

    if (status & SPI_SR_TDRE) {
        //g_b_spi_interrupt_tx_ready = true;
        spi_disable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IDR_TDRE);
    }

    if (status & SPI_SR_RDRF) {
        //g_b_spi_interrupt_rx_ready = true;
        spi_disable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IDR_RDRF);
    }
}
/** 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);
}
Example #5
0
void SPI0_Handler(void) {	
	uint16_t us_data;
	uint32_t us_tx_data;	
			
	uint8_t p_pcs;
	
	uint32_t status = spi_read_status(_spi_base);
		
	if (status & SPI_SR_RDRF) {		
		if ( spi_read( _spi_base, &us_data,	&p_pcs ) == SPI_OK ) {
			// store received byte
			fifo_push_uint8(_this->_spi_rx_fifo_desc, us_data);
			
			// If handler defined - call it with instance and received byte.
			if (_this->_call_back)
			{
				_this->_call_back(_this, (uint8_t)us_data);
			}
		}
	}	
	
	if (status & SPI_SR_TDRE) {
		// more bytes to send?		
		if ( fifo_pull_uint32(_this->_spi_tx_fifo_desc, &us_tx_data) == FIFO_OK ) {
			_spi_base->SPI_TDR = us_tx_data;
		} else {
			// No
			// Disable SPI TX interrupt
			spi_disable_interrupt(_spi_base, SPI_IDR_TDRE);
			_spi_active = 0;
		}
	}
}
Example #6
0
/**
@ingroup spi_function
@brief Send an array of bytes to to the SPI bus.

@note Can only be used if SPI_USE_BUFFER are enabled in spi_iha_defs.h

@see spi_iha_defs.h for SPI_USE_BUFFER setup.

@return SPI_OK: OK byte send to SPI bus or put in tx_buffer.\n
SPI_NO_ROOM_IN_TX_BUFFER: Buffer full no data send\n
SPI_ILLEGAL_INSTANCE: instance is null.
@param spi to send to.
@param *buf pointer to buffer to be send.
@param len no of bytes to send.
*/
uint8_t spi_send_bytes(spi_p spi, uint8_t buf[], uint8_t len) {
	uint8_t result = SPI_OK;
	uint32_t value;
	uint8_t tmp = 0;	
	
	if (spi == NULL) {
		return SPI_ILLEGAL_INSTANCE;
	}

	// Select correct instance
	if (_this != spi ) {
		_select_instance(spi);
	}

	// Critical section
	 	{
 		// disable interrupt
		spi_disable_interrupt(_spi_base, SPI_IDR_TDRE | SPI_IDR_RDRF);

		// Check if buffer is free
		if (len > fifo_get_free_size(spi->_spi_tx_fifo_desc)) {
			result = SPI_NO_ROOM_IN_TX_BUFFER;
		} else {
			// If SPI in idle send the first byte
			if (!_spi_active) {
				_spi_active = 1;
					
				// Send first byte
				value = SPI_TDR_TD(buf[0]) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
				if (len == 1) {
					// It was last byte
					value |= SPI_TDR_LASTXFER;
				}					

				// Send byte
				_spi_base->SPI_TDR = value;
				//spi_enable_interrupt(_spi_base, SPI_IER_TDRE);
				tmp = 1;
			}
				
			// Put in the tx buffer
			for (uint8_t i = tmp; i < len; i++) {
				value = SPI_TDR_TD(buf[i]) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
				if (i == len-1) {
					// It was last byte
					value |= SPI_TDR_LASTXFER;
				}
				if ( fifo_push_uint32(spi->_spi_tx_fifo_desc, value) == FIFO_ERROR_OVERFLOW ) {
					result = SPI_NO_ROOM_IN_TX_BUFFER;			
				}
			}
		}

 		// restore interrupt state
		spi_enable_interrupt(_spi_base, SPI_IER_TDRE | SPI_IER_RDRF);
	}
	return result;
}
Example #7
0
uint8_t spi_send_byte(spi_p spi, uint8_t byte, uint8_t last_byte)
{
	uint8_t result = SPI_OK;
	uint32_t value;
	
	if (spi == NULL) {
		return SPI_ILLEGAL_INSTANCE;
	}

	// Select correct instance
	if (_this != spi ) {
		_select_instance(spi);
	}

	// Critical section
	{
		// disable interrupt
		spi_disable_interrupt(_spi_base, SPI_IDR_TDRE | SPI_IDR_RDRF);
		
		value = SPI_TDR_TD(byte) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
		if (last_byte) {
			value |= SPI_TDR_LASTXFER;
		}

		// If SPI in idle send the byte
		if (!_spi_active) {
			_spi_active = 1;

			// Send byte
			_spi_base->SPI_TDR = value;
		} else {
			// Put in the TX buffer
			if ( fifo_push_uint32(spi->_spi_tx_fifo_desc, value) == FIFO_ERROR_UNDERFLOW )
				result = SPI_NO_ROOM_IN_TX_BUFFER;
		}
		// Enable interrupt
		spi_enable_interrupt(_spi_base, SPI_IER_TDRE | SPI_IER_RDRF);
	}

	return result;
}
Example #8
0
OSStatus host_platform_bus_init( void )
{
#ifndef USE_OWN_SPI_DRV 
	struct spi_master_vec_config spi; 
#else
	pdc_packet_t pdc_spi_packet;
#endif
    OSStatus result;

    MCU_CLOCKS_NEEDED();

	spi_disable_interrupt(SPI_MASTER_BASE, 0xffffffff);
    //Disable_global_interrupt();//TBD!

    result = mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 );
    if ( result != kNoErr )
    {
        return result;
    }
    
    mico_gpio_initialize( (mico_gpio_t)MICO_GPIO_9, INPUT_PULL_UP );
    //ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(PORTA,24));
    //pio_set_input(PIOA,ul_mask, PIO_PULLUP|PIO_DEBOUNCE);
    mico_gpio_enable_IRQ( (mico_gpio_t)MICO_GPIO_9, IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, NULL );
#ifndef HARD_CS_NSS0	
    mico_gpio_initialize( MICO_GPIO_15, OUTPUT_PUSH_PULL);//spi ss/cs 
	mico_gpio_output_high( MICO_GPIO_15 );//MICO_GPIO_15 TBD!
#else
	ioport_set_pin_peripheral_mode(SPI_NPCS0_GPIO, SPI_NPCS0_FLAGS);//TBD!
#endif
    /* set PORTB 01 to high to put WLAN module into g_SPI mode */
    mico_gpio_initialize( (mico_gpio_t)WL_GPIO0, OUTPUT_PUSH_PULL );
    mico_gpio_output_high( (mico_gpio_t)WL_GPIO0 );
#ifdef USE_OWN_SPI_DRV 
#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
    //Init pdc, and clear RX TX.
    spi_m_pdc = spi_get_pdc_base(SPI_MASTER_BASE);

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

	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);
#ifdef HARD_CS_NSS0
	//spi_enable_peripheral_select_decode(SPI_MASTER_BASE);
	//spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL);
	spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_PCS); //use soft nss comment here
#endif
	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() / SPI_BAUD_RATE));
	spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT);

    /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
    /* otherwise FreeRTOS will not be able to mask the interrupt */
    /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */
    /* is the lowest priority */
	/* Configure SPI interrupts . */
    spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_RXBUFF);
    //spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_NSSR | SPI_IER_RXBUFF);
	
	NVIC_DisableIRQ(SPI_IRQn);
    //irq_register_handler(SPI_IRQn, 3);
	NVIC_ClearPendingIRQ(SPI_IRQn);
	NVIC_SetPriority(SPI_IRQn, 3);
	NVIC_EnableIRQ(SPI_IRQn);

    spi_enable(SPI_MASTER_BASE);
#else
    spi.baudrate = SPI_BAUD_RATE;
	if (STATUS_OK != spi_master_vec_init(&spi_master, SPI_MASTER_BASE, &spi)) {
		return -1;
	}

	spi_master_vec_enable(&spi_master);
#endif
    //if (!Is_global_interrupt_enabled())
    //    Enable_global_interrupt();
    MCU_CLOCKS_NOT_NEEDED();

    return kNoErr;
}
Example #9
0
/*
 * For internal use only.
 * A common SPI interrupt handler that is called for all SPI peripherals.
 */
static void local_spi_handler(const portBASE_TYPE spi_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t spi_status;
	Spi *spi_port;

	spi_port = all_spi_definitions[spi_index].peripheral_base_address;

	spi_status = spi_read_status(spi_port);
	spi_status &= spi_read_interrupt_mask(spi_port);

	/* Has the PDC completed a transmission? */
	if ((spi_status & SPI_SR_ENDTX) != 0UL) {
		spi_disable_interrupt(spi_port, SPI_IDR_ENDTX);

		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the sending task supplied a notification semaphore, then
		 * notify the task that the transmission has completed. */
		if (tx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	/* Has the PDC completed a reception? */
	if ((spi_status & SPI_SR_ENDRX) != 0UL) {
		spi_disable_interrupt(spi_port, SPI_IDR_ENDRX);

		/* If the driver is supporting multi-threading, then return the access
		mutex.  NOTE: As a reception is performed by first performing a
		transmission, the SPI receive function uses the tx access semaphore. */
		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* If the receiving task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if (rx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					rx_dma_control[spi_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((spi_status & SR_ERROR_INTERRUPTS) != 0) {
		/* An mode error occurred in either a transmission or reception.  Abort.
		Stop the transmission, disable interrupts used by the peripheral, and
		ensure the peripheral access mutex is made available to tasks.  As this
		peripheral is half duplex, only the Tx peripheral access mutex exits. */
		spi_disable_interrupt(spi_port, SPI_IDR_ENDTX);
		spi_disable_interrupt(spi_port, SPI_IDR_ENDRX);

		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* The SPI port will have been disabled, re-enable it. */
		spi_enable(spi_port);
	}

	/* If giving a semaphore caused a task to unblock, and the unblocked task
	has a priority equal to or higher than the currently running task (the task
	this ISR interrupted), then higher_priority_task_woken will have
	automatically been set to pdTRUE within the semaphore function.
	portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to
	the higher priority unblocked task. */
	portEND_SWITCHING_ISR(higher_priority_task_woken);
}
Example #10
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;
}
Example #11
0
/**
 * \brief Test SPI transfer.
 *
 * This test tests SPI read/write.
 *
 * \param test Current test case.
 */
static void run_spi_trans_test(const struct test_case *test)
{
	spi_status_t rc;
	uint16_t     spi_data;
	uint8_t      spi_pcs;

	spi_reset(CONF_TEST_SPI);
	spi_set_lastxfer(CONF_TEST_SPI);
	spi_set_master_mode(CONF_TEST_SPI);
	spi_disable_mode_fault_detect(CONF_TEST_SPI);
	spi_set_peripheral_chip_select_value(CONF_TEST_SPI, CONF_TEST_SPI_NPCS);
	spi_set_clock_polarity(CONF_TEST_SPI,
		CONF_TEST_SPI_NPCS, SPI_CLK_POLARITY);
	spi_set_clock_phase(CONF_TEST_SPI, CONF_TEST_SPI_NPCS, SPI_CLK_PHASE);
	spi_set_bits_per_transfer(CONF_TEST_SPI,
		CONF_TEST_SPI_NPCS, SPI_CSR_BITS_8_BIT);
	spi_set_baudrate_div(CONF_TEST_SPI,
		CONF_TEST_SPI_NPCS,
		(sysclk_get_cpu_hz() / TEST_CLOCK));
	spi_set_transfer_delay(CONF_TEST_SPI,
		CONF_TEST_SPI_NPCS, SPI_DLYBS, SPI_DLYBCT);
	spi_set_variable_peripheral_select(CONF_TEST_SPI);
	spi_enable_loopback(CONF_TEST_SPI);

	/* Test read/write timeout: should return SPI_ERROR_TIMEOUT. */
	rc = spi_write(CONF_TEST_SPI, TEST_PATTERN, TEST_PCS, 1);
	test_assert_true(test, rc == SPI_ERROR_TIMEOUT,
		"Test SPI Write timeout: return code should not be %d", rc);

	rc = spi_read(CONF_TEST_SPI, &spi_data, &spi_pcs);
	test_assert_true(test, rc == SPI_ERROR_TIMEOUT,
		"Test SPI Read timeout: return code should not be %d", rc);

	spi_enable(CONF_TEST_SPI);
	spi_enable_interrupt(CONF_TEST_SPI, SPI_IER_TDRE|SPI_IER_RDRF);
	NVIC_EnableIRQ((IRQn_Type)CONF_TEST_SPI_ID);

	/* Test write: should return OK. */
	rc = spi_write(CONF_TEST_SPI, TEST_PATTERN, TEST_PCS, 1);
	test_assert_true(test, rc == SPI_OK,
		"Test SPI Write: return code should not be %d", rc);

	/* Test read: should return OK with what is sent. */
	rc = spi_read(CONF_TEST_SPI, &spi_data, &spi_pcs);
	test_assert_true(test, rc == SPI_OK,
		"Test SPI Read: return code should not be %d", rc);
	test_assert_true(test, spi_data == TEST_PATTERN,
		"Unexpected SPI data: %x, should be %x",
		spi_data, TEST_PATTERN);
	test_assert_true(test, spi_pcs == TEST_PCS,
		"Unexpected SPI PCS: %x, should be %x",
		spi_pcs, TEST_PCS);

	/* Check interrupts. */
	test_assert_true(test, g_b_spi_interrupt_tx_ready,
		"Test SPI TX interrupt not detected");
	test_assert_true(test, g_b_spi_interrupt_rx_ready,
		"Test SPI RX interrupt not detected");

	/* Done, disable SPI and all interrupts. */
	spi_disable_loopback(CONF_TEST_SPI);
	spi_disable(CONF_TEST_SPI);
	spi_disable_interrupt(CONF_TEST_SPI, 0xFFFFFFFF);
	NVIC_DisableIRQ((IRQn_Type)CONF_TEST_SPI_ID);
}
Example #12
0
void AJ_WSL_SPI_ShutdownSPIController(void)
{
    spi_disable(AJ_WSL_SPI_DEVICE);
    spi_disable_interrupt(AJ_WSL_SPI_DEVICE, 0xFFFFFFFF);
}
Example #13
0
OSStatus host_platform_bus_init( void )
{
  pdc_packet_t  pdc_spi_packet;
  Pdc*          spi_pdc  = spi_get_pdc_base( wifi_spi.port );
  
  platform_mcu_powersave_disable( );
  
  mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 );
  
  /* Setup the SPI lines */
  platform_gpio_peripheral_pin_init(  wifi_spi.mosi_pin,  ( wifi_spi.mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  platform_gpio_peripheral_pin_init(  wifi_spi.miso_pin,  ( wifi_spi.miso_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  platform_gpio_peripheral_pin_init(  wifi_spi.clock_pin, ( wifi_spi.clock_pin_mux_mode | IOPORT_MODE_PULLUP ) );
  
  /* Setup the interrupt input for WLAN_IRQ */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
  platform_gpio_irq_enable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );
  
  /* Setup SPI slave select GPIOs */
  platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], OUTPUT_PUSH_PULL );
  platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] );
  
#if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP )
  /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL );
  platform_gpio_output_high( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] );
  platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL );
  platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] );
#endif
  
  /* Enable the peripheral and set SPI mode. */
  flexcom_enable( flexcom_base[ wifi_spi.spi_id ] );
  flexcom_set_opmode( flexcom_base[ wifi_spi.spi_id ], FLEXCOM_SPI );
  
  /* Init pdc, and clear RX TX. */
  pdc_spi_packet.ul_addr = 0;
  pdc_spi_packet.ul_size = 1;
  pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL );
  pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL );
  
  spi_disable_interrupt(wifi_spi.port, 0xffffffff );
  spi_disable( wifi_spi.port );
  spi_reset( wifi_spi.port );
  spi_set_lastxfer( wifi_spi.port );
  spi_set_master_mode( wifi_spi.port );
  spi_disable_mode_fault_detect( wifi_spi.port );
  
  spi_set_clock_polarity( wifi_spi.port, 0, SPI_CLK_POLARITY );
  spi_set_clock_phase( wifi_spi.port, 0, SPI_CLK_PHASE );
  spi_set_bits_per_transfer( wifi_spi.port, 0, SPI_CSR_BITS_8_BIT );
  spi_set_baudrate_div( wifi_spi.port, 0, (sysclk_get_cpu_hz() / SPI_BAUD_RATE) );
  spi_set_transfer_delay( wifi_spi.port, 0, 0, 0 );
  
  /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */
  /* otherwise FreeRTOS will not be able to mask the interrupt */
  /* keep in mind that ARMCM4 interrupt priority logic is inverted, the highest value */
  /* is the lowest priority */
  /* Configure SPI interrupts . */
  
  NVIC_EnableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] );
  
  spi_enable(wifi_spi.port);
  
  platform_mcu_powersave_enable( );
  
  return kNoErr;
}
Example #14
0
/*!
 * This function inititializes register address and set default configuration.
 *
 * @param        spi        the module number
 * @return       This function returns 0 if successful, -EPERM otherwise.
 */
int spi_init_default_conf(module_nb_t spi)
{
	int error = 0;

#ifdef CONFIG_MOT_WFN446
        if(spi >= CONFIG_SPI_NB_MAX) {
            return -EPERM;
        }
#endif

	/* Configure SPI registers adresses */
	spi_add[spi].rx_address = spi_add[spi].base_address +
	    OFFSET_CSPI_RXDATAREG;
	spi_add[spi].tx_address = spi_add[spi].base_address +
	    OFFSET_CSPI_TXDATAREG;
	spi_add[spi].ctrl_address = spi_add[spi].base_address +
	    OFFSET_CSPI_CONTROLREG;
	spi_add[spi].int_address = spi_add[spi].base_address +
	    OFFSET_CSPI_INTREG;
	spi_add[spi].stat_address = spi_add[spi].base_address +
	    OFFSET_CSPI_STATREG;
	spi_add[spi].period_address = spi_add[spi].base_address +
	    OFFSET_CSPI_PERIODREG;
	spi_add[spi].test_address = spi_add[spi].base_address +
	    OFFSET_CSPI_TESTREG;
	spi_add[spi].reset_address = spi_add[spi].base_address +
	    OFFSET_CSPI_RESETREG;

	/* SPI current handle configuration */
	spi_port[spi].current_config_handle = NULL;

	/* SPI exchange mutex initialization */
	init_MUTEX_LOCKED(&(spi_port[spi].sync_interface));

	/* Software reset of the module */
	spi_disable(spi);
	/* Module enabled */
	spi_enable(spi);

	/* Disable all interrupt sources */
	error = spi_disable_interrupt(spi,
				      SPI_STATUS_TX_FIFO_EMPTY |
				      SPI_STATUS_TX_FIFO_HALF_EMPTY |
				      mxc_spi_unique_def->
				      spi_status_transfer_complete |
				      SPI_STATUS_RX_FIFO_DATA_READY |
				      SPI_STATUS_TX_FIFO_FULL |
				      SPI_STATUS_RX_FIFO_HALF_FULL |
				      SPI_STATUS_RX_FIFO_FULL |
				      SPI_STATUS_RX_FIFO_OVERFLOW |
				      mxc_spi_unique_def->
				      spi_status_bit_count_overflow);

	if (error != 0) {
		return error;
	}
	/* Request IRQ */
	/*
	   error = request_irq(spi_port[spi].int_cspi, spi_isr_handler, 0,
	   "cspi IRQ", (void*)(&spi_port[spi]));
	   if (error != 0 ){
	   return error;
	   }
	 */

	/* enable IT */
	/*
	   error = spi_enable_interrupt(spi, SPI_STATUS_RX_FIFO_DATA_READY);
	   if (error != 0 ){
	   return error;
	   }
	 */

	return 0;
}
Example #15
0
/**
 * \brief Write a register value.
 *
 * \param reg the register address to modify.
 * \param wrdata the new register value.
 */
void ksz8851_reg_write(uint16_t reg, uint16_t wrdata)
{
pdc_packet_t g_pdc_spi_tx_packet;
pdc_packet_t g_pdc_spi_rx_packet;
uint16_t cmd = 0;
int iTryCount = 3;

	while( iTryCount-- > 0 )
	{
	uint32_t ulStatus;


		spi_clear_ovres();
		/* 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 write code. */
		cmd |= CMD_WRITE;
		cmdBuf.uc[0] = cmd >> 8;
		cmdBuf.uc[1] = cmd & 0xff;
		cmdBuf.uc[2] = wrdata & 0xff;
		cmdBuf.uc[3] = wrdata >> 8;

		/* Prepare PDC transfer. */
		g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
		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, NULL);
		pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, NULL);
		gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);

		spi_disable_interrupt( KSZ8851SNL_SPI, ~0ul );

		pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
		for( ;; )
		{
			ulStatus = spi_read_status( KSZ8851SNL_SPI );
			if( ( ulStatus & ( SPI_SR_OVRES | SPI_SR_ENDRX ) ) != 0 )
			{
				break;
			}
		}
		gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
		if( ( ulStatus & SPI_SR_OVRES ) == 0 )
		{
			break;
		}
		pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
		lUDPLoggingPrintf( "ksz8851_reg_write: SPI_SR_OVRES\n" );
	}
}