示例#1
0
static void twim_init(void)
{
	uint8_t status;
	const gpio_map_t TWIM_GPIO_MAP = {
		(AVR32_TWIMS0_TWCK_0_0_PIN, AVR32_TWIMS0_TWCK_0_0_FUNCTION,AVR32_TWIMS0_TWD_0_0_PIN, AVR32_TWIMS0_TWD_0_0_FUNCTION)
	};

	gpio_enable_module(TWIM_GPIO_MAP, sizeof(TWIM_GPIO_MAP)/sizeof(TWIM_GPIO_MAP[0]));
	status = twim_master_init(TWIM, &twi_opt_GYRO);	
	
	twim_set_speed (TWIM, TWI_STD_MODE_SPEED, FPBA_HZ);
}
示例#2
0
文件: twim.c 项目: AndreyMostovov/asf
/**
 * \brief Initialize the TWIM module
 *
 * \param twim         Base address of the TWIM
 * \param config       Options for initializing the TWIM module
 *
 * \retval STATUS_OK        Transaction is successful
 * \retval ERR_INVALID_ARG  Invalid arg resulting in wrong CWGR Exponential
 */
status_code_t twim_set_config(Twim *twim, struct twim_config *config)
{
	sysclk_enable_peripheral_clock(twim);
	/* Enable master transfer */
	twim->TWIM_CR = TWIM_CR_MEN;
	/* Reset TWI */
	twim->TWIM_CR = TWIM_CR_SWRST;
	/* Clear SR */
	twim->TWIM_SCR = ~0UL;

	if (config->smbus) {
		/* Enable SMBUS Transfer */
		twim->TWIM_CR = TWIM_CR_SMEN;
		twim->TWIM_SMBTR = (uint32_t) -1;
	}

	/* Select the speed */
	if (config->speed) {
		if (twim_set_speed(twim, config->speed, config->twim_clk,
				config->data_setup_cycles) != STATUS_OK) {
			return ERR_INVALID_ARG;
		}
	}
	if (config->hsmode_speed) {
		if (twim_set_hsmode_speed(twim, config->hsmode_speed, config->twim_clk,
				config->hsmode_data_setup_cycles) != STATUS_OK) {
			return ERR_INVALID_ARG;
		}
	}

	/* Set clock and data slew rate */
	twim->TWIM_SRR = ((config->speed < TWI_FAST_MODE_PLUS_SPEED) ?
			TWIM_SRR_FILTER(2) : TWIM_SRR_FILTER(3))
			| TWIM_SRR_CLSLEW(config->clock_slew_limit)
			| TWIM_SRR_CLDRIVEL(config->clock_drive_strength_low)
			| TWIM_SRR_DASLEW(config->data_slew_limit)
			| TWIM_SRR_DADRIVEL(config->data_drive_strength_low);
	twim->TWIM_HSSRR = TWIM_HSSRR_FILTER(1)
			| TWIM_HSSRR_CLSLEW(config->hs_clock_slew_limit)
			| TWIM_HSSRR_CLDRIVEL(config->hs_clock_drive_strength_low)
			| TWIM_HSSRR_CLDRIVEH(config->hs_clock_drive_strength_high)
			| TWIM_HSSRR_DASLEW(config->hs_data_slew_limit)
			| TWIM_HSSRR_DADRIVEL(config->hs_data_drive_strength_low);

#if TWIM_LOW_POWER_ENABLE
	sleepmgr_init();
#endif

	return STATUS_OK;
}
示例#3
0
/**
 * \brief Initialize the twi master module
 *
 * \param twim              Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param *opt              Options for initializing the twim module
 *                          (see \ref twim_options_t)
 * \retval STATUS_OK        Transaction is successful
 * \retval ERR_INVALID_ARG  Invalid arg resulting in wrong CWGR Exponential
 * \retval ERR_IO_ERROR     NACK is received or Bus Arbitration lost
 */
status_code_t twim_master_init (volatile avr32_twim_t *twim,
		const twim_options_t *opt)
{
	bool global_interrupt_enabled = cpu_irq_is_enabled ();
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	// Disable TWI interrupts
	if (global_interrupt_enabled) {
		cpu_irq_disable ();
	}
	twim->idr = ~0UL;
	// Enable master transfer
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	// Reset TWI
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	if (global_interrupt_enabled) {
		cpu_irq_enable ();
	}
	// Clear SR
	twim->scr = ~0UL;

	// register Register twim_master_interrupt_handler interrupt on level CONF_TWIM_IRQ_LEVEL
	irqflags_t flags = cpu_irq_save();
	irq_register_handler(twim_master_interrupt_handler,
			CONF_TWIM_IRQ_LINE, CONF_TWIM_IRQ_LEVEL);
	cpu_irq_restore(flags);
/*
	if (opt->smbus) {
		// Enable SMBUS Transfer
		twim->cr = AVR32_TWIM_CR_SMEN_MASK;
		twim->smbtr = (uint32_t) -1;
	}
*/
	// Select the speed
	if (twim_set_speed (twim, opt->speed, opt->pba_hz) ==
			ERR_INVALID_ARG) {
		return ERR_INVALID_ARG;
	}
	// Probe the component
	twim_probe (twim, opt->chip);
	//Check for nack and abitration
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
示例#4
0
void i2c_driver_init(uint8_t  i2c_device) 
{
	volatile avr32_twim_t *twim;
	switch (i2c_device) {
	case I2C0: 
		twim = &AVR32_TWIM0;
		///< Register PDCA IRQ interrupt.
		INTC_register_interrupt( (__int_handler) &i2c_int_handler_i2c0, AVR32_TWIM0_IRQ, AVR32_INTC_INT1);
		gpio_enable_module_pin(AVR32_TWIMS0_TWCK_0_0_PIN, AVR32_TWIMS0_TWCK_0_0_FUNCTION);
		gpio_enable_module_pin(AVR32_TWIMS0_TWD_0_0_PIN, AVR32_TWIMS0_TWD_0_0_FUNCTION);

	break;
	case I2C1:
		twim = &AVR32_TWIM1;///< Register PDCA IRQ interrupt.
		//INTC_register_interrupt( (__int_handler) &i2c_int_handler_i2c1, AVR32_TWIM1_IRQ, AVR32_INTC_INT1);
		gpio_enable_module_pin(AVR32_TWIMS1_TWCK_0_0_PIN, AVR32_TWIMS1_TWCK_0_0_FUNCTION);
		gpio_enable_module_pin(AVR32_TWIMS1_TWD_0_0_PIN, AVR32_TWIMS1_TWD_0_0_FUNCTION);
	break;
	default: ///< invalid device ID
		return;
	}		
	
	static twim_options_t twi_opt=
	{
		.pba_hz = 64000000,
		.speed = 400000,
		.chip = 0xff,
		.smbus = false
	};
	
	twi_opt.pba_hz = sysclk_get_pba_hz();
	
	status_code_t ret_twim_init = twim_master_init(twim, &twi_opt);
	
	print_util_dbg_print("\r\n");
	
	switch(ret_twim_init)
	{
		case ERR_IO_ERROR :
			print_util_dbg_print("NO Twim probe here \r\n");
		case STATUS_OK :
			print_util_dbg_print("I2C initialised \r\n");
			break;
		default :
			print_util_dbg_print("Error initialising I2C \r\n");
			break;
	}
}

int8_t  i2c_driver_reset(uint8_t  i2c_device) 
{
	volatile avr32_twim_t *twim;
	switch (i2c_device) 
	{
		case 0: 
			twim = &AVR32_TWIM0;
		break;
		case 1:
			twim = &AVR32_TWIM1;
		break;
		default: ///< invalid device ID
			return -1;
	}		
	bool global_interrupt_enabled = cpu_irq_is_enabled ();
	///< Disable TWI interrupts
	if (global_interrupt_enabled) 
	{
		cpu_irq_disable ();
	}
	twim->idr = ~0UL;
	///< Enable master transfer
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	///< Reset TWI
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	if (global_interrupt_enabled) 
	{
		cpu_irq_enable ();
	}
	///< Clear SR
	twim->scr = ~0UL;
	
	return STATUS_OK; //No error
}

int8_t  i2c_driver_trigger_request(uint8_t  i2c_device, i2c_packet_t *transfer) 
{
	///< initiate transfer of given request
	///< set up DMA channel
	volatile avr32_twim_t *twim;
	bool global_interrupt_enabled = cpu_irq_is_enabled ();
	
	if (global_interrupt_enabled) 
	{
		cpu_irq_disable ();
	}
	
	switch (i2c_device) 
	{
		case 0: 
			twim = &AVR32_TWIM0;
			twim->cr = AVR32_TWIM_CR_MEN_MASK;
			twim->cr = AVR32_TWIM_CR_SWRST_MASK;
			twim->cr = AVR32_TWIM_CR_MDIS_MASK;
			twim->scr = ~0UL;
			// Clear the interrupt flags
			twim->idr = ~0UL;
			if (twim_set_speed(twim, transfer->i2c_speed, sysclk_get_pba_hz()) == ERR_INVALID_ARG) 
			{
				return ERR_INVALID_ARG;
			}
		
			//pdca_load_channel(TWI0_DMA_CH, (void *)schedule[i2c_device][schedule_slot].config.write_data, schedule[i2c_device][schedule_slot].config.write_count);
			///< Enable pdca interrupt each time the reload counter reaches zero, i.e. each time
			///< the whole block was received
		
			//pdca_enable_interrupt_transfer_error(TWI0_DMA_CH);		
			break;
		case 1:
			twim = &AVR32_TWIM1;
			twim->cr = AVR32_TWIM_CR_MEN_MASK;
			twim->cr = AVR32_TWIM_CR_SWRST_MASK;
			twim->cr = AVR32_TWIM_CR_MDIS_MASK;
			twim->scr = ~0UL;
			///< Clear the interrupt flags
			twim->idr = ~0UL;
			if (twim_set_speed(twim, transfer->i2c_speed, sysclk_get_pba_hz()) == ERR_INVALID_ARG) 
			{
				return ERR_INVALID_ARG;
			}
			break;
		default: ///< invalid device ID
			return -1;
	}		

	///< set up I2C speed and mode
	//twim_set_speed(twim, 100000, sysclk_get_pba_hz());
    
	switch (1/*conf->direction*/)  
	{
		case I2C_READ:
 			twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
 						| (transfer->data_size << AVR32_TWIM_CMDR_NBYTES_OFFSET)
 						| (AVR32_TWIM_CMDR_VALID_MASK)
 						| (AVR32_TWIM_CMDR_START_MASK)
 						| (AVR32_TWIM_CMDR_STOP_MASK)
 						| (AVR32_TWIM_CMDR_READ_MASK);
			twim->ncmdr = 0;					
			twim->ier = AVR32_TWIM_IER_STD_MASK |  AVR32_TWIM_IER_RXRDY_MASK;
			break;	
		case I2C_WRITE1_THEN_READ:
			///< set up next command register for the burst read transfer
			///< set up command register to initiate the write transfer. The DMA will take care of the reading once this is done.
 			twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
 						| ((1)<< AVR32_TWIM_CMDR_NBYTES_OFFSET)
 						| (AVR32_TWIM_CMDR_VALID_MASK)
 						| (AVR32_TWIM_CMDR_START_MASK)
 						//| (AVR32_TWIM_CMDR_STOP_MASK)
 						| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
 						;	 
 			twim->ncmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
 						| ((transfer->data_size) << AVR32_TWIM_CMDR_NBYTES_OFFSET)
 						| (AVR32_TWIM_CMDR_VALID_MASK)
 						| (AVR32_TWIM_CMDR_START_MASK)
 						| (AVR32_TWIM_CMDR_STOP_MASK)
 						| (AVR32_TWIM_CMDR_READ_MASK);
			twim->ier = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_RXRDY_MASK | AVR32_TWIM_IER_TXRDY_MASK;
			///< set up writing of one byte (usually a slave register index)
			twim->cr = AVR32_TWIM_CR_MEN_MASK;
			twim->thr = transfer->write_then_read_preamble;
			twim->cr = AVR32_TWIM_CR_MEN_MASK;
			break;	
		case I2C_WRITE:
 			twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
 						| ((transfer->data_size) << AVR32_TWIM_CMDR_NBYTES_OFFSET)
 						| (AVR32_TWIM_CMDR_VALID_MASK)
 						| (AVR32_TWIM_CMDR_START_MASK)
 						| (AVR32_TWIM_CMDR_STOP_MASK);
			twim->ncmdr = 0;						;	
			twim->ier = AVR32_TWIM_IER_NAK_MASK |  AVR32_TWIM_IER_TXRDY_MASK;
		break;	
	}
			
	///< start transfer
	current_transfer = transfer;
	current_transfer->transfer_in_progress = 1;
	current_transfer->data_index = 0;
	
	if (global_interrupt_enabled) 
	{
		cpu_irq_enable ();
	}	
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	
	return STATUS_OK;
}
示例#5
0
int32_t i2c_driver_init(uint8_t  i2c_device) 
{
	int32_t i;
	volatile avr32_twim_t *twim;
	
	switch (i2c_device) 
	{
		case 0: 
			twim = &AVR32_TWIM0;
			// Register PDCA IRQ interrupt.
			INTC_register_interrupt( (__int_handler) &pdca_int_handler_i2c0, TWI0_DMA_IRQ, AVR32_INTC_INT0);
			gpio_enable_module_pin(AVR32_TWIMS0_TWCK_0_0_PIN, AVR32_TWIMS0_TWCK_0_0_FUNCTION);
			gpio_enable_module_pin(AVR32_TWIMS0_TWD_0_0_PIN, AVR32_TWIMS0_TWD_0_0_FUNCTION);
		break;
		
		case 1:
			twim = &AVR32_TWIM1;// Register PDCA IRQ interrupt.
			INTC_register_interrupt( (__int_handler) &pdca_int_handler_i2c0, TWI1_DMA_IRQ, AVR32_INTC_INT0);
			gpio_enable_module_pin(AVR32_TWIMS1_TWCK_0_0_PIN, AVR32_TWIMS1_TWCK_0_0_FUNCTION);
			gpio_enable_module_pin(AVR32_TWIMS1_TWD_0_0_PIN, AVR32_TWIMS1_TWD_0_0_FUNCTION);
			gpio_enable_pin_pull_up(AVR32_TWIMS1_TWCK_0_0_PIN);
			gpio_enable_pin_pull_up(AVR32_TWIMS1_TWD_0_0_PIN);
		break;
		
		default: // invalid device ID
			return -1;
	}		
	for (i = 0; i < I2C_SCHEDULE_SLOTS; i++) 
	{
		schedule[i2c_device][i].active = -1;
	}
				
	bool global_interrupt_enabled = cpu_irq_is_enabled ();
	// Disable TWI interrupts
	if (global_interrupt_enabled) 
	{
		cpu_irq_disable ();
	}
	twim->idr = ~0UL;
	// Enable master transfer
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	// Reset TWI
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	
	if (global_interrupt_enabled) 
	{
		cpu_irq_enable ();
	}
	// Clear SR
	twim->scr = ~0UL;
	
	// register Register twim_master_interrupt_handler interrupt on level CONF_TWIM_IRQ_LEVEL
//	irqflags_t flags = cpu_irq_save();
//	irq_register_handler(twim_master_interrupt_handler,
//			CONF_TWIM_IRQ_LINE, CONF_TWIM_IRQ_LEVEL);
//	cpu_irq_restore(flags);
	
	// Select the speed
	if (twim_set_speed(twim, 100000, sysclk_get_pba_hz()) == 
			ERR_INVALID_ARG) 
	{	
		return ERR_INVALID_ARG;
	}
	return STATUS_OK;
}