Пример #1
0
/** \brief method to change the bus speed of I2C
 * \param[in] interface on which to change bus speed
 * \param[in] baud rate (typically 100000 or 400000)
 */
void change_i2c_speed( ATCAIface iface, uint32_t speed )
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	
	switch(bus)
	{
		case 0:
			//pmc_enable_periph_clk(ID_TWI0);
			//flexcom_enable(FLEXCOM0);
			//flexcom_set_opmode(FLEXCOM0, FLEXCOM_TWI);
			flexcom_enable(FLEX_Channel0);
			flexcom_set_opmode(FLEX_Channel0, FLEXCOM_TWI);
			
			opt_twi_master.master_clk = sysclk_get_cpu_hz();
			opt_twi_master.speed      = speed;
			opt_twi_master.smbus      = 0;
			//twi_master_init(TWI0, &opt_twi_master);
			twi_master_init(TWI_Channel0, &opt_twi_master);
			
			break;
		case 1:
			//pmc_enable_periph_clk(ID_TWI1);
			flexcom_enable(FLEX_Channel1);
			flexcom_set_opmode(FLEX_Channel1, FLEXCOM_TWI);
			
			opt_twi_master.master_clk = sysclk_get_cpu_hz();
			opt_twi_master.speed      = speed;
			opt_twi_master.smbus      = 0;
			twi_master_init(TWI_Channel1, &opt_twi_master);
			break;
	}
}
Пример #2
0
static void reconfigure_console(uint32_t ul_mck, uint32_t ul_baudrate)
{
	sam_usart_opt_t uart_serial_options;
	
	uart_serial_options.baudrate = ul_baudrate,
	uart_serial_options.char_length = CONF_UART_CHAR_LENGTH,
	uart_serial_options.parity_type = US_MR_PAR_NO;
	uart_serial_options.stop_bits = CONF_UART_STOP_BITS,
	uart_serial_options.channel_mode= US_MR_CHMODE_NORMAL,
	uart_serial_options.irda_filter = 0,

	/* Configure PMC */
	flexcom_enable(CONF_FLEXCOM);
	flexcom_set_opmode(CONF_FLEXCOM, FLEXCOM_USART);

	/* Configure PIO */
	pio_configure_pin_group(CONF_UART_PIO, CONF_PINS_UART,
			CONF_PINS_UART_FLAGS);

	/* Configure UART */
	usart_init_rs232(CONF_UART, &uart_serial_options, ul_mck);
	/* Enable the receiver and transmitter. */
	usart_enable_tx(CONF_UART);
	usart_enable_rx(CONF_UART);
}
Пример #3
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;
}
Пример #4
0
/**
 * \brief Application entry point for TWI Slave example.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint32_t i;

	/* Initialize the SAM system */
	sysclk_init();

#if (SAM4S || SAM4E)
	/* Select PB4 and PB5 function, this will cause JTAG discconnect */
	REG_CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
	REG_CCFG_SYSIO |= CCFG_SYSIO_SYSIO5;
#endif

	/* Initialize the board */
	board_init();

	/* Initialize the console UART */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);

#if (SAMG55)
	/* Enable the peripheral and set TWI mode. */
	flexcom_enable(BOARD_FLEXCOM_TWI);
	flexcom_set_opmode(BOARD_FLEXCOM_TWI, FLEXCOM_TWI);
#else
	/* Enable the peripheral clock for TWI */
	pmc_enable_periph_clk(BOARD_ID_TWI_SLAVE);
#endif

	for (i = 0; i < MEMORY_SIZE; i++) {
		emulate_driver.uc_memory[i] = 0;
	}
	emulate_driver.us_offset_memory = 0;
	emulate_driver.uc_acquire_address = 0;
	emulate_driver.us_page_address = 0;

	/* Configure TWI as slave */
	puts("-I- Configuring the TWI in slave mode\n\r");
	twi_slave_init(BOARD_BASE_TWI_SLAVE, SLAVE_ADDRESS);

	/* Clear receipt buffer */
	twi_read_byte(BOARD_BASE_TWI_SLAVE);

	/* Configure TWI interrupts */
	NVIC_DisableIRQ(BOARD_TWI_IRQn);
	NVIC_ClearPendingIRQ(BOARD_TWI_IRQn);
	NVIC_SetPriority(BOARD_TWI_IRQn, 0);
	NVIC_EnableIRQ(BOARD_TWI_IRQn);
	twi_enable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_SR_SVACC);

	while (1) {
	}
}
Пример #5
0
/** \brief Initialize the SPI in master mode.
 *
 * \param p_spi  Base address of the SPI instance.
 *
 */
void spi_master_init(Spi *p_spi)
{
#if SAMG55
    flexcom_enable(BOARD_FLEXCOM_SPI);
    flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI);
#else
    spi_enable_clock(p_spi);
#endif
    spi_reset(p_spi);
    spi_set_master_mode(p_spi);
    spi_disable_mode_fault_detect(p_spi);
    spi_disable_loopback(p_spi);
    spi_set_peripheral_chip_select_value(p_spi, DEFAULT_CHIP_ID);
    spi_set_fixed_peripheral_select(p_spi);
    spi_disable_peripheral_select_decode(p_spi);
    spi_set_delay_between_chip_select(p_spi, CONFIG_SPI_MASTER_DELAY_BCS);
}
Пример #6
0
/*! \brief Enable the USART system clock in SPI master mode.
 *
 * \param p_usart Pointer to Base address of the USART instance.
 *
 */
void usart_spi_init(Usart *p_usart)
{
#if (!SAMG55)

	uint8_t uc_id;

#ifdef USART0
	if (p_usart == USART0) {
		uc_id = ID_USART0;
	}
#endif

#ifdef USART1
	else if(p_usart == USART1) {
		uc_id = ID_USART1;
	}
#endif

#ifdef USART2
	else if(p_usart == USART2) {
		uc_id = ID_USART2;
	}
#endif

#ifdef USART3
	else if(p_usart == USART3) {
		uc_id = ID_USART3;
	}
#endif

#endif

#if SAM4L
	sysclk_enable_peripheral_clock(p_usart);
#elif SAMG55
	flexcom_enable(BOARD_FLEXCOM_USART);
	flexcom_set_opmode(BOARD_FLEXCOM_USART, FLEXCOM_USART);
#else
	sysclk_enable_peripheral_clock(uc_id);
#endif
}
Пример #7
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);
}
Пример #8
0
/**
 * \brief Configure USART in synchronous mode.
 *
 * \param ul_ismaster  1 for master, 0 for slave.
 * \param ul_baudrate  Baudrate for synchronous communication.
 *
 */
static void configure_usart(uint32_t ul_ismaster, uint32_t ul_baudrate)
{
	sam_usart_opt_t usart_console_settings = {
		0,
		US_MR_CHRL_8_BIT,
		US_MR_PAR_NO,
		US_MR_NBSTOP_1_BIT,
		US_MR_CHMODE_NORMAL,
		/* This field is only used in IrDA mode. */
		0
	};

	usart_console_settings.baudrate = ul_baudrate;

#if (SAMG55)
	/* Enable the peripheral and set USART mode. */
	flexcom_enable(BOARD_FLEXCOM);
	flexcom_set_opmode(BOARD_FLEXCOM, FLEXCOM_USART);
#else
	/* Enable the peripheral clock in the PMC. */
	sysclk_enable_peripheral_clock(BOARD_ID_USART);
#endif

	/* Configure USART in SYNC. master or slave mode. */
	if (ul_ismaster) {
		usart_init_sync_master(BOARD_USART, &usart_console_settings, sysclk_get_cpu_hz());
	} else {
		usart_init_sync_slave(BOARD_USART, &usart_console_settings);
	}

	/* Disable all the interrupts. */
	usart_disable_interrupt(BOARD_USART, ALL_INTERRUPT_MASK);
	
	/* Enable TX & RX function. */
	usart_enable_tx(BOARD_USART);
	usart_enable_rx(BOARD_USART);

	/* Configure and enable interrupt of USART. */
	NVIC_EnableIRQ(USART_IRQn);
}
Пример #9
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);
}
Пример #10
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;
}
Пример #11
0
/**
 * \ingroup freertos_twi_peripheral_control_group
 * \brief Initializes the FreeRTOS ASF TWI (I2C) master driver for the specified
 * TWI port.
 *
 * freertos_twi_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 TWI port.
 *
 * If freertos_driver_parameters->operation_mode equals TWI_I2C_MASTER then
 * freertos_twi_master_init() will configure the TWI port for master mode
 * operation and enable the peripheral.  If
 * freertos_driver_parameters->operation_mode equals any other value then
 * freertos_twi_master_init() will not take any action.
 *
 * Other ASF TWI functions can be called after freertos_twi_master_init() has
 * completed successfully.
 *
 * The FreeRTOS ASF driver both installs and handles the TWI 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_twi    The twi 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 TWI read and write functions is returned.  If
 *     the initialisation fails then NULL is returned.
 */
freertos_twi_if freertos_twi_master_init(Twi *p_twi,
		const freertos_peripheral_options_t *const freertos_driver_parameters)
{
	portBASE_TYPE twi_index;
	bool is_valid_operating_mode;
	freertos_twi_if return_value;
	const enum peripheral_operation_mode valid_operating_modes[] = {TWI_I2C_MASTER};

	/* Find the index into the all_twi_definitions array that holds details of
	the p_twi peripheral. */
	twi_index = get_pdc_peripheral_details(all_twi_definitions, MAX_TWIS,
			(void *) p_twi);

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

		/* Enable the peripheral's clock. */
#if (SAMG55)
		/* Enable the peripheral and set TWI mode. */
		uint32_t temp = (uint32_t)(all_twi_definitions[twi_index].peripheral_base_address - 0x600);
		Flexcom *p_flexcom = (Flexcom *)temp;
		flexcom_enable(p_flexcom);
		flexcom_set_opmode(p_flexcom, FLEXCOM_TWI);
#else
		pmc_enable_periph_clk(
				all_twi_definitions[twi_index].peripheral_id);
#endif
		/* Ensure everything is disabled before configuration. */
		pdc_disable_transfer(
				all_twi_definitions[twi_index].pdc_base_address,
				(PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS));
		twi_disable_interrupt(
				all_twi_definitions[twi_index].peripheral_base_address,
				MASK_ALL_INTERRUPTS);
		twi_reset(
				all_twi_definitions[twi_index].peripheral_base_address);

		switch (freertos_driver_parameters->operation_mode) {
		case TWI_I2C_MASTER:
			/* Call the standard ASF init function. */
			twi_enable_master_mode(
					all_twi_definitions[twi_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[twi_index]),
				&(rx_dma_control[twi_index]));

		/* Error interrupts are always enabled. */
		twi_enable_interrupt(
				all_twi_definitions[twi_index].peripheral_base_address,
				IER_ERROR_INTERRUPTS);

		/* Configure and enable the TWI interrupt in the interrupt controller. */
		configure_interrupt_controller(
				all_twi_definitions[twi_index].peripheral_irq,
				freertos_driver_parameters->interrupt_priority);

		return_value = (freertos_twi_if) p_twi;
	} else {
		return_value = NULL;
	}

	return return_value;
}
Пример #12
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;
}
Пример #13
0
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    int clockid = NC, flexcom = NC;

    /*To determine the uart peripheral associated with pins*/
    UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
    UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
    UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);

    MBED_ASSERT(uart != (UARTName)NC);

    if (g_sys_init == 0) {
        sysclk_init();
        system_board_init();
        g_sys_init = 1;
    }
    pUSART_S(obj) = uart;
    pSERIAL_S(obj)->uart_serial_options.baudrate = (9600UL);
    pSERIAL_S(obj)->uart_serial_options.charlength = US_MR_CHRL_8_BIT;
    pSERIAL_S(obj)->uart_serial_options.paritytype = US_MR_PAR_NO;
    pSERIAL_S(obj)->uart_serial_options.stopbits = US_MR_NBSTOP_1_BIT;
    pSERIAL_S(obj)->actrec = false;
    pSERIAL_S(obj)->acttra = false;

    /* Configure UART pins */
    if(tx != NC) {
        pin_function(tx, pinmap_find_function(tx, PinMap_UART_TX));
        ioport_disable_pin(tx);
    }
    if(rx != NC) {
        pin_function(rx, pinmap_find_function(rx, PinMap_UART_RX));
        ioport_disable_pin(rx);
    }
    clockid = get_usart_clock_id(uart);
    if (clockid != NC) {
        sysclk_enable_peripheral_clock(clockid);
    }

    flexcom = (int)get_flexcom_id(uart);
#if (!SAM4L)
#if (SAMG55)
    /* Configure flexcom for usart */
    flexcom_enable((Flexcom* )flexcom);
    flexcom_set_opmode((Flexcom* )flexcom, FLEXCOM_USART);
#else
    sysclk_enable_peripheral_clock(clockid);
#endif
    /* Configure USART */
    usart_init_rs232((Usart*)uart, (sam_usart_opt_t*)&(pSERIAL_S(obj)->uart_serial_options),
                     sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
    sysclk_enable_peripheral_clock(clockid);
    /* Configure USART */
    usart_init_rs232((Usart*)uart,  (sam_usart_opt_t*)&(pSERIAL_S(obj)->uart_serial_options, sysclk_get_peripheral_bus_hz((Usart*)uart));
#endif
                     /* Disable rx and tx in case 1 line only required to be configured for usart */
                     usart_disable_tx((Usart*)uart);
                     usart_disable_rx((Usart*)uart);
                     /* Enable the receiver and transmitter. */
    if(tx != NC) {
    usart_enable_tx((Usart*)uart);
    }
    if(rx != NC) {
    usart_enable_rx((Usart*)uart);
    }

    if(uart == STDIO_UART) {
    stdio_uart_inited = 1;
    memcpy(&stdio_uart, obj, sizeof(serial_t));
    }
}
Пример #14
0
/**
 * \ingroup freertos_usart_peripheral_control_group
 * \brief Initializes the FreeRTOS ASF USART driver for the specified USART
 * port.
 *
 * freertos_usart_serial_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 USART port.
 *
 * If freertos_driver_parameters->operation_mode equals USART_RS232 then
 * freertos_usart_serial_init() will configure the USART port for standard RS232
 * operation.  If freertos_driver_parameters->operation_mode equals any other
 * value then freertos_usart_serial_init() will not take any action.
 *
 * Other ASF USART functions can be called after freertos_usart_serial_init()
 * has completed successfully.
 *
 * The FreeRTOS ASF driver both installs and handles the USART 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_usart    The USART peripheral being initialized.
 * \param uart_parameters    Structure that defines the USART bus and transfer
 *     parameters, such the baud rate and the number of data bits.
 *     sam_usart_opt_t is a standard ASF type (it is not FreeRTOS specific).
 * \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 USART read and write functions is returned.  If
 *     the initialisation fails then NULL is returned.
 */
freertos_usart_if freertos_usart_serial_init(Usart *p_usart,
		const sam_usart_opt_t *const uart_parameters,
		const freertos_peripheral_options_t *const freertos_driver_parameters)
{
	portBASE_TYPE usart_index;
	bool is_valid_operating_mode;
	freertos_usart_if return_value;
	const enum peripheral_operation_mode valid_operating_modes[] = {USART_RS232};

	/* Find the index into the all_usart_definitions array that holds details of
	the p_usart peripheral. */
	usart_index = get_pdc_peripheral_details(all_usart_definitions,
			MAX_USARTS,
			(void *) p_usart);

	/* 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_usart pointer was used, and a valid
	operating mode was requested. */
	if ((usart_index < MAX_USARTS) && (is_valid_operating_mode == true)) {
		/* This function must be called exactly once per supported USART.  Check it
		has not been called	before. */
		configASSERT(rx_buffer_definitions[usart_index].next_byte_to_read == NULL);

		/* Disable everything before enabling the clock. */
		usart_disable_tx(p_usart);
		usart_disable_rx(p_usart);
		pdc_disable_transfer(all_usart_definitions[usart_index].pdc_base_address,
				(PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS));

#if (SAMG55)
		/* Enable the peripheral and set USART mode. */
		uint32_t temp = (uint32_t)all_usart_definitions[usart_index].peripheral_base_address - 0x200;
		Flexcom *p_flexcom = (Flexcom *)temp;
		flexcom_enable(p_flexcom);
		flexcom_set_opmode(p_flexcom, FLEXCOM_USART);
#else
		/* Enable the peripheral clock in the PMC. */
		pmc_enable_periph_clk(
				all_usart_definitions[usart_index].peripheral_id);
#endif

		switch (freertos_driver_parameters->operation_mode) {
		case USART_RS232:
			/* Call the standard ASF init function. */
			usart_init_rs232(p_usart, uart_parameters,
					sysclk_get_cpu_hz());
			break;

		default:
			/* Other modes are not currently supported. */
			break;
		}

		/* Disable all the interrupts. */
		usart_disable_interrupt(p_usart, MASK_ALL_INTERRUPTS);

		/* Create any required peripheral access mutexes and transaction complete
		semaphores.  This peripheral is full duplex so only the Tx semaphores
		are created in the following function.  The the Rx semaphores are
		created	separately. */
		create_peripheral_control_semaphores(
				freertos_driver_parameters->options_flags,
				&(tx_dma_control[usart_index]),
				NULL /* The rx structures are not created in this function. */);

		/* Is the driver also going to receive? */
		if (freertos_driver_parameters->receive_buffer != NULL) {
			/* rx_event_semaphore is used to signal the arival of new data.  It
			must be a counting semaphore for the following reason:  If the Rx
			DMA places data at the end of its circular buffer it will give the
			semaphore to indicate the presence of unread data.  If it then
			receives more data, it will write this to the start of the circular
			buffer, then give the semaphore again.  Now, if a task reads data
			out of the same circular buffer, and requests less data than is
			available, but more than is available between the next read pointer
			and the end of the buffer, the actual amount returned will be
			capped to that available up to the end of the buffer only.  If this
			semaphore was a binary semaphore, it would then be 'taken' even
			though, unknown to the reading task, unread and therefore available
			data remained at the beginning of the buffer. */
			rx_buffer_definitions[usart_index].rx_event_semaphore =
					xSemaphoreCreateCounting(portMAX_DELAY, 0);
			configASSERT(rx_buffer_definitions[usart_index].rx_event_semaphore);

			/* Set the timeout to 5ms, then start waiting for a character (the
			timeout is not started until characters have started to	be
			received). */
			usart_set_rx_timeout(p_usart,
					(uart_parameters->baudrate / BITS_PER_5_MS));
			usart_start_rx_timeout(p_usart);

			/* The receive buffer is currently empty, so the DMA has control
			over the entire buffer. */
			rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_addr =
					(uint32_t)freertos_driver_parameters->receive_buffer;
			rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_size =
					freertos_driver_parameters->receive_buffer_size;
			pdc_rx_init(
					all_usart_definitions[usart_index].pdc_base_address,
					&(rx_buffer_definitions[usart_index].rx_pdc_parameters),
					NULL);

			/* Set the next byte to read to the start of the buffer as no data
			has yet been read. */
			rx_buffer_definitions[usart_index].next_byte_to_read =
					freertos_driver_parameters->receive_buffer;

			/* Remember the limits of entire buffer. */
			rx_buffer_definitions[usart_index].rx_buffer_start_address =
					rx_buffer_definitions[usart_index].rx_pdc_parameters.ul_addr;
			rx_buffer_definitions[usart_index].past_rx_buffer_end_address =
					rx_buffer_definitions[usart_index].rx_buffer_start_address +
					freertos_driver_parameters->receive_buffer_size;

			/* If the rx driver is to be thread aware, create an access control
			mutex. */
			if ((freertos_driver_parameters->options_flags &
					USE_RX_ACCESS_MUTEX) != 0) {
				rx_buffer_definitions[usart_index].rx_access_mutex =
					xSemaphoreCreateMutex();
				configASSERT(rx_buffer_definitions[usart_index].rx_access_mutex);
			}

			/* Catch the DMA running out of Rx space, and gaps in the
			reception.  These events are both used to signal that there is
			data available in the Rx buffer. */
			usart_enable_interrupt(p_usart, US_IER_ENDRX | US_IER_TIMEOUT);

			/* The Rx DMA is running all the time, so enable it now. */
			pdc_enable_transfer(
					all_usart_definitions[usart_index].pdc_base_address,
					PERIPH_PTCR_RXTEN);
		} else {
			/* next_byte_to_read is used to check to see if this function
			has been called before, so it must be set to something, even if
			it is not going to be used.  The value it is set to is not
			important, provided it is not zero (NULL). */
			rx_buffer_definitions[usart_index].next_byte_to_read = RX_NOT_USED;
		}

		/* Configure and enable the USART interrupt in the interrupt controller. */
		configure_interrupt_controller(all_usart_definitions[usart_index].peripheral_irq,
				freertos_driver_parameters->interrupt_priority);

		/* Error interrupts are always enabled. */
		usart_enable_interrupt(
				all_usart_definitions[usart_index].peripheral_base_address,
				IER_ERROR_INTERRUPTS);

		/* Finally, enable the receiver and transmitter. */
		usart_enable_tx(p_usart);
		usart_enable_rx(p_usart);

		return_value = (freertos_usart_if) p_usart;
	} else {
		return_value = NULL;
	}

	return return_value;
}
Пример #15
0
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
{
    pdc_packet_t      pdc_uart_packet, pdc_uart_tx_packet;
    OSStatus          err = kNoErr;
    sam_usart_opt_t   settings;
    bool              hardware_shaking = false;

    platform_mcu_powersave_disable();

    require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
    require_action_quiet( (optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0), exit, err = kUnsupportedErr);

    driver->rx_size              = 0;
    driver->tx_size              = 0;
    driver->rx_ring_buffer       = optional_ring_buffer;
    driver->last_transmit_result = kNoErr;
    driver->last_receive_result  = kNoErr;
    driver->peripheral           = (platform_uart_t*)peripheral;
#ifndef NO_MICO_RTOS
    mico_rtos_init_semaphore( &driver->tx_complete, 1 );
    mico_rtos_init_semaphore( &driver->rx_complete, 1 );
    mico_rtos_init_semaphore( &driver->sem_wakeup,  1 );
    mico_rtos_init_mutex    ( &driver->tx_mutex );
#else
    driver->tx_complete = false;
    driver->rx_complete = false;
#endif

    /* Set Tx and Rx pin mode to UART peripheral */
    platform_gpio_peripheral_pin_init( peripheral->tx_pin, ( peripheral->tx_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    platform_gpio_peripheral_pin_init( peripheral->rx_pin, ( peripheral->rx_pin_mux_mode | IOPORT_MODE_PULLUP ) );

    /* Init CTS and RTS pins (if available) */
    if ( peripheral->cts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
    {
        hardware_shaking = true;
        platform_gpio_peripheral_pin_init( peripheral->cts_pin, ( peripheral->cts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    }

    if ( peripheral->rts_pin != NULL && (config->flow_control == FLOW_CONTROL_CTS || config->flow_control == FLOW_CONTROL_CTS_RTS) )
    {
        hardware_shaking = true;
        platform_gpio_peripheral_pin_init( peripheral->rts_pin, ( peripheral->rts_pin_mux_mode | IOPORT_MODE_PULLUP ) );
    }

    /* Enable the clock. */
    if( pmc_is_periph_clk_enabled( peripheral->peripheral_id ) == 0  ) {
        flexcom_enable( peripheral->flexcom_base );
    }
    flexcom_set_opmode( peripheral->flexcom_base, FLEXCOM_USART );

    /* Enable the receiver and transmitter. */
    usart_reset_tx( peripheral->port );
    usart_reset_rx( peripheral->port );

    /* Disable all the interrupts. */
    usart_disable_interrupt( peripheral->port, 0xffffffff );

    switch ( config->parity ) {
    case NO_PARITY:
        settings.parity_type = US_MR_PAR_NO;
        break;
    case EVEN_PARITY:
        settings.parity_type = US_MR_PAR_EVEN;
        break;
    case ODD_PARITY:
        settings.parity_type = US_MR_PAR_ODD;
        break;
    default:
        err = kParamErr;
        goto exit;
    }
    switch ( config->data_width) {
    case DATA_WIDTH_5BIT:
        settings.char_length = US_MR_CHRL_5_BIT;
        break;
    case DATA_WIDTH_6BIT:
        settings.char_length = US_MR_CHRL_6_BIT;
        break;
    case DATA_WIDTH_7BIT:
        settings.char_length = US_MR_CHRL_7_BIT;
        break;
    case DATA_WIDTH_8BIT:
        settings.char_length = US_MR_CHRL_8_BIT;
        break;
    case DATA_WIDTH_9BIT:
        settings.char_length = US_MR_MODE9;
        break;
    default:
        err = kParamErr;
        goto exit;
    }
    settings.baudrate = config->baud_rate;
    settings.stop_bits = ( config->stop_bits == STOP_BITS_1 ) ? US_MR_NBSTOP_1_BIT : US_MR_NBSTOP_2_BIT;
    settings.channel_mode= US_MR_CHMODE_NORMAL;

    /* Configure USART in serial mode. */
    if (!hardware_shaking) {
        usart_init_rs232( peripheral->port, &settings, sysclk_get_peripheral_hz());
    } else {
        usart_init_hw_handshaking( peripheral->port, &settings, sysclk_get_peripheral_hz());
    }

    /* Enable uart interrupt */
    NVIC_SetPriority( platform_flexcom_irq_numbers[peripheral->uart_id], 0x06 );
    NVIC_EnableIRQ( platform_flexcom_irq_numbers[peripheral->uart_id] );

    /* Enable PDC transmit */
    pdc_enable_transfer( usart_get_pdc_base( peripheral->port ), PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN );
    pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->port ), PERIPH_PTCR_TXTDIS );

    pdc_uart_packet.ul_addr = (uint32_t)driver->rx_ring_buffer->buffer;
    pdc_uart_packet.ul_size = (uint32_t)driver->rx_ring_buffer->size;
    pdc_rx_init( usart_get_pdc_base( peripheral->port ), &pdc_uart_packet, &pdc_uart_packet );

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

    pdc_tx_init( usart_get_pdc_base( driver->peripheral->port ), &pdc_uart_tx_packet, NULL );

    usart_enable_interrupt( peripheral->port, US_IER_ENDRX | US_IER_RXBUFF | US_IER_RXRDY | US_IER_ENDTX );

    /* Enable the receiver and transmitter. */
    usart_enable_tx( peripheral->port );
    usart_enable_rx( peripheral->port );

exit:
    platform_mcu_powersave_enable( );
    return err;
}
Пример #16
0
/** \brief initialize an I2C interface using given config
 * \param[in] hal - opaque ptr to HAL data
 * \param[in] cfg - interface configuration
 */
ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg)
{
	int bus = cfg->atcai2c.bus;	// 0-based logical bus number
	ATCAHAL_t *phal = (ATCAHAL_t *)hal;
	
	if (i2c_bus_ref_ct == 0)	// power up state, no i2c buses will have been used
	{
		for(int i = 0; i < MAX_I2C_BUSES; i++)
		{
			i2c_hal_data[i] = NULL;
		}
	}
	
	i2c_bus_ref_ct++;	// total across buses
	
	if (bus >= 0 && bus < MAX_I2C_BUSES)
	{
		// if this is the first time this bus and interface has been created, do the physical work of enabling it
		if (i2c_hal_data[bus] == NULL)
		{
			i2c_hal_data[bus] = malloc(sizeof(ATCAI2CMaster_t));
			i2c_hal_data[bus]->ref_ct = 1;	// buses are shared, this is the first instance
			
			switch(bus)
			{
				/*
				case 0: pmc_enable_periph_clk(ID_TWI0); break;				
				case 1: pmc_enable_periph_clk(ID_TWI1); break;
				*/
				case 0:
					//flexcom_enable(FLEXCOM0);
					//flexcom_set_opmode(FLEXCOM0, FLEXCOM_TWI);
					flexcom_enable(FLEX_Channel0);
					flexcom_set_opmode(FLEX_Channel0, FLEXCOM_TWI);
					break;
					
				case 1:
					flexcom_enable(FLEX_Channel1);
					flexcom_set_opmode(FLEX_Channel1, FLEXCOM_TWI);
					break;
			}
			
			opt_twi_master.master_clk = sysclk_get_cpu_hz();
			opt_twi_master.speed = cfg->atcai2c.baud;
			opt_twi_master.smbus = 0;
			
			switch(bus)
			{
				case 0: twi_master_init(TWI_Channel0, &opt_twi_master);break;
				case 1: twi_master_init(TWI_Channel1, &opt_twi_master);break;
			}
			
			// store this for use during the release phase
			i2c_hal_data[bus]->bus_index = bus;
		}
		else
		{
			// otherwise, another interface already initialized the bus, so this interface will share it and any different
			// cfg parameters will be ignored...first one to initialize this sets the configuration
			i2c_hal_data[bus]->ref_ct++;
		}
		
		phal->hal_data = i2c_hal_data[bus];
		
		return ATCA_SUCCESS;
	}
	
	return ATCA_COMM_FAIL;
}