Пример #1
0
/**
 * \brief Initialize TWIHS slave mode.
 *
 * \param p_twihs Pointer to a TWIHS instance.
 * \param ul_device_addr Device address of the SAM slave device on the I2C bus.
 */
void twihs_slave_init(Twihs *p_twihs, uint32_t ul_device_addr)
{
	/* Disable TWIHS interrupts */
	p_twihs->TWIHS_IDR = ~0UL;
	p_twihs->TWIHS_SR;

	/* Reset TWIHS */
	twihs_reset(p_twihs);

	/* Set slave address in slave mode */
	p_twihs->TWIHS_SMR = TWIHS_SMR_SADR(ul_device_addr);

	/* Enable slave mode */
	twihs_enable_slave_mode(p_twihs);
}
Пример #2
0
/**
 * \brief Initialize TWIHS master mode.
 *
 * \param p_twihs Pointer to a TWIHS instance.
 * \param p_opt Options for initializing the TWIHS module (see \ref twihs_options_t).
 *
 * \return TWIHS_SUCCESS if initialization is complete, error code otherwise.
 */
uint32_t twihs_master_init(Twihs *p_twihs, const twihs_options_t *p_opt)
{
	uint32_t status = TWIHS_SUCCESS;

	/* Disable TWIHS interrupts */
	p_twihs->TWIHS_IDR = ~0UL;

	/* Dummy read in status register */
	p_twihs->TWIHS_SR;

	/* Reset TWIHS peripheral */
	twihs_reset(p_twihs);

	twihs_enable_master_mode(p_twihs);

	/* Select the speed */
	if (twihs_set_speed(p_twihs, p_opt->speed, p_opt->master_clk) == FAIL) {
		/* The desired speed setting is rejected */
		status = TWIHS_INVALID_ARGUMENT;
	}

	return status;
}
Пример #3
0
/**
 * \ingroup freertos_twihs_peripheral_control_group
 * \brief Initializes the FreeRTOS ASF TWIHS (I2C) master driver for the specified
 * TWIHS port.
 *
 * freertos_twihs_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 TWIHS port.
 *
 * If freertos_driver_parameters->operation_mode equals TWIHS_I2C_MASTER then
 * freertos_twihs_master_init() will configure the TWIHS port for master mode
 * operation and enable the peripheral.  If
 * freertos_driver_parameters->operation_mode equals any other value then
 * freertos_twihs_master_init() will not take any action.
 *
 * Other ASF TWIHS functions can be called after freertos_twihs_master_init() has
 * completed successfully.
 *
 * The FreeRTOS ASF driver both installs and handles the TWIHS 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_twihs    The twihs 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 TWIHS read and write functions is returned.  If
 *     the initialisation fails then NULL is returned.
 */
freertos_twihs_if freertos_twihs_master_init(Twihs *p_twihs,
		const freertos_peripheral_options_t *const freertos_driver_parameters)
{
	portBASE_TYPE twihs_index;
	bool is_valid_operating_mode;
	freertos_twihs_if return_value;
	const enum peripheral_operation_mode valid_operating_modes[] = {TWIHS_I2C_MASTER};

	/* Find the index into the all_twihs_definitions array that holds details of
	the p_twihs peripheral. */
	twihs_index = get_pdc_peripheral_details(all_twihs_definitions, MAX_TWIHS,
			(void *) p_twihs);

	/* 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_twihs pointer was used, and a valid
	operating mode was requested. */
	if ((twihs_index < MAX_TWIHS) && (is_valid_operating_mode == true)) {
		/* This function must be called exactly once per supported twihs.  Check
		it has not been called	before. */
		configASSERT(memcmp((void *)&(tx_dma_control[twihs_index]),
				&null_dma_control,
				sizeof(null_dma_control)) == 0);
		configASSERT(memcmp((void *)&(rx_dma_control[twihs_index]),
				&null_dma_control,
				sizeof(null_dma_control)) == 0);

		/* Enable the peripheral's clock. */
		pmc_enable_periph_clk(
				all_twihs_definitions[twihs_index].peripheral_id);

		/* Ensure everything is disabled before configuration. */
		pdc_disable_transfer(
				all_twihs_definitions[twihs_index].pdc_base_address,
				(PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS));
		twihs_disable_interrupt(
				all_twihs_definitions[twihs_index].peripheral_base_address,
				MASK_ALL_INTERRUPTS);
		twihs_reset(
				all_twihs_definitions[twihs_index].peripheral_base_address);

		switch (freertos_driver_parameters->operation_mode) {
		case TWIHS_I2C_MASTER:
			/* Call the standard ASF init function. */
			twihs_enable_master_mode(
					all_twihs_definitions[twihs_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[twihs_index]),
				&(rx_dma_control[twihs_index]));

		/* Error interrupts are always enabled. */
		twihs_enable_interrupt(
				all_twihs_definitions[twihs_index].peripheral_base_address,
				IER_ERROR_INTERRUPTS);

		/* Configure and enable the TWIHS interrupt in the interrupt controller. */
		configure_interrupt_controller(
				all_twihs_definitions[twihs_index].peripheral_irq,
				freertos_driver_parameters->interrupt_priority);

		return_value = (freertos_twihs_if) p_twihs;
	} else {
		return_value = NULL;
	}

	return return_value;
}