/*! \brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
 */
static void sd_mmc_resources_init(void)
{
  // GPIO pins used for SD/MMC interface
  static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
  {
    {SD_MMC_SPI_SCK_PIN,  SD_MMC_SPI_SCK_FUNCTION },  // SPI Clock.
    {SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION},  // MISO.
    {SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION},  // MOSI.
    {SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
  };

  // SPI options.
  spi_options_t spiOptions =
  {
    .reg          = SD_MMC_SPI_NPCS,
    .baudrate     = SD_MMC_SPI_MASTER_SPEED,  // Defined in conf_sd_mmc_spi.h.
    .bits         = SD_MMC_SPI_BITS,          // Defined in conf_sd_mmc_spi.h.
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 1,
    .spi_mode     = 0,
    .modfdis      = 1
  };

  // Assign I/Os to SPI.
  gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
                     sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));

  // Initialize as master.
  spi_initMaster(SD_MMC_SPI, &spiOptions);

  // Set SPI selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(SD_MMC_SPI, 0, 0, 0);

  // Enable SPI module.
  spi_enable(SD_MMC_SPI);

  // Initialize SD/MMC driver with SPI clock (PBA).
  sd_mmc_spi_init(spiOptions, PBA_HZ);
}


/*! \brief Initialize PDCA (Peripheral DMA Controller A) resources for the SPI transfer and start a dummy transfer
 */
void local_pdca_init(void)
{
  // this PDCA channel is used for data reception from the SPI
  pdca_channel_options_t pdca_options_SPI_RX ={ // pdca channel options

    .addr = ram_buffer,
    // memory address. We take here the address of the string dummy_data. This string is located in the file dummy.h

    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_RX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // this channel is used to activate the clock of the SPI by sending a dummy variables
  pdca_channel_options_t pdca_options_SPI_TX ={ // pdca channel options

    .addr = (void *)&dummy_data,              // memory address.
                                              // We take here the address of the string dummy_data.
                                              // This string is located in the file dummy.h
    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_TX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // Init PDCA transmission channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_TX, &pdca_options_SPI_TX);

  // Init PDCA Reception channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_RX, &pdca_options_SPI_RX);

  //! \brief Enable pdca transfer interrupt when completed
  INTC_register_interrupt(&pdca_int_handler, AVR32_PDCA_IRQ_0, AVR32_INTC_INT1);  // pdca_channel_spi1_RX = 0

}


/*! \brief Main function. Execution starts here.
 */
int main(void)
{
  int i, j;


  // Switch the main clock to the external oscillator 0
  pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

  // Initialize debug RS232 with PBA clock
  init_dbg_rs232(PBA_HZ);

  //start test
  print_dbg("\r\nInit SD/MMC Driver");
  print_dbg("\r\nInsert SD/MMC...");

  // Initialize Interrupt Controller
  INTC_init_interrupts();

  // Initialize SD/MMC driver resources: GPIO, SPI and SD/MMC.
  sd_mmc_resources_init();

  // Wait for a card to be inserted
  while (!sd_mmc_spi_mem_check());
  print_dbg("\r\nCard detected!");

  // Read Card capacity
  sd_mmc_spi_get_capacity();
  print_dbg("Capacity = ");
  print_dbg_ulong(capacity >> 20);
  print_dbg(" MBytes");

  // Enable all interrupts.
  Enable_global_interrupt();

  // Initialize PDCA controller before starting a transfer
  local_pdca_init();

  // Read the first sectors number 1, 2, 3 of the card
  for(j = 1; j <= 3; j++)
  {
    // Configure the PDCA channel: the address of memory ram_buffer to receive the data at sector address j
    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_RX,
                     &ram_buffer,
                     512);

    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_TX,
                     (void *)&dummy_data,
                     512); //send dummy to activate the clock

    end_of_transfer = false;
    // open sector number j
    if(sd_mmc_spi_read_open_PDCA (j))
    {
      print_dbg("\r\nFirst 512 Bytes of Transfer number ");
      print_dbg_ulong(j);
      print_dbg(" :\r\n");

      spi_write(SD_MMC_SPI,0xFF); // Write a first dummy data to synchronize transfer
      pdca_enable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX);
      pdca_channelrx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_RX); // get the correct PDCA channel pointer
      pdca_channeltx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_TX); // get the correct PDCA channel pointer
      pdca_channelrx->cr = AVR32_PDCA_TEN_MASK; // Enable RX PDCA transfer first
      pdca_channeltx->cr = AVR32_PDCA_TEN_MASK; // and TX PDCA transfer

      while(!end_of_transfer);

      // Display the first 2O bytes of the ram_buffer content
      for( i = 0; i < 20; i++)
      {
        print_dbg_char_hex( (U8)(*(ram_buffer + i)));
      }
    }
    else
    {
      print_dbg("\r\n! Unable to open memory \r\n");
    }
  }
  print_dbg("\r\nEnd of the example.\r\n");

  while (1);
}
Esempio n. 2
0
uint8_t check_SD(void)
{
	if(SD_card_inserted()==false)
	{
		return SD_card_not_inserted;	
	}
	spi_options_t SD_spiOptions =
	  {
		.reg          = SD_MMC_SPI_NPCS,
		.baudrate     = SD_SPI_SPEED,  // Defined in conf_sd_mmc_spi.h.
		.bits         = 8,          // Defined in conf_sd_mmc_spi.h.
		.spck_delay   = 0,
		.trans_delay  = 0,
		.stay_act     = 1,
		.spi_mode     = 0,
		.modfdis      = 1
	  };
  
	if(sd_mmc_spi_init(SD_spiOptions, PBA_SPEED)==false)
	{
		return SD_card_init_failed;
	}
  
	if(card_type!=SD_CARD_2_SDHC)
	{
		return SD_card_invalid;
	}
	return SD_card_valid;
}

bool SD_card_inserted(void)
{
	if(gpio_get_pin_value(SD_detect_pin)==0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

uint8_t hostmode_run(void)
{
	//first receive and verify full experiment
	//set USB PDCA to store experiment
	USB_USART->rtor=0;	//disable timeout
	pdca_disable(USB_USART_RX_PDCA_CHANNEL);
	my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_RX_PDCA_PID,   0,  0, PDCA_TRANSFER_SIZE_BYTE);
	pdca_enable(USB_USART_RX_PDCA_CHANNEL);
	
	while(!(pdca_get_transfer_status(USB_USART_RX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done
	
	if(validate_sequences()==false)
	{
		usart_write_line(USB_USART, "badexp\n");
		
		usart_putchar(USB_USART,(uint8_t)(get_experiment_problem()));
		
		my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE);
		pdca_enable(USB_USART_RX_PDCA_CHANNEL);
		USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received
		USB_USART->rtor=15000;	//set to timeout in 1ms
		
		return 0;
	}
	
	usart_write_line(USB_USART, "goodexp\n");
	pdca_disable(USB_USART_TX_PDCA_CHANNEL);
	gettruesequence();
	my_pdca_init_channel(USB_USART_TX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_TX_PDCA_PID,   0,  0, PDCA_TRANSFER_SIZE_BYTE);
	pdca_enable(USB_USART_TX_PDCA_CHANNEL);
	while(!(pdca_get_transfer_status(USB_USART_TX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done
	pdca_disable(USB_USART_TX_PDCA_CHANNEL);
	
	//change back USB USART to accept command tokens
	my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE);
	pdca_enable(USB_USART_RX_PDCA_CHANNEL);
	
	for(uint8_t i=0;i<Nsequences_max;i++)
	{
		usart_putchar(USB_USART,(uint8_t)(t_experiment.t_sequence[i].clusters_per_sequence));
	}
	
	USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received
	USB_USART->rtor=15000;	//set to timeout in 1ms
	
	reset_SD_sink_ptr();
	uint32_t SD_read_ptr=data_base_address;
	
	DAC1->dr0=t_experiment.t_Vgain; //set gain of RF amp
	
	while(1)	//once in host mode, this will run until a restart command is received
	{
		char *HOSTCMD="false";
		while(strcmp(HOSTCMD,"false")==0)
		{
			HOSTCMD=get_HOST_cmd();
			if(strcmp((HOSTCMD+1),"sequencetoken")==0)
			{
				uint8_t sequenceindex=*HOSTCMD;
				t_currentsequence=t_experiment.t_sequence[sequenceindex];
				
				executesequence_SDstorage_multiprep_combined();
				
				if(did_data_fail())
				{
					usart_write_line(USB_USART, "fail\n");
					usart_putchar(USB_USART,(uint8_t)(get_failure_cause()));
					usart_putchar(USB_USART,(uint8_t)(get_saved_r1()));
				}					
				else
				{
					usart_write_line(USB_USART, "good\n");
					send_data_to_host(SD_read_ptr,t_currentsequence.clusters_per_sequence);
				}	
				
				
				SD_read_ptr+=t_currentsequence.clusters_per_sequence*blocks_per_cluster*bytes_per_block;
				//set back to command mode
				pdca_disable(USB_USART_RX_PDCA_CHANNEL);
				my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE);
				pdca_enable(USB_USART_RX_PDCA_CHANNEL);
				USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received
				USB_USART->rtor=15000;	//set to timeout in 1ms
			}
			else if(strcmp((HOSTCMD),"RESTART\n")==0)
			{	//want to handle start of new host mode experiment
				return 1;
			}
		}
			
	}
	return 1;	
}
Esempio n. 3
0
File: init.c Progetto: mtwieg/NMR
static void tc_init_fast(volatile avr32_tc_t *tc)
{
	// Options for waveform generation.
	static const tc_waveform_opt_t waveform_opt_1 = {

		.channel  = FAST_TC_CHANNEL,  // Channel selection.
		.bswtrg   = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB.
		.beevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOB.
		.bcpc     = TC_EVT_EFFECT_NOOP,	// RC compare effect on TIOB.
		.bcpb     = TC_EVT_EFFECT_NOOP,	// RB compare effect on TIOB.
		.aswtrg   = TC_EVT_EFFECT_NOOP,	// Software trigger effect on TIOA.
		.aeevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOA.
		.acpc     = TC_EVT_EFFECT_NOOP,	// RC compare effect on TIOA.
		.acpa     = TC_EVT_EFFECT_NOOP,	//RA compare effect on TIOA. 
		.wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,	//Waveform selection: Up mode with automatic trigger(reset)
		.enetrg   = false,	//// External event trigger enable.
		.eevt     = 0,	//// External event selection.
		.eevtedg  = TC_SEL_NO_EDGE,	//// External event edge selection.
		.cpcdis   = false,	// Counter disable when RC compare.
		.cpcstop  = false,	// Counter clock stopped with RC compare.
		.burst    = false,	// Burst signal selection
		.clki     = false,	// Clock inversion.
		.tcclks   = TC_CLOCK_SOURCE_TC3	// Internal source clock 3, connected to fPBA / 8.
	};

	// Options for enabling TC interrupts
	static const tc_interrupt_t tc_interrupt = {
		.etrgs = 0,
		.ldrbs = 0,
		.ldras = 0,
		.cpcs  = 1, // Enable interrupt on RC compare alone
		.cpbs  = 0,
		.cpas  = 0,
		.lovrs = 0,
		.covfs = 0
	};
	// Initialize the timer/counter.
	tc_init_waveform(tc, &waveform_opt_1);

	tc_write_rc(tc, FAST_TC_CHANNEL, 10);
	// configure the timer interrupt
	tc_configure_interrupts(tc, FAST_TC_CHANNEL, &tc_interrupt);
}

static void tc_init_slow(volatile avr32_tc_t *tc)
{
	// Options for waveform generation.
	static const tc_waveform_opt_t waveform_opt_2 = {
		.channel  = SLOW_TC_fast_CHANNEL,	// Channel selection.
		.bswtrg   = TC_EVT_EFFECT_NOOP,	// Software trigger effect on TIOB.
		.beevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOB.
		.bcpc     = TC_EVT_EFFECT_NOOP,	// RC compare effect on TIOB.
		.bcpb     = TC_EVT_EFFECT_NOOP,	// RB compare effect on TIOB.
		.aswtrg   = TC_EVT_EFFECT_NOOP,	// Software trigger effect on TIOA.
		.aeevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOA.
		.acpc     = TC_EVT_EFFECT_CLEAR,	// RC compare effect on TIOA.
		.acpa     = TC_EVT_EFFECT_SET,	// RA compare effect on TIOA. 
		.wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,	//Waveform selection: Up mode with automatic trigger(reset)
		.enetrg   = false,	// External event trigger enable.
		.eevt     = 0,	// External event selection.
		.eevtedg  = TC_SEL_NO_EDGE,	// External event edge selection.
		.cpcdis   = false,	// Counter disable when RC compare.
		.cpcstop  = false,	// Counter clock stopped with RC compare.
		.burst    = false,	// Burst signal selection.
		.clki     = false,	// Clock inversion.
		.tcclks   = TC_CLOCK_SOURCE_TC3	// Internal source clock 3, connected to fPBA / 8.
	};

	// Initialize the timer/counter.
	tc_init_waveform(tc, &waveform_opt_2);
	tc_write_rc(tc, SLOW_TC_fast_CHANNEL, 7500); //counter will count milliseconds
	tc_write_ra(tc, SLOW_TC_fast_CHANNEL, 3500); //configure ra so that TIOA0 is toggled
	
	static const tc_waveform_opt_t waveform_opt_3 = {
		.channel  = SLOW_TC_slow_CHANNEL,	// Channel selection.	
		.bswtrg   = TC_EVT_EFFECT_NOOP,	// Software trigger effect on TIOB.
		.beevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOB.
		.bcpc     = TC_EVT_EFFECT_NOOP,	// RC compare effect on TIOB.
		.bcpb     = TC_EVT_EFFECT_NOOP,	// RB compare effect on TIOB.
		.aswtrg   = TC_EVT_EFFECT_NOOP,	// Software trigger effect on TIOA.
		.aeevt    = TC_EVT_EFFECT_NOOP,	// External event effect on TIOA.
		.acpc     = TC_EVT_EFFECT_NOOP,	// RC compare effect on TIOA.
		.acpa     = TC_EVT_EFFECT_NOOP,	//RA compare effect on TIOA. 
		.wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,	//Waveform selection: Up mode with automatic trigger(reset)
		.enetrg   = false,	//// External event trigger enable.
		.eevt     = 0,	//// External event selection.
		.eevtedg  = TC_SEL_NO_EDGE,	//// External event edge selection.
		.cpcdis   = false,	// Counter disable when RC compare.
		.cpcstop  = false,	// Counter clock stopped with RC compare.
		.burst    = false,	// Burst signal selection.
		.clki     = false,	// Clock inversion.
		.tcclks   = TC_CLOCK_SOURCE_XC0	// Use XC1 as clock source.  Must configure TIOA0 to be XC1
	};
	
	tc_init_waveform(tc, &waveform_opt_3);
	tc_write_rc(tc, SLOW_TC_slow_CHANNEL, 100); //
	tc_select_external_clock(tc,SLOW_TC_slow_CHANNEL,AVR32_TC_BMR_TC0XC0S_TIOA1); //use TIOA1 as XC0
}


	static void configure_hmatrix(uint32_t mode)
{
	// Configure all Slave in Last Default Master
#if (defined AVR32_HMATRIX) 
	for(uint32_t i = 0; i < AVR32_HMATRIX_SLAVE_NUM; i++) {
		AVR32_HMATRIX.SCFG[i].defmstr_type = mode;
	}
#endif
#if (defined AVR32_HMATRIXB)
	for(uint32_t i = 0;i < AVR32_HMATRIXB_SLAVE_NUM; i++) {
		AVR32_HMATRIXB.SCFG[i].defmstr_type = mode;
	}
#endif 
}

void board_init(void)
{
	/* This function is meant to contain board-specific initialization code
	 * for, e.g., the I/O pins. The initialization can rely on application-
	 * specific board configuration, found in conf_board.h.
	 */
	gpio_local_init();
	
	static pcl_freq_param_t pcl_freq_param =
{
	.cpu_f        = CPU_SPEED,
	.pba_f        = PBA_SPEED,
	.osc0_f       = FOSC0,
	.osc0_startup = OSC0_STARTUP
};

	if (pcl_configure_clocks(&pcl_freq_param) != PASS)
	while (true);
	
	configure_hmatrix(AVR32_HMATRIXB_DEFMSTR_TYPE_NO_DEFAULT);
	
	AVR32_LowLevelInit();
	
	//configure all GPIO
	gpio_local_enable_pin_output_driver(ADC_CONV_pin);
	gpio_local_clr_gpio_pin(ADC_CONV_pin);
	gpio_local_enable_pin_output_driver(DDS_IOUD_pin);
	gpio_local_clr_gpio_pin(DDS_IOUD_pin);
	gpio_local_enable_pin_output_driver(DDS_RESET_pin);
	gpio_local_clr_gpio_pin(DDS_RESET_pin);
	gpio_local_enable_pin_output_driver(DDS_PDN_pin);
	gpio_local_set_gpio_pin(DDS_PDN_pin);
	
	gpio_local_enable_pin_output_driver(DDS_P0_pin);
	gpio_local_clr_gpio_pin(DDS_P0_pin);
	gpio_local_enable_pin_output_driver(DDS_P1_pin);
	gpio_local_clr_gpio_pin(DDS_P1_pin);
	gpio_local_enable_pin_output_driver(DDS_P2_pin);
	gpio_local_clr_gpio_pin(DDS_P2_pin);
	gpio_local_enable_pin_output_driver(DDS_P3_pin);
	gpio_local_clr_gpio_pin(DDS_P3_pin);
	
	gpio_local_enable_pin_output_driver(RXSW_pin);
	gpio_local_clr_gpio_pin(RXSW_pin);
	gpio_local_enable_pin_output_driver(TXSW_pin);
	gpio_local_clr_gpio_pin(TXSW_pin);
	gpio_local_enable_pin_output_driver(TPAbias_pin);
	gpio_local_clr_gpio_pin(TPAbias_pin);
	gpio_local_enable_pin_output_driver(GEN1_pin);
	gpio_local_clr_gpio_pin(GEN1_pin);
	gpio_local_enable_pin_output_driver(GEN2_pin);
	gpio_local_clr_gpio_pin(GEN2_pin);
	
	gpio_local_enable_pin_output_driver(PWM0_pin);
	gpio_local_clr_gpio_pin(PWM0_pin);
	
	gpio_local_disable_pin_output_driver(SD_detect_pin);
	
	//configure all peripheral IO
	
	static const gpio_map_t GCLK_GPIO_MAP =
	{
		{AVR32_SCIF_GCLK_0_1_PIN, AVR32_SCIF_GCLK_0_1_FUNCTION}
	};
	
	gpio_enable_module(GCLK_GPIO_MAP,
			sizeof(GCLK_GPIO_MAP) / sizeof(GCLK_GPIO_MAP[0]));
	
	genclk_enable_config(9, GENCLK_SRC_CLK_CPU, 2);
	
	static const gpio_map_t SPI_GPIO_MAP =
	{
		{SPI1_SCK_PIN, SPI1_SCK_FUNCTION},
		{SPI1_MOSI_PIN, SPI1_MOSI_FUNCTION},
		{SPI1_MISO_PIN, SPI1_MISO_FUNCTION},
		{SPI1_NPCS2_PIN, SPI1_NPCS2_FUNCTION}
	};
	
	gpio_enable_module(SPI_GPIO_MAP,
			sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0]));


spi_options_t SPI1_OPTIONS_0 = 
{
  .reg			= 0,		//! The SPI channel to set up.
  .baudrate		= 30000000,	//! Preferred baudrate for the SPI.
  .bits			=16,	//! Number of bits in each character (8 to 16).
  .spck_delay	=0,	//! Delay before first clock pulse after selecting slave (in PBA clock periods). 
  .trans_delay	=0,	//! Delay between each transfer/character (in PBA clock periods).
  .stay_act		=0,	 //! Sets this chip to stay active after last transfer to it.
  .spi_mode		=1,	//! Which SPI mode to use when transmitting.
  .modfdis		=1	 //! Disables the mode fault detection.
};

spi_options_t SPI1_OPTIONS_3 = 
{
  .reg			= 3,		//! The SPI channel to set up.
  .baudrate		= 30000000,	//! Preferred baudrate for the SPI.
  .bits			=8,	//! Number of bits in each character (8 to 16).
  .spck_delay	=0,	//! Delay before first clock pulse after selecting slave (in PBA clock periods).
  .trans_delay	=0,	//! Delay between each transfer/character (in PBA clock periods).
  .stay_act		=1,	//! Sets this chip to stay active after last transfer to it.
  .spi_mode		=0,	//! Which SPI mode to use when transmitting.
  .modfdis		=1	//! Disables the mode fault detection.
};

	spi_initMaster(SPI1, &SPI1_OPTIONS_0); 
	spi_selectionMode(SPI1,1,0,0);
	spi_enable(SPI1);
	spi_setupChipReg(SPI1,&SPI1_OPTIONS_0,PBA_SPEED);
	spi_setupChipReg(SPI1,&SPI1_OPTIONS_3,PBA_SPEED);
	spi_selectChip(SPI1, 3);
	
	static const gpio_map_t USB_USART_GPIO_MAP =
	{
		{USB_USART_RX_PIN, USB_USART_RX_FUNCTION},
		{USB_USART_TX_PIN, USB_USART_TX_FUNCTION},
		{USB_USART_RTS_PIN, USB_USART_RTS_FUNCTION},
		{USB_USART_CTS_PIN, USB_USART_CTS_FUNCTION}
	};
	
	gpio_enable_module(USB_USART_GPIO_MAP,
			sizeof(USB_USART_GPIO_MAP) / sizeof(USB_USART_GPIO_MAP[0]));
			
	static const usart_options_t USB_USART_OPTIONS =
	{
		.baudrate     = 3000000,
		.charlength   = 8,
		.paritytype   = USART_NO_PARITY,
		.stopbits     = USART_1_STOPBIT,
		.channelmode  = USART_NORMAL_CHMODE
	};
			
	usart_init_hw_handshaking(USB_USART, &USB_USART_OPTIONS, PBA_SPEED);
	
	static const gpio_map_t LCD_USART_GPIO_MAP =
	{
		{LCD_USART_RX_PIN, LCD_USART_RX_FUNCTION},
		{LCD_USART_TX_PIN, LCD_USART_TX_FUNCTION}
	};
	
	gpio_enable_module(LCD_USART_GPIO_MAP,
			sizeof(LCD_USART_GPIO_MAP) / sizeof(LCD_USART_GPIO_MAP[0]));
			
	static const usart_options_t LCD_USART_OPTIONS =
	{
		.baudrate     = 115200,
		.charlength   = 8,
		.paritytype   = USART_NO_PARITY,
		.stopbits     = USART_1_STOPBIT,
		.channelmode  = USART_NORMAL_CHMODE
	};
			
	usart_init_rs232(LCD_USART, &LCD_USART_OPTIONS, PBA_SPEED);
	LCD_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received
	LCD_USART->rtor=230;	//set to timeout in 2ms
	
	
	my_pdca_init_channel(LCD_USART_RX_PDCA_CHANNEL, (uint32_t)(&LCD_USART_buffer),(uint32_t)(sizeof(LCD_USART_buffer)),LCD_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE);
	pdca_disable(LCD_USART_RX_PDCA_CHANNEL);
	
	my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE);
	pdca_disable(USB_USART_RX_PDCA_CHANNEL);
	
	USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received
	USB_USART->rtor=15000;	//set to timeout in 1ms
	
	// GPIO pins used for SD/MMC interface
  static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
  {
    {SPI0_SCK_PIN,  SPI0_SCK_FUNCTION },  // SPI Clock.
    {SPI0_MISO_PIN, SPI0_MISO_FUNCTION},  // MISO.
    {SPI0_MOSI_PIN, SPI0_MOSI_FUNCTION},  // MOSI.
    {SPI0_NPCS0_PIN, SPI0_NPCS0_FUNCTION}   // Chip Select NPCS.
  };

   //SPI options.
  spi_options_t SD_spiOptions =
  {
    .reg          = SD_MMC_SPI_NPCS,
    .baudrate     = SD_SPI_SPEED,  // Defined in conf_sd_mmc_spi.h.
    .bits         = 8,          // Defined in conf_sd_mmc_spi.h.
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 1,
    .spi_mode     = 0,
    .modfdis      = 1
  };

  // Assign I/Os to SPI.
  gpio_enable_module(SD_MMC_SPI_GPIO_MAP,sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));
  // Initialize as master.
  spi_initMaster(SPI0, &SD_spiOptions);
  // Set SPI selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(SPI0, 0, 0, 0);
  // Enable SPI module.
  spi_enable(SPI0);
  // Initialize SD/MMC driver with SPI clock (PBA).
  sd_mmc_spi_init(SD_spiOptions, PBA_SPEED);
  
  tc_init_fast(FAST_TC);
  tc_init_slow(SLOW_TC);
  
  static const gpio_map_t DACIFB_GPIO_MAP =
  {
    {AVR32_DACREF_PIN,AVR32_DACREF_FUNCTION},
    {AVR32_ADCREFP_PIN,AVR32_ADCREFP_FUNCTION},
    {AVR32_ADCREFN_PIN,AVR32_ADCREFN_FUNCTION},
    {DAC0A_pin, DAC0A_FUNCTION},
	{DAC1A_pin, DAC1A_FUNCTION}
  };
  
  gpio_enable_module(DACIFB_GPIO_MAP, sizeof(DACIFB_GPIO_MAP) / sizeof(DACIFB_GPIO_MAP[0]));
  
  dacifb_opt_t dacifb_opt = {
    .reference                  = DACIFB_REFERENCE_EXT ,        // VDDANA Reference
    .channel_selection          = DACIFB_CHANNEL_SELECTION_A,     // Selection Channels A&B
    .low_power                  = false,                          // Low Power Mode
    .dual                       = false,                          // Dual Mode
    .prescaler_clock_hz         = DAC_PRESCALER_CLK     // Prescaler Clock (Should be 500Khz)
};

// DAC Channel Configuration
dacifb_channel_opt_t dacifb_channel_opt = {
    .auto_refresh_mode    = true,                      // Auto Refresh Mode
    .trigger_mode         = DACIFB_TRIGGER_MODE_MANUAL, // Trigger selection
    .left_adjustment      = false,                      // Right Adjustment
    .data_shift           = 0,                          // Number of Data Shift
    .data_round_enable    = false                       // Data Rouding Mode                                              };
};

volatile avr32_dacifb_t *dacifb0 = &AVR32_DACIFB0; // DACIFB IP registers address
volatile avr32_dacifb_t *dacifb1 = &AVR32_DACIFB1; // DACIFB IP registers address

//The factory calibration for DADIFB is broken, so use manual calibration
//dacifb_get_calibration_data(DAC0,&dacifb_opt,0);

dacifb_opt.gain_calibration_value=0x0090;
dacifb_opt.offset_calibration_value=0x0153;

  // configure DACIFB0
dacifb_configure(DAC0,&dacifb_opt,PBA_SPEED);

dacifb_configure_channel(DAC0,DACIFB_CHANNEL_SELECTION_A,&dacifb_channel_opt,DAC_PRESCALER_CLK);

dacifb_start_channel(DAC0,DACIFB_CHANNEL_SELECTION_A,PBA_SPEED);

//The factory calibration for DADIFB is broken, so use manual calibration					
dacifb_set_value(DAC0,DACIFB_CHANNEL_SELECTION_A,false,1024);					   
					   				 
//dacifb_get_calibration_data(DAC1, &dacifb_opt,1);
							
dacifb_opt.gain_calibration_value=0x0084;
dacifb_opt.offset_calibration_value=0x0102;							

  // configure DACIFB1
dacifb_configure(DAC1,&dacifb_opt,PBA_SPEED);
				   
dacifb_configure_channel(DAC1,DACIFB_CHANNEL_SELECTION_A,&dacifb_channel_opt,DAC_PRESCALER_CLK);

dacifb_start_channel(DAC1,DACIFB_CHANNEL_SELECTION_A,PBA_SPEED);
					   
dacifb_set_value(DAC1,DACIFB_CHANNEL_SELECTION_A,false,1024);					   				   				 

DAC0->dr0=2048;
DAC1->dr0=4095;
}
Esempio n. 4
0
// initializes the SD/MMC memory resources: GPIO, SPI and MMC
//-------------------------------------------------------------------
static void sd_mmc_resources_init(long pba_hz) {
	
	// GPIO pins used for SD/MMC interface
	static const gpio_map_t SD_MMC_SPI_GPIO_MAP = {
	{SD_MMC_SPI_SCK_PIN,  SD_MMC_SPI_SCK_FUNCTION },  // SPI Clock.
	{SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION},  // MISO.
	{SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION},  // MOSI.
	{SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
	};

	// SPI options.
	spi_options_t spiOptions = {
		.reg          = SD_MMC_SPI_NPCS,
		.baudrate     = SD_MMC_SPI_MASTER_SPEED,  // Defined in conf_sd_mmc_spi.h.
		.bits         = SD_MMC_SPI_BITS,          // Defined in conf_sd_mmc_spi.h.
		.spck_delay   = 0,
		.trans_delay  = 0,
		.stay_act     = 1,
		.spi_mode     = 0,
		.modfdis      = 1
	};

	// assign I/Os to SPI.
	gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
	sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));

	// initialize as master.
	spi_initMaster(SD_MMC_SPI, &spiOptions);

	// set SPI selection mode: variable_ps, pcs_decode, delay.
	spi_selectionMode(SD_MMC_SPI, 0, 0, 0);

	// enable SPI module.
	spi_enable(SD_MMC_SPI);

	// Initialize SD/MMC driver with SPI clock (PBA).
	sd_mmc_spi_init(spiOptions, pba_hz);
}

// process a USB frame
//-------------------------------------------------------------------
void process_frame(uint16_t framenumber)
{
	static uint8_t cpt_sof = 0;
	static injectState_t state = state_START_INJECT;
	static uint8_t wait = 0;
	static uint16_t debounce = 0;
	static uint16_t injectToken = 0x0000;
	
	static uint16_t delay = 0;
	
	// scan process running each 2ms
	cpt_sof++;
	if( 2 > cpt_sof )
	return;
	cpt_sof = 0;
	
	// pulse led
	LED_Set_Intensity( LED0, framenumber >> 1 );
	
	// debounce switch
	if( debounce > 0 ) --debounce;
	
	//delay a random amount
	if(delay == 0){
		// injection state machine
		switch(state) {

			case state_IDLE:
			// check switch
			if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) {
			
				// debounce
				if( debounce == 0 ) {
					state = state_START_INJECT;
					debounce = 250;
				}
			}
			break;
		
			case state_START_INJECT:
			file_open(FOPEN_MODE_R);
			state = state_INJECTING;
			break;
		
			case state_INJECTING:
		
			if( file_eof() ) {
				file_close();
				state = state_IDLE;
				break;
			}
		
			injectToken = ( file_getc() | ( file_getc() << 8 ) );
		
			if( ( injectToken&0xff ) == 0x00 ) {
				wait = injectToken>>8;
				state = state_WAIT;
			}
			else if( ( injectToken>>8 ) == 0x00 ) {
				state = state_KEY_DOWN;
			}
			else {
				state = state_MOD_DOWN;
			}
			break;
		
			case state_KEY_DOWN:
			udi_hid_kbd_down(injectToken&0xff);
			state = state_KEY_UP;
			delay = rand() % MAX_DELAY;
			break;

			case state_KEY_UP:
			udi_hid_kbd_up(injectToken&0xff);
			state = state_INJECTING;
			delay = rand() % MAX_DELAY;
			break;
		
			case state_MOD_DOWN:
			udi_hid_kbd_modifier_down(injectToken>>8);
			state = state_MOD_KEY_DOWN;
			delay = rand() % MAX_DELAY;
			break;

			case state_MOD_KEY_DOWN:
			udi_hid_kbd_down(injectToken&0xff);
			state = state_MOD_KEY_UP;
			delay = rand() % MAX_DELAY;
			break;

			case state_MOD_KEY_UP:
			udi_hid_kbd_up(injectToken&0xff);
			state = state_MOD_UP;
			delay = rand() % MAX_DELAY;
			break;
		
			case state_MOD_UP:
			udi_hid_kbd_modifier_up(injectToken>>8);
			state = state_INJECTING;
			delay = rand() % 50;
			break;
		
			case state_WAIT:
			if( --wait == 0 ) {
				state = state_INJECTING;
			}
			break;
		
			default:
			state = state_IDLE;
		}
void memories_initialization(void)
{
	//-- Hmatrix bus configuration
	// This improve speed performance
#ifdef AVR32_HMATRIXB
	union {
		unsigned long scfg;
		avr32_hmatrixb_scfg_t SCFG;
	} u_avr32_hmatrixb_scfg;

	sysclk_enable_pbb_module(SYSCLK_HMATRIX);

	// For the internal-flash HMATRIX slave, use last master as default.
	u_avr32_hmatrixb_scfg.scfg =
			AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_FLASH];
	u_avr32_hmatrixb_scfg.SCFG.defmstr_type =
			AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_FLASH] =
			u_avr32_hmatrixb_scfg.scfg;
	// For the internal-SRAM HMATRIX slave, use last master as default.
	u_avr32_hmatrixb_scfg.scfg =
			AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_SRAM];
	u_avr32_hmatrixb_scfg.SCFG.defmstr_type =
			AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_SRAM] =
			u_avr32_hmatrixb_scfg.scfg;
# ifdef AVR32_HMATRIXB_SLAVE_EBI
	// For the EBI HMATRIX slave, use last master as default.
	u_avr32_hmatrixb_scfg.scfg =
			AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_EBI];
	u_avr32_hmatrixb_scfg.SCFG.defmstr_type =
			AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_EBI] =
			u_avr32_hmatrixb_scfg.scfg;
# endif
#endif

#ifdef AVR32_HMATRIX
	union {
		unsigned long scfg;
		avr32_hmatrix_scfg_t SCFG;
	} u_avr32_hmatrix_scfg;

	sysclk_enable_pbb_module(SYSCLK_HMATRIX);

	// For the internal-flash HMATRIX slave, use last master as default.
	u_avr32_hmatrix_scfg.scfg =
			AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH];
	u_avr32_hmatrix_scfg.SCFG.defmstr_type =
			AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH] =
			u_avr32_hmatrix_scfg.scfg;
	// For the internal-SRAM HMATRIX slave, use last master as default.
	u_avr32_hmatrix_scfg.scfg =
			AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_SRAM];
	u_avr32_hmatrix_scfg.SCFG.defmstr_type =
			AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_SRAM] =
			u_avr32_hmatrix_scfg.scfg;
# ifdef AVR32_HMATRIX_SLAVE_EBI
	// For the EBI HMATRIX slave, use last master as default.
	u_avr32_hmatrix_scfg.scfg =
			AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_EBI];
	u_avr32_hmatrix_scfg.SCFG.defmstr_type =
			AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_EBI] =
			u_avr32_hmatrix_scfg.scfg;
# endif
#endif

#ifdef AVR32_HMATRIX_MASTER_USBB_DMA
	union {
		unsigned long                 mcfg;
		avr32_hmatrix_mcfg_t          MCFG;
	} u_avr32_hmatrix_mcfg;
 
	// For the USBB DMA HMATRIX master, use infinite length burst.
	u_avr32_hmatrix_mcfg.mcfg =
			AVR32_HMATRIX.mcfg[AVR32_HMATRIX_MASTER_USBB_DMA];
	u_avr32_hmatrix_mcfg.MCFG.ulbt =
			AVR32_HMATRIX_ULBT_INFINITE;
	AVR32_HMATRIX.mcfg[AVR32_HMATRIX_MASTER_USBB_DMA] =
			u_avr32_hmatrix_mcfg.mcfg;
	
	// For the USBB DPRAM HMATRIX slave, use the USBB DMA as fixed default master.
	u_avr32_hmatrix_scfg.scfg =
			AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_USBB_DPRAM];
	u_avr32_hmatrix_scfg.SCFG.fixed_defmstr =
			AVR32_HMATRIX_MASTER_USBB_DMA;
	u_avr32_hmatrix_scfg.SCFG.defmstr_type =
			AVR32_HMATRIX_DEFMSTR_TYPE_FIXED_DEFAULT;
	AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_USBB_DPRAM] =
			u_avr32_hmatrix_scfg.scfg;
#endif

#if (defined AT45DBX_MEM) && (AT45DBX_MEM == ENABLE)
	sysclk_enable_peripheral_clock(AT45DBX_SPI_MODULE);
	at45dbx_init();
#endif

#if ((defined SD_MMC_MCI_0_MEM) && (SD_MMC_MCI_0_MEM == ENABLE)) \
	|| ((defined SD_MMC_MCI_1_MEM) && (SD_MMC_MCI_1_MEM == ENABLE))
	sysclk_enable_pbb_module(SYSCLK_MCI);
	sysclk_enable_hsb_module(SYSCLK_DMACA);
	sd_mmc_mci_init(SD_SLOT_8BITS, sysclk_get_pbb_hz(), sysclk_get_cpu_hz());
#endif

#if (defined SD_MMC_SPI_MEM) && (SD_MMC_SPI_MEM == ENABLE)
	// SPI options.
	spi_options_t spiOptions = {
		.reg          = SD_MMC_SPI_NPCS,
		.baudrate     = SD_MMC_SPI_MASTER_SPEED,  // Defined in conf_sd_mmc_spi.h.
		.bits         = SD_MMC_SPI_BITS,          // Defined in conf_sd_mmc_spi.h.
		.spck_delay   = 0,
		.trans_delay  = 0,
		.stay_act     = 1,
		.spi_mode     = 0,
		.modfdis      = 1
	};

	sysclk_enable_peripheral_clock(SD_MMC_SPI);

	// If the SPI used by the SD/MMC is not enabled.
	if (!spi_is_enabled(SD_MMC_SPI)) {
		// Initialize as master.
		spi_initMaster(SD_MMC_SPI, &spiOptions);
		// Set selection mode: variable_ps, pcs_decode, delay.
		spi_selectionMode(SD_MMC_SPI, 0, 0, 0);
		// Enable SPI.
		spi_enable(SD_MMC_SPI);
	}

	// Initialize SD/MMC with SPI PB clock.
	sd_mmc_spi_init(spiOptions,sysclk_get_pba_hz());
#endif  // SD_MMC_SPI_MEM == ENABLE

}
Esempio n. 6
0
// initialize application timer
extern void init_tc (volatile avr32_tc_t *tc) {
  // waveform options
  static const tc_waveform_opt_t waveform_opt = {
    .channel  = APP_TC_CHANNEL,  // channel
    .bswtrg   = TC_EVT_EFFECT_NOOP, // software trigger action on TIOB
    .beevt    = TC_EVT_EFFECT_NOOP, // external event action
    .bcpc     = TC_EVT_EFFECT_NOOP, // rc compare action
    .bcpb     = TC_EVT_EFFECT_NOOP, // rb compare
    .aswtrg   = TC_EVT_EFFECT_NOOP, // soft trig on TIOA
    .aeevt    = TC_EVT_EFFECT_NOOP, // etc
    .acpc     = TC_EVT_EFFECT_NOOP,
    .acpa     = TC_EVT_EFFECT_NOOP,
    // Waveform selection: Up mode with automatic trigger(reset) on RC compare.
    .wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,
    .enetrg   = false,             // external event trig
    .eevt     = 0,                 // extern event select
    .eevtedg  = TC_SEL_NO_EDGE,    // extern event edge
    .cpcdis   = false,             // counter disable when rc compare
    .cpcstop  = false,            // counter stopped when rc compare
    .burst    = false,
    .clki     = false,
    // Internal source clock 5, connected to fPBA / 128.
    .tcclks   = TC_CLOCK_SOURCE_TC5
  };

  // Options for enabling TC interrupts
  static const tc_interrupt_t tc_interrupt = {
    .etrgs = 0,
    .ldrbs = 0,
    .ldras = 0,
    .cpcs  = 1, // Enable interrupt on RC compare alone
    .cpbs  = 0,
    .cpas  = 0,
    .lovrs = 0,
    .covfs = 0
  };
  // Initialize the timer/counter.
  tc_init_waveform(tc, &waveform_opt);

  // set timer compare trigger.
  // we want it to overflow and generate an interrupt every 1 ms
  // so (1 / fPBA / 128) * RC = 0.001
  // so RC = fPBA / 128 / 1000
  tc_write_rc(tc, APP_TC_CHANNEL, (FPBA_HZ / 128 / 1000));
  // configure the timer interrupt
  tc_configure_interrupts(tc, APP_TC_CHANNEL, &tc_interrupt);
  // Start the timer/counter.
  tc_start(tc, APP_TC_CHANNEL);
}


// initialize usb USARTy
void init_ftdi_usart (void) {
  // GPIO map for USART.
  static const gpio_map_t FTDI_USART_GPIO_MAP = {
    { FTDI_USART_RX_PIN, FTDI_USART_RX_FUNCTION },
    { FTDI_USART_TX_PIN, FTDI_USART_TX_FUNCTION }
  };
  
  // Options for USART.
  static const usart_options_t FTDI_USART_OPTIONS = {
    .baudrate = FTDI_USART_BAUDRATE,
    .charlength = 8,
    .paritytype = USART_NO_PARITY,
    .stopbits = USART_1_STOPBIT,
    .channelmode = USART_NORMAL_CHMODE
  };

  // Set up GPIO for FTDI_USART
  gpio_enable_module(FTDI_USART_GPIO_MAP,
                     sizeof(FTDI_USART_GPIO_MAP) / sizeof(FTDI_USART_GPIO_MAP[0]));

  // Initialize in RS232 mode.
  usart_init_rs232(FTDI_USART, &FTDI_USART_OPTIONS, FPBA_HZ);
}

// initialize spi1: OLED, ADC, SD/MMC
extern void init_spi1 (void) {
  
  static const gpio_map_t OLED_SPI_GPIO_MAP = {
    {OLED_SPI_SCK_PIN,  OLED_SPI_SCK_FUNCTION },
    {OLED_SPI_MISO_PIN, OLED_SPI_MISO_FUNCTION},
    {OLED_SPI_MOSI_PIN, OLED_SPI_MOSI_FUNCTION},
    {OLED_SPI_NPCS0_PIN,  OLED_SPI_NPCS0_FUNCTION },
    {OLED_SPI_NPCS1_PIN,  OLED_SPI_NPCS1_FUNCTION },
    {OLED_SPI_NPCS2_PIN,  OLED_SPI_NPCS2_FUNCTION },
  };

  // SPI options for OLED
  spi_options_t spiOptions = {
    .reg = OLED_SPI_NPCS,
    .baudrate     = 40000000,
    .bits = 8,
    .trans_delay = 0,
    .spck_delay = 0,
    .stay_act = 1,
    .spi_mode = 3,
    .modfdis = 1
  };

  // Assign GPIO to SPI.
  gpio_enable_module(OLED_SPI_GPIO_MAP,
		     sizeof(OLED_SPI_GPIO_MAP) / sizeof(OLED_SPI_GPIO_MAP[0]));
  // Initialize as master.
  spi_initMaster(OLED_SPI, &spiOptions);
  // Set SPI selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(OLED_SPI, 0, 0, 0);
  // Enable SPI module.
  spi_enable(OLED_SPI);

  // setup chip register for OLED
  spi_setupChipReg( OLED_SPI, &spiOptions, FPBA_HZ );

  // add ADC chip register
  spiOptions.reg          = ADC_SPI_NPCS;
  spiOptions.baudrate     = 20000000;
  spiOptions.bits         = 16;
  spiOptions.spi_mode     = 2;
  spiOptions.spck_delay   = 0;
  spiOptions.trans_delay  = 5;
  spiOptions.stay_act     = 0;
  spiOptions.modfdis      = 0;

  spi_setupChipReg( ADC_SPI, &spiOptions, FPBA_HZ );

  // add SD/MMC chip register
  spiOptions.reg         = SD_MMC_SPI_NPCS;
  spiOptions.baudrate    = SD_MMC_SPI_MASTER_SPEED; // Defined in conf_sd_mmc_spi.h;
  spiOptions.bits        = SD_MMC_SPI_BITS; // Defined in conf_sd_mmc_spi.h;
  spiOptions.spck_delay  = 0;
  spiOptions.trans_delay = 0;
  spiOptions.stay_act    = 1;
  spiOptions.spi_mode    = 0;
  spiOptions.modfdis     = 1;

  // Initialize SD/MMC driver with SPI clock (PBA).
  sd_mmc_spi_init(spiOptions, FPBA_HZ);
}


// init PDCA (Peripheral DMA Controller A) resources for the SPI transfer and start a dummy transfer
void init_local_pdca(void)
{
  // PDCA channel for SPI RX
  pdca_channel_options_t pdca_options_SPI_RX ={ // pdca channel options
    .addr = (void *)&pdcaRxBuf,
    .size = FS_BUF_SIZE,                      // transfer size
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_RX,        // select peripheral ID - SPI1 RX
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // PDCA channel for SPI TX
  pdca_channel_options_t pdca_options_SPI_TX ={ // pdca channel options
    .addr = (void *)&pdcaTxBuf,               // memory address.
    .size = FS_BUF_SIZE,                      // transfer size
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_TX,        // select peripheral ID - SPI1 TX
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // Init PDCA transmission channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_TX, &pdca_options_SPI_TX);

  // Init PDCA Reception channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_RX, &pdca_options_SPI_RX);
}

// intialize resources for bf533 communication: SPI, GPIO
void init_bfin_resources(void) {
  static const gpio_map_t BFIN_SPI_GPIO_MAP = {
    { BFIN_SPI_SCK_PIN, BFIN_SPI_SCK_FUNCTION },
    { BFIN_SPI_MISO_PIN, BFIN_SPI_MISO_FUNCTION },
    { BFIN_SPI_MOSI_PIN, BFIN_SPI_MOSI_FUNCTION },
    { BFIN_SPI_NPCS0_PIN, BFIN_SPI_NPCS0_FUNCTION },
  };
  
  spi_options_t spiOptions = {
    .reg          = BFIN_SPI_NPCS,
    //// FIXME: 
    //// would prefer fast baudrate / lower trans delay during boot,
    //// but need multiple registers for boot (fast) and run (slow)
    //// investigate if this is possible...
    //   .baudrate     = 20000000,
    //     .baudrate     = 10000000,
    //     .baudrate     = 5000000,
     .baudrate     = 20000000,
    .bits         = 8,
    .spck_delay   = 0,
    //    .trans_delay  = 0,
    .trans_delay = 20,
    .stay_act     = 1,
    .spi_mode     = 1,
    .modfdis      = 1
  };

  // assign pins to SPI.
  gpio_enable_module(BFIN_SPI_GPIO_MAP,
		     sizeof(BFIN_SPI_GPIO_MAP) / sizeof(BFIN_SPI_GPIO_MAP[0]));

  // intialize as master
  spi_initMaster(BFIN_SPI, &spiOptions);

  // set selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(BFIN_SPI, 0, 0, 0);

  // enable SPI.
  spi_enable(BFIN_SPI);

  // intialize the chip register
  spi_setupChipReg(BFIN_SPI, &spiOptions, FPBA_HZ);
  // enable pulldown on bfin HWAIT line
  //// shit! not implemented... 
  // gpio_enable_pin_pull_down(BFIN_HWAIT_PIN);
  
  // enable pullup on bfin RESET line
  gpio_enable_pin_pull_up(BFIN_RESET_PIN);
}

// intialize two-wire interface
void init_twi(void) {
  // TWI/I2C GPIO map
  static const gpio_map_t TWI_GPIO_MAP = {
    { TWI_DATA_PIN, TWI_DATA_FUNCTION },
    { TWI_CLOCK_PIN, TWI_CLOCK_FUNCTION }
  };
  gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0]));
}


// initialize USB host stack
void init_usb_host (void) {
  //  pm_configure_usb_clock();
  uhc_start();
}