Ejemplo n.º 1
0
/**
 ** PDCA Init.
 **/
void init_pdca(void)
{
  // PDCA channel 0/1 options
  static const pdca_channel_options_t PDCA_CH_OPTIONS =
  {
    .addr = (void *)aDataTransfered,          // memory address
    .pid = AVR32_PDCA_PID_USART2_TX,          // select peripheral - data are transmit on USART TX line.
    .size = 0,                                // transfer counter
    .r_addr = (void *)aDataTransfered,        // next memory address
    .r_size = sizeof(aDataTransfered),        // next transfer counter
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE, // select size of one data packet
    .etrig = true                          // Trigger transfer on event.
  };

  Disable_global_interrupt();

  // Initialize interrupt vectors.
  INTC_init_interrupts();

  // Register the PDCA interrupt handler to the interrupt controller.
  INTC_register_interrupt(&pdca_int_handler, PDCA_CHANNEL_IRQ, AVR32_INTC_INT0);

  Enable_global_interrupt();

  // Init PDCA channel with the pdca_options.
  pdca_init_channel(PDCA_CHANNEL_USART, &PDCA_CH_OPTIONS);
  pdca_channel = pdca_get_handler(PDCA_CHANNEL_USART); // For use in the pdca interrupt handler.

  // Enable pdca transfer error interrupt & transfer complete interrupt.
  pdca_enable_interrupt_transfer_error(PDCA_CHANNEL_USART);
  pdca_enable_interrupt_transfer_complete(PDCA_CHANNEL_USART);

  // Enable the PEVC channel "PDCA CHANNEL 0/1 ONE-ITEM-TRANSFER"
  PEVC_CHANNELS_ENABLE(ppevc, 1<<PEVC_PDCA_SOT_USER);

  // Enable the PDCA.
  pdca_enable(PDCA_CHANNEL_USART);
}

/**
 ** AST Init.
 **/
void init_ast(void)
{

  avr32_ast_pir0_t pir = {
    .insel = 14 // Set a event every second
  };

  ast_calendar_t ast_calendar;
  ast_calendar.FIELD.sec  = 30;
  ast_calendar.FIELD.min  = 45;
  ast_calendar.FIELD.hour = 12;
  ast_calendar.FIELD.day  = 7;
  ast_calendar.FIELD.month= 10;
  ast_calendar.FIELD.year = 9;

  scif_osc32_opt_t opt;
  opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL;
  opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC;

  // Start OSC_32KHZ
  scif_start_osc32(&opt,true);

  // Initialize the AST
  if (!ast_init_calendar(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_calendar))
  {
    print_dbg("Error initializing the AST\r\n");
    while(1);
  }

  ast_set_periodic0_value(&AVR32_AST,pir);

  ast_enable_periodic0(&AVR32_AST);

  // Clear All Interrupt
  AVR32_AST.scr=0xFFFFFFFF;

  // Enable the AST
  ast_enable(&AVR32_AST);
}

/*! \brief Initializes the MCU system clocks.
*/
static void init_sys_clocks(void)
{

  /*! \name System Clock Frequencies
   */
  //! @{
  static pcl_freq_param_t pcl_freq_param =
  {
    .cpu_f        = FCPU_HZ,
    .pba_f        = FPBA_HZ,
    .osc0_f       = FOSC0,
    .osc0_startup = OSC0_STARTUP
  };
  //! @}

  // Configure system clocks.
  if (pcl_configure_clocks(&pcl_freq_param) != PASS) {
    while(1);
  }
}

/*! \brief This example show a DMA transfer to USART controlled by the AST
    periodic alarm using the PEVC.
 */
int main(void)
{
  int i;

  // Init the string with a simple recognizable pattern.
  for(i=0;i<sizeof(aDataTransfered);i++)
    aDataTransfered[i] = '0' + (i%36);

  init_sys_clocks();

  init_usart();

  gpio_clr_gpio_pin(LED0_GPIO);

  init_pevc();

  init_ast();

  init_pdca();

  while(1)
  {
    gpio_tgl_gpio_pin(LED1_GPIO);
    delay_ms(500); //Wait 500ms
  }
}
Ejemplo n.º 2
0
int8_t  i2c_driver_trigger_request(uint8_t  i2c_device, uint8_t  schedule_slot) 
{
	// initiate transfer of given request
	// set up DMA channel
	volatile avr32_twim_t *twim;
	
	i2c_packet_conf_t* conf = &schedule[i2c_device][schedule_slot].config;
	static  pdca_channel_options_t PDCA_OPTIONS =
			{
				.addr = 0,                                // memory address
				.pid = AVR32_TWIM0_PDCA_ID_TX,            // select peripheral 
				.size = 4,	                              // transfer counter
				.r_addr = NULL,                           // next memory address
				.r_size = 0,                              // next transfer counter
				.transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer
			};
	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;
		
		switch (conf->direction)  
		{
		case I2C_WRITE1_THEN_READ:
		case I2C_READ:
			PDCA_OPTIONS.pid = AVR32_TWIM0_PDCA_ID_RX;
			PDCA_OPTIONS.addr = (void *)conf->read_data;
			PDCA_OPTIONS.size=conf->read_count;
			// Init PDCA channel with the pdca_options.
			pdca_init_channel(TWI0_DMA_CH, &PDCA_OPTIONS); // init PDCA channel with options.
			break;
			
		case I2C_WRITE:
			PDCA_OPTIONS.pid = AVR32_TWIM0_PDCA_ID_TX;
			PDCA_OPTIONS.addr = (void *)conf->write_data;
			PDCA_OPTIONS.size=conf->write_count;
			
			// Init PDCA channel with the pdca_options.
			pdca_init_channel(TWI0_DMA_CH, &PDCA_OPTIONS); // init PDCA channel with options.
			pdca_load_channel(TWI0_DMA_CH, (void *)conf->write_data, conf->write_count);
			break;
		}
		
		//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_complete(TWI0_DMA_CH);
		pdca_enable_interrupt_transfer_error(TWI0_DMA_CH);
	break;
		
	case 1:
		twim = &AVR32_TWIM1;
	break;
	
	default: // invalid device ID
		return -1;
	}		

	// set up I2C speed and mode
	//twim_set_speed(twim, 100000, sysclk_get_pba_hz());
    
	switch (conf->direction)  
	{
		case I2C_READ:
			twim->cmdr = (conf->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
						| (conf->read_count << AVR32_TWIM_CMDR_NBYTES_OFFSET)
						| (AVR32_TWIM_CMDR_VALID_MASK)
						| (AVR32_TWIM_CMDR_START_MASK)
						| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
						| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
		break;
		
		case I2C_WRITE1_THEN_READ:
			print_util_dbg_print( "wr");
			
			// 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 = (conf->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
						| (1 << AVR32_TWIM_CMDR_NBYTES_OFFSET)
						| (AVR32_TWIM_CMDR_VALID_MASK)
						| (AVR32_TWIM_CMDR_START_MASK)
						| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
						;
			
			twim->ncmdr = (conf->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
						| ((conf->read_count) << AVR32_TWIM_CMDR_NBYTES_OFFSET)
						| (AVR32_TWIM_CMDR_VALID_MASK)
						| (AVR32_TWIM_CMDR_START_MASK)
						| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
						| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
			// set up writing of one byte (usually a slave register index)
			//twim->cr = AVR32_TWIM_CR_MEN_MASK;
			twim->thr = conf->write_then_read_preamble;
			twim->cr = AVR32_TWIM_CR_MEN_MASK;
		break;	
			
		case I2C_WRITE:
			print_util_dbg_print( "w");
			twim->cmdr = (conf->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
						| ((conf->write_count) << AVR32_TWIM_CMDR_NBYTES_OFFSET)
						| (AVR32_TWIM_CMDR_VALID_MASK)
						| (AVR32_TWIM_CMDR_START_MASK)
						| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
						;
			twim->ncmdr = (conf->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET)
						| ((conf->write_count) << AVR32_TWIM_CMDR_NBYTES_OFFSET)
						//| (AVR32_TWIM_CMDR_VALID_MASK)
						| (AVR32_TWIM_CMDR_START_MASK)
						| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
						;	
			
		break;	
	}		
	// start transfer

	current_schedule_slot[i2c_device] = schedule_slot;
	schedule[i2c_device][schedule_slot].transfer_in_progress = 1;
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	pdca_enable(TWI0_DMA_CH);
	return 0;
}

int8_t  i2c_driver_pause_request(uint8_t  i2c_device, uint8_t  schedule_slot)
{
	// pause scheduler
	// if this request currently active, wait for current transfer to finish
	// deactivate request
	// resume scheduler
}

int8_t  i2c_driver_enable_request(uint8_t  i2c_device, uint8_t  schedule_slot){
	return 0;
}

int8_t  i2c_driver_remove_request(uint8_t  i2c_device, uint8_t  schedule_slot){
	return 0;
}