Example #1
0
File: lin.c Project: InSoonPark/asf
__interrupt
#endif
static void lin_pdca_int_rx_handler_node1(void)
{
  U8 index = 0;
  U8 l_handle = 0xFF;
  // Check ID Value for the current message
  for(index = 0; index < NUMBER_OF_LIN_FRAMES_NODE1; index ++)
  {
      if(lin_descript_list_node1[index].l_id == usart_lin_get_id_char(usart_lin_node1))
      {
          l_handle = index;
                    break;
      }
  }

  // Check if the ID received is registered into the lin description list
  if (l_handle!=0xFF)
  {
    if (pdca_get_transfer_status(USART_LIN_NODE1_RX_PDCA_CHANNEL)&PDCA_TRANSFER_COMPLETE)
    {
        pdca_disable_interrupt_transfer_complete(USART_LIN_NODE1_RX_PDCA_CHANNEL);
        lin_get_response (1,lin_descript_list_node1[l_handle].l_pt_data);
        // Start of the associated task
        lin_descript_list_node1[l_handle].l_pt_function(lin_descript_list_node1[l_handle].l_pt_data);
        lin_handle_node1 = 0xFF;  // End of communication
    }
  }
}
Example #2
0
void  aic23b_dac_mute(bool mute)
{
#if (AIC23B_MODE==AIC23B_MODE_DAC)
/*  if(mute==true) {
    pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);
  }
  else {
       pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);
  }
*/
  if (mute)
  {
    uint32_t save_dac_reload_callback_opt;

    // Disable the reload callback function
    save_dac_reload_callback_opt = aic23b_output_params.callback_opt;
    aic23b_output_params.callback_opt = 0;
    // Disable the transfer complete interruption and wait until the transfer is complete
    pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
    while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
    // Re-enable the reload callback function
    aic23b_output_params.callback_opt = save_dac_reload_callback_opt;
  }
  else
  {
    // Re-enable the reload interrupt
    pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
  }

#endif
}
Example #3
0
//this gets an experiment, plus additional data, from the host
//A full cluster will be transferred
void get_experiment_from_host_to_SD(void)
{
	USB_USART->rtor=0; //going to use PDCA for receiving data, so disable receive timeout
	pdca_disable(USB_USART_RX_PDCA_CHANNEL);
	my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&bank0[0]),samplebuffer_size, 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
	
	pdca_disable(USB_USART_RX_PDCA_CHANNEL);	//reset USART RX channel to receive host commands
	
	USB_USART->cr|=AVR32_USART_CR_STTTO_MASK;	//changing back to receiving command mode
	USB_USART->rtor=15000; //so reenable timeout
	
	pdca_load_channel(USB_USART_RX_PDCA_CHANNEL, (&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)));
	pdca_enable(USB_USART_RX_PDCA_CHANNEL);
	
	spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS);
	while(check_busy_fast()!=0xFF);
	spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS);
	
	my_SD_SPI_block_write_multi(bank0,experiment_base_address,blocks_per_cluster);	//write data to SD
	
	spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS);
	while(check_busy_fast()!=0xFF);
	spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS);
}
Example #4
0
ISR(tpa6130_abdac_tx_pdca_int_handler, TPA6130_ABDAC_PDCA_IRQ_GROUP, TPA6130_ABDAC_PDCA_INT_LEVEL)
{
  if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
  {
    pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
    if (tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
      tpa6130_output_param.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
  }

  if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
  {
    pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
    if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
      tpa6130_output_param.callback(AUDIO_DAC_RELOAD_CB);
  }
}
Example #5
0
File: ms3.c Project: avrxml/asf
void ms3_dac_mute(bool mute)
{
	if (mute) {
		U32 save_dac_reload_callback_opt;

		// Mute all channels
		// ms3_write_reg(MS3_MUTE_VOL_CTRL, 0xAF);

		// Disable the reload callback function
		save_dac_reload_callback_opt = ms3_output_params.callback_opt;
		ms3_output_params.callback_opt = 0;
		// Disable the transfer complete interruption and wait until the transfer is complete
		pdca_disable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL);
		while (!(pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
		// Re-enable the reload callback function
		ms3_output_params.callback_opt = save_dac_reload_callback_opt;
		// Set as gpio pin
		gpio_enable_gpio(MS3_GPIO_MAP, sizeof(MS3_GPIO_MAP) / sizeof(MS3_GPIO_MAP[0]));
	}
	else {
		// Re-enable the reload interrupt
		pdca_enable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL);
		// Unmute all channels
		// ms3_write_reg(MS3_MUTE_VOL_CTRL, 0xA0);
		// Enable SSC interface
		gpio_enable_module(MS3_GPIO_MAP, sizeof(MS3_GPIO_MAP) / sizeof(MS3_GPIO_MAP[0]));
	}
}
Example #6
0
void aic23b_dac_flush(void)
{
  pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
  pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);

  while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
           PDCA_TRANSFER_COMPLETE));
}
Example #7
0
__interrupt
#endif
static void aic23b_ssc_rx_pdca_int_handler(void)
{
  if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
  {
    pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
    if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
      aic23b_output_params.callback(AUDIO_ADC_OUT_OF_SAMPLE_CB);
  }

  if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
  {
    pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
    if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
      aic23b_output_params.callback(AUDIO_ADC_RELOAD_CB);
  }
}
Example #8
0
File: ms3.c Project: avrxml/asf
__interrupt
#endif
static void ms3_ssc_tx_pdca_int_handler(void)
{
	if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
	{
		pdca_disable_interrupt_transfer_complete(MS3_SSC_TX_PDCA_CHANNEL);
		if (ms3_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
			ms3_output_params.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
	}

	if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
	{
		pdca_disable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL);
		if (ms3_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
			ms3_output_params.callback(AUDIO_DAC_RELOAD_CB);
	}
}
Example #9
0
bool aic23b_adc_input(void *sample_buffer, size_t sample_length)
{
  if (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
        PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
    return false;

  if (sample_length)
  {
    pdca_reload_channel(AIC23B_SSC_RX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
    pdca_get_reload_size(AIC23B_SSC_RX_PDCA_CHANNEL);

    if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
      pdca_enable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
    if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
      pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
  }

  return true;
}
Example #10
0
void aic23b_dac_start(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t arg),
                      uint32_t callback_opt,
                      uint32_t pba_hz)
{
#if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
  static const spi_options_t AIC23B_SPI_OPTIONS =
  {
    .reg          = AIC23B_SPI_NPCS,
    .baudrate     = AIC23B_SPI_MASTER_SPEED,
    .bits         = AIC23B_CTRL_SIZE,
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 0,
    .spi_mode     = 3,
    .modfdis      = 1
  };
  spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
#endif

  aic23b_dac_stop();

  gpio_enable_module(AIC23B_SSC_DAC_GPIO_MAP,
                     sizeof(AIC23B_SSC_DAC_GPIO_MAP) / sizeof(AIC23B_SSC_DAC_GPIO_MAP[0]));

  aic23b_pdc_t pdc;
  pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
  pdc.off   = 0;
  pdc.clk   = 0;
  pdc.osc   = 0;
  pdc.out   = 0;
  pdc.dac   = 0;
  pdc.adc   = 1;
  pdc.mic   = 1;
  pdc.line  = 1;
  aic23b_set_power_down_state(pdc);

  aic23b_dac_setup(sample_rate_hz,
                   num_channels,
                   bits_per_sample,
                   swap_channels,
                   callback,
                   callback_opt,
                   pba_hz);

  aic23b_aapc_t aapc;
  aapc.data = AIC23B_DEFAULT(AIC23B_AAPC);
  aapc.ste  = 0;
  aapc.dac  = 1;
  aapc.byp  = 0;
  aapc.micm = 1;
  aapc.micb = 0;
  aic23b_set_analog_audio_path(aapc);

  aic23b_dapc_t dapc;
  dapc.data   = AIC23B_DEFAULT(AIC23B_DAPC);
  dapc.dacm   = 0;
  dapc.deemp  = AIC23B_DAPC_DEEMP_NONE;
  dapc.adchp  = 1;
  aic23b_set_digital_audio_path(dapc);

  // set an acceptable start volume
  aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
                              -30,
                              true);

  aic23b_activate_dig_audio(true);

  INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler,
                          AIC23B_SSC_TX_PDCA_IRQ,
                          AIC23B_SSC_TX_PDCA_INT_LEVEL);
}


void aic23b_dac_setup(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t arg),
                      uint32_t callback_opt,
                      uint32_t pba_hz)
{
#if defined(AIC23B_DAC_USE_RX_CLOCK) && AIC23B_DAC_USE_RX_CLOCK == true
  #if defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK)
    AIC23B_DAC_RX_CLOCK_SET_CALLBACK(2 * sample_rate_hz *
                                     ((bits_per_sample <= 16) ? 16 :
                                     (bits_per_sample <= 20) ? 20 :
                                     (bits_per_sample <= 24) ? 24 :
                                     32));
  #endif
  ssc_i2s_init(AIC23B_SSC,
               sample_rate_hz,
               bits_per_sample,
               (bits_per_sample <= 16) ? 16 :
               (bits_per_sample <= 20) ? 20 :
               (bits_per_sample <= 24) ? 24 :
                                         32,
               SSC_I2S_MODE_STEREO_OUT_EXT_CLK,
               pba_hz);
#else
  ssc_i2s_init(AIC23B_SSC,
               sample_rate_hz,
               bits_per_sample,
               (bits_per_sample <= 16) ? 16 :
               (bits_per_sample <= 20) ? 20 :
               (bits_per_sample <= 24) ? 24 :
                                         32,
               SSC_I2S_MODE_STEREO_OUT,
               pba_hz);
#endif

  pdca_channel_options_t aic23b_ssc_pdca_options =
  {
    .addr           = NULL,
    .size           = 0,
    .r_addr         = NULL,
    .r_size         = 0,
    .pid            = AIC23B_SSC_TX_PDCA_PID,
    .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
                      (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
                                                PDCA_TRANSFER_SIZE_WORD
  };
  pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options);
  pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);

#if !defined(AIC23B_DAC_USE_RX_CLOCK) || AIC23B_DAC_USE_RX_CLOCK == false || \
    !defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK)
  // Set DAC frequency
  aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);
#endif

  aic23b_daif_t daif;
  daif.data   = AIC23B_DEFAULT(AIC23B_DAIF);
  daif.ms     = AIC23B_DAIF_MS_SLAVE;
  daif.lrswap = swap_channels;
  daif.lrp    = 0;
  daif.iwl    = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
                (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
                (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
                                          AIC23B_DAIF_IWL_32;
  daif.fmt    = AIC23B_DAIF_FMT_I2S;
  aic23b_write_reg(AIC23B_DAIF, daif.data);

  aic23b_output_params.num_channels             = num_channels;
  aic23b_output_params.callback                 = callback;
  aic23b_output_params.callback_opt             = callback_opt;
}
#endif

bool aic23b_dac_output(void *sample_buffer, size_t sample_length)
{
  bool global_interrupt_enabled;

  if (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
        PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
    return false;

  if (sample_length)
  {
    if (aic23b_output_params.num_channels == 1)
    {
      int16_t *s16_sample_buffer = sample_buffer;
      int i;

      for (i = sample_length - 1; i >= 0; i--)
      {
        s16_sample_buffer[2 * i + 1] =
        s16_sample_buffer[2 * i]     = s16_sample_buffer[i];
      }
    }

    // The PDCA is not able to synchronize its start of transfer with the SSC
    // start of period, so this has to be done by polling the TF pin.
    // Not doing so may result in channels being swapped randomly.
    if ((global_interrupt_enabled = Is_global_interrupt_enabled()))
      Disable_global_interrupt();
    if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
        PDCA_TRANSFER_COMPLETE)
    {
      while (gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
      while (!gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
    }
    pdca_reload_channel(AIC23B_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
    pdca_get_reload_size(AIC23B_SSC_TX_PDCA_CHANNEL);
    if (global_interrupt_enabled)
      Enable_global_interrupt();

    if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
      pdca_enable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
    if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
      pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
  }
  return true;
}
Example #11
0
void idle(void)
	{
	while(1)
	{
		uint8_t tempmode=0;
	
		while(tempmode==0)	//wait until a command has been received
		{
			if(lcdinit==false) //check for LCD
			{
				if(detect_lcd()==true)
				{
					usart_write_line(LCD_USART, "play modesel\r\n");
					lcdinit=true;
				}
			}
			tempmode=idle_getmode();
		}
		uint8_t tempsd=check_SD();
		
		switch(tempmode) {
			case start_hostmode:
				if(tempsd!=SD_card_valid)
				{
					usart_write_line(USB_USART, "bad SD card\n");
				}
				else
				{
					usart_write_line(USB_USART, "good SD card\n");
					hostmode_run();
					//go to host execution
				}	
				break;

			case select_standalone:
				if(tempsd==SD_card_valid)
				{	//valid SD card detected
					//retrieve experiment from SD card
					my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank0[0]), sizeof(experiment), blocks_per_cluster);
					if(validate_sequences()==false)
					{	//sequence was not valid
						usart_write_line(LCD_USART, "play badexp\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						usart_write_line(LCD_USART, "play modesel\r\n");
					}
					else
					{	//sequence was valid
						usart_write_line(LCD_USART, "play goodexp\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						standalone_mode_run();
					
						//re-enable USB USART to receive commands from host
						pdca_load_channel(USB_USART_RX_PDCA_CHANNEL, (&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)));
						pdca_enable(USB_USART_RX_PDCA_CHANNEL);
						USB_USART->cr|=AVR32_USART_CR_STTTO_MASK;	//set to not start counting again until after new character is received
						USB_USART->rtor=15000; //baud rate is 3mbaud, so 15000 gives 5ms timeout
					
						usart_write_line(LCD_USART, "play modesel\r\n");
						//will eventually have branch here to cancel, examine experiment, or proceed
					}
				}
				else if(tempsd==SD_card_not_inserted)
				{	//no SD card inserted
					usart_write_line(LCD_USART, "play noSD\r\n");
					while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
					usart_write_line(LCD_USART, "play modesel\r\n");
				}
				else if(tempsd==SD_card_init_failed)
				{	//SD card failed to init
					usart_write_line(LCD_USART, "play SDerr\r\n");
					while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
					usart_write_line(LCD_USART, "play modesel\r\n");
				}
				else if(tempsd==SD_card_invalid)
				{	//SD card init but not valid
					usart_write_line(LCD_USART, "play badSD\r\n");
					while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
					usart_write_line(LCD_USART, "play modesel\r\n");
				}	
				break;
				
			case select_checkSD:
				switch (tempsd) {
					case  SD_card_valid:
						usart_write_line(LCD_USART, "play goodSD\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						usart_write_line(LCD_USART, "play modesel\r\n");
						break;
					case SD_card_not_inserted:
						usart_write_line(LCD_USART, "play noSD\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						usart_write_line(LCD_USART, "play modesel\r\n");
						break;
					case SD_card_init_failed:
						usart_write_line(LCD_USART, "play SDerr\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						usart_write_line(LCD_USART, "play modesel\r\n");
						break;
					case SD_card_invalid:
						usart_write_line(LCD_USART, "play badSD\r\n");
						while(strcmp(get_LCD_cmd(),"BR2\r")!=0);
						usart_write_line(LCD_USART, "play modesel\r\n");
						break;
				}	
				break;

			case program_experiment:
				if(tempsd!=SD_card_valid)
				{
					usart_write_line(USB_USART, "bad SD card\n");
				}
				else
				{
					usart_write_line(USB_USART, "good SD card\n");
					get_experiment_from_host_to_SD();
				
					my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank1[0]), sizeof(experiment), blocks_per_cluster);
				
					if(validate_sequences()==true)
					{
						usart_write_line(USB_USART, "goodexp\n");
					}
					else
					{
						usart_write_line(USB_USART, "badexp\n");
					}
				}
				break;

			case get_data:
				if(tempsd!=SD_card_valid)
				{
					usart_write_line(USB_USART, "bad SD card\n");	//if SD card is bad, say so and return
				}
				else
				{//if SD card is good, say so.  Then read the experiment and validate it
					usart_write_line(USB_USART, "good SD card\n");	
					//this will read in entire first cluster of SD
					my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank1[0]), sizeof(experiment), blocks_per_cluster);
				
					if(validate_sequences()==true)
					{	//if experiment is valid, say so, then get true experiment
						usart_write_line(USB_USART, "goodexperiment\n");
						gettruesequence();
						//send entire cluster's worth of data to host.  this will start with experiment and also include other "stuff" in the first cluster
						pdca_disable(USB_USART_TX_PDCA_CHANNEL);//goin to set up PDCA to send all of experiment, then start reading out bank1 until an entire cluster has been written
						my_pdca_init_channel(USB_USART_TX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_TX_PDCA_PID,   (uint32_t)(&bank1[0]),  (blocks_per_cluster*512-(uint32_t)(sizeof(experiment))), 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);
					
						for(uint8_t i=0;i<Nsequences_max;i++)
						{
							usart_putchar(USB_USART,(uint8_t)(t_experiment.t_sequence[i].clusters_per_sequence));
						}
					
						uint32_t SD_read_ptr=data_base_address;
					
						//now need to send actual data
						for(uint8_t i=0;i<t_experiment.N_experiments;i++)
						{
							for(uint8_t j=0;j<t_experiment.N_sequences;j++)
							{
								while(strcmp(get_HOST_cmd(),"SEND SEQUENCE\n")!=0); //wait for host to ask for each sequence
								send_data_to_host(SD_read_ptr,t_experiment.t_sequence[j].clusters_per_sequence);
								SD_read_ptr+=t_experiment.t_sequence[j].clusters_per_sequence*blocks_per_cluster*bytes_per_block;
							}
						}
					}
					else
					{
						usart_write_line(USB_USART, "badexperiment\n");
					}
				}
				break;		
		}
	}
}
Example #12
0
File: ms3.c Project: avrxml/asf
void ms3_dac_setup(U32 sample_rate_hz, U8 num_channels, U8 bits_per_sample,
		bool swap_channels, void (*callback)(U32 arg), U32 callback_opt,
		U32 pba_hz)
{
	//configure clock
	if (sample_rate_hz < (8000 + 8021) / 2) {
		usb_stream_resync_frequency = 4096000;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}
	else if (sample_rate_hz < (8021 + 22050) / 2) {
		usb_stream_resync_frequency = 4106752;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}
	else if (sample_rate_hz < (22050 + 32000) / 2) {
		usb_stream_resync_frequency = 11289600;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}
	else if (sample_rate_hz < (32000 + 44100) / 2) {
		usb_stream_resync_frequency = 16384000;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}
	else if (sample_rate_hz < (44100 + 48000) / 2) {
		usb_stream_resync_frequency = 22579200;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}
	else if (sample_rate_hz < (48000 + 88200) / 2) {
		usb_stream_resync_frequency = 24576000;
		cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF));
	}

	//configure ssc to use clock on TX_CLOCK pin
	AVR32_SSC.tcmr = (0 << AVR32_SSC_TCMR_CKO_OFFSET)
			| (1 << AVR32_SSC_TCMR_STTDLY_OFFSET)
			| (2 << AVR32_SSC_TCMR_CKS_OFFSET)
			| (7 << AVR32_SSC_TCMR_START_OFFSET)
			| (0x1f << AVR32_SSC_TCMR_PERIOD_OFFSET);

	AVR32_SSC.tfmr = (0xf << AVR32_SSC_TFMR_DATLEN_OFFSET)
			| (1 << AVR32_SSC_TFMR_MSBF_OFFSET)
			| (1 << AVR32_SSC_TFMR_FSOS_OFFSET)
			| (1 << AVR32_SSC_TFMR_FSLENHI_OFFSET)
			| (0xf << AVR32_SSC_TFMR_FSLEN_OFFSET);

	AVR32_SSC.cr = AVR32_SSC_CR_TXEN_MASK;

	//configure DMA
	pdca_channel_options_t ms3_ssc_pdca_options = {
		.addr = NULL,
		.size = 0,
		.r_addr = NULL,
		.r_size = 0,
		.pid = AVR32_PDCA_PID_SSC_TX,
		.transfer_size = (bits_per_sample <=  8)?PDCA_TRANSFER_SIZE_BYTE:
				(bits_per_sample <= 16)?PDCA_TRANSFER_SIZE_HALF_WORD:
				PDCA_TRANSFER_SIZE_WORD
	};
	pdca_init_channel(MS3_SSC_TX_PDCA_CHANNEL, &ms3_ssc_pdca_options);
	pdca_enable(MS3_SSC_TX_PDCA_CHANNEL);

	//configure audio parameters
	ms3_output_params.num_channels = num_channels;
	ms3_output_params.callback = callback;
	ms3_output_params.callback_opt = callback_opt;
}

bool ms3_dac_output(void *sample_buffer, size_t sample_length)
{
	bool global_interrupt_enabled;

	if (!(pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) &
			PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
		return false;

	if (sample_length) {
		if (ms3_output_params.num_channels == 1) {
			S16 *s16_sample_buffer = sample_buffer;
			int i;

			for (i = sample_length - 1; i >= 0; i--) {
				s16_sample_buffer[2 * i + 1] =
						s16_sample_buffer[2 * i] =
						s16_sample_buffer[i];
			}
		}

		// The PDCA is not able to synchronize its start of transfer with the SSC
		// start of period, so this has to be done by polling the TF pin.
		// Not doing so may result in channels being swapped randomly.
		if ((global_interrupt_enabled = Is_global_interrupt_enabled()))
			Disable_global_interrupt();

		if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) &
				PDCA_TRANSFER_COMPLETE) {
			while (gpio_get_pin_value(MS3_SSC_TX_FRAME_SYNC_PIN));
			while (!gpio_get_pin_value(MS3_SSC_TX_FRAME_SYNC_PIN));
		}

		pdca_reload_channel(MS3_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
		pdca_get_reload_size(MS3_SSC_TX_PDCA_CHANNEL);
		if (global_interrupt_enabled)
			Enable_global_interrupt();

		if (ms3_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
			pdca_enable_interrupt_transfer_complete(MS3_SSC_TX_PDCA_CHANNEL);
		if (ms3_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
			pdca_enable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL);
	}

	return true;
}
void aic23b_codec_start(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t arg),
                      uint32_t callback_opt,
                      uint32_t pba_hz)
{
#if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
  static const spi_options_t AIC23B_SPI_OPTIONS =
  {
    .reg          = AIC23B_SPI_NPCS,
    .baudrate     = AIC23B_SPI_MASTER_SPEED,
    .bits         = AIC23B_CTRL_SIZE,
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 0,
    .spi_mode     = 3,
    .modfdis      = 1
  };
  spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
#endif

  aic23b_codec_stop();

  gpio_enable_module(AIC23B_SSC_CODEC_GPIO_MAP,
                     sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));

  aic23b_pdc_t pdc;
  pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
  pdc.off   = 0;
  pdc.clk   = 0;
  pdc.osc   = 0;
  pdc.out   = 0;
  pdc.dac   = 0;
  pdc.adc   = 0;
#if (AIC23B_INPUT==AIC23B_INPUT_LINE)
  pdc.mic   = 1;
  pdc.line  = 0;
#elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
  pdc.mic   = 0;
  pdc.line  = 1;
#else
  #error No Input defined in file 'conf_tlv320aic23b.h'
#endif
  aic23b_set_power_down_state(pdc);

  aic23b_codec_setup(sample_rate_hz,
                   num_channels,
                   bits_per_sample,
                   swap_channels,
                   callback,
                   callback_opt,
                   pba_hz);

  aic23b_aapc_t aapc;
  aapc.data  = AIC23B_DEFAULT(AIC23B_AAPC);
#if (AIC23B_INPUT==AIC23B_INPUT_LINE)
  aapc.ste   = 0;
  aapc.dac   = 1;
  aapc.byp   = 0;
  aapc.insel = 0;
  aapc.micm  = 0;
  aapc.micb  = 1;
#elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
  aapc.ste   = 0;
  aapc.dac   = 1;
  aapc.sta   = 4;
  aapc.byp   = 0;
  aapc.insel = 1;
  aapc.micm  = 0;
  aapc.micb  = 1;
#else
  #error No Input defined in file 'conf_tlv320aic23b.h'
#endif
  aic23b_set_analog_audio_path(aapc);

  aic23b_dapc_t dapc;
  dapc.data   = AIC23B_DEFAULT(AIC23B_DAPC);
  dapc.dacm   = 0;
  dapc.deemp  = AIC23B_DAPC_DEEMP_NONE;
  dapc.adchp  = 0;
  aic23b_set_digital_audio_path(dapc);


  aic23b_llicvc_t llivc;
  llivc.data  = AIC23B_DEFAULT(AIC23B_LLICVC);
  llivc.liv   = 20;
  llivc.lim   = 0;
  llivc.lrs   = 1;
  aic23b_write_reg(AIC23B_LLICVC, llivc.data);

  aic23b_rlicvc_t rlivc;
  rlivc.data  = AIC23B_DEFAULT(AIC23B_RLICVC);
  rlivc.riv   = 20;
  rlivc.rim   = 0;
  rlivc.rls   = 1;
  aic23b_write_reg(AIC23B_RLICVC, rlivc.data);

  INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler,
                          AIC23B_SSC_RX_PDCA_IRQ,
                          AIC23B_SSC_RX_PDCA_INT_LEVEL);

  // set an acceptable start volume
  aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
                              -30,
                              true);

  aic23b_activate_dig_audio(true);

  INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler,
                          AIC23B_SSC_TX_PDCA_IRQ,
                          AIC23B_SSC_TX_PDCA_INT_LEVEL);
}

void aic23b_codec_setup(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t opt),
                      uint32_t callback_opt,
                      uint32_t pba_hz)
{
  uint32_t master_clock = AIC23B_MCLK_HZ; // default configuration

  // Change the CPU frequency
  //
  //Disable_global_interrupt();

  // Switch to OSC0 during OSC1 transition
  //pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

  // Switch to PLL0 as the master clock
  //pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0);

  if (sample_rate_hz < (8000 + 8021) / 2)
  { // 8000 Hz
  }
  else if (sample_rate_hz < (8021 + 32000) / 2)
  { // 8021 Hz
  }
  else if (sample_rate_hz < (32000 + 44100) / 2)
  { // 32000 Hz
    master_clock = usb_stream_resync_frequency = 8192000;
    cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0));
    pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(8192000);
  }
  else if (sample_rate_hz < (44100 + 48000) / 2)
  { // 44100 Hz
    master_clock = usb_stream_resync_frequency = 11289600;
    cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0));
    pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(11289600);
  }
  else if (sample_rate_hz < (48000 + 88200) / 2)
  { // 48000 Hz
    master_clock = usb_stream_resync_frequency = 12288000;
    cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0));
    pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(12288000);
  }
  else if (sample_rate_hz < (88200 + 96000) / 2)
  { // 88200 Hz
  }
  else
  { // 96000 Hz
  }

  //Enable_global_interrupt();

  ssc_i2s_init(AIC23B_SSC,
               sample_rate_hz,
               bits_per_sample,
               (bits_per_sample <= 16) ? 16 :
               (bits_per_sample <= 20) ? 20 :
               (bits_per_sample <= 24) ? 24 :
                                         32,
               SSC_I2S_MODE_STEREO_OUT_STEREO_IN,
               pba_hz);

  pdca_channel_options_t aic23b_ssc_pdca_options_rx =
  {
    .addr           = NULL,
    .size           = 0,
    .r_addr         = NULL,
    .r_size         = 0,
    .pid            = AIC23B_SSC_RX_PDCA_PID,
    .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
                      (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
                                                PDCA_TRANSFER_SIZE_WORD

  };
  pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_rx);
  pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL);

  pdca_channel_options_t aic23b_ssc_pdca_options_tx =
  {
    .addr           = NULL,
    .size           = 0,
    .r_addr         = NULL,
    .r_size         = 0,
    .pid            = AIC23B_SSC_TX_PDCA_PID,
    .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
                      (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
                                                PDCA_TRANSFER_SIZE_WORD
  };
  pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_tx);
  pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);

  // Set codec frequency
  aic23b_configure_freq(master_clock, sample_rate_hz);

  aic23b_daif_t daif;
  daif.data   = AIC23B_DEFAULT(AIC23B_DAIF);
  daif.ms     = AIC23B_DAIF_MS_SLAVE;
  daif.lrswap = swap_channels;
  daif.lrp    = 0;
  daif.iwl    = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
                (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
                (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
                                          AIC23B_DAIF_IWL_32;
  daif.fmt    = AIC23B_DAIF_FMT_I2S;
  aic23b_write_reg(AIC23B_DAIF, daif.data);

  aic23b_output_params.num_channels              = num_channels;
  aic23b_output_params.callback                  = callback;
  aic23b_output_params.callback_opt              = callback_opt;
}

void aic23b_codec_flush(void)
{
  pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
  while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
           PDCA_TRANSFER_COMPLETE));
  pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
  while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
           PDCA_TRANSFER_COMPLETE));
}

void aic23b_codec_stop(void)
{
  aic23b_codec_flush();

  aic23b_reset();

  aic23b_pdc_t pdc;
  pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
  pdc.off   = 1;
  pdc.clk   = 1;
  pdc.osc   = 1;
  pdc.out   = 1;
  pdc.dac   = 1;
  pdc.adc   = 1;
  pdc.mic   = 1;
  pdc.line  = 1;
  aic23b_set_power_down_state(pdc);

  pdca_disable(AIC23B_SSC_RX_PDCA_CHANNEL);
  pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);

  ssc_i2s_reset(AIC23B_SSC);

  gpio_enable_gpio(AIC23B_SSC_CODEC_GPIO_MAP,
                   sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));

  aic23b_output_params.num_channels             = 0;
  aic23b_output_params.callback                 = NULL;
  aic23b_output_params.callback_opt             = 0;
}
Example #14
0
/*! \brief Sets the DACs up with new settings.
 *
 * \note The DACs must have been started beforehand.
 */
void tpa6130_dac_setup(uint32_t sample_rate_hz,
                       uint8_t num_channels,
                       uint8_t bits_per_sample,
                       bool swap_channels,
                       void (*callback)(uint32_t arg),
                       uint32_t callback_opt,
                       uint32_t pba_hz)
{
  // save input parameters to local driver data
  tpa6130_output_param.num_channels = num_channels;
  tpa6130_output_param.callback     = callback;
  tpa6130_output_param.callback_opt = callback_opt;

  /* Probe for amplifier and initialize it */
  tpa6130_init();

#if defined(TPA6130_DAC_CLOCK_SET_CALLBACK)
  TPA6130_DAC_CLOCK_SET_CALLBACK(sample_rate_hz);
#else
  /* ABDAC configuration
   * The ABDAC needs the input frequency of its generic clock (bus_hz)
   * Here we use the configuration value from the conf_tpa6130.h file
   * (TPA6130_ABDAC_GCLK_INPUT_HZ).
   * The sample rate specifies the desired sample rate for the ABDAC.
   * The generic clock input must be greater than 256*sample_rate_hz
   * or the setup of the ABDAC will fail silently here.
   * TODO we could add asserts here to detect wrong settings during
   * compile time.
   */
  if(!abdac_set_dac_sample_rate(sample_rate_hz)) {
    // if it is not possible to set correctly the sample rate
    // Use default set function
    abdac_set_dac_hz(TPA6130_ABDAC, TPA6130_ABDAC_GCLK_INPUT_HZ,sample_rate_hz);
  }
#endif

  if(swap_channels)
  {
    abdac_swap_channels(TPA6130_ABDAC);
  }
  abdac_enable(TPA6130_ABDAC);

  /* PDCA setup */
  /*FIXME we use only word as transfer size for now.
   * half-word transfer size will only write to channel0
   * of the ABDAC, this can be used to implement mono */
  pdca_channel_options_t tpa6130_abdac_pdca_options =
  {
    .addr   = NULL,
    .size   = 0,
    .r_addr   = 0,
    .r_size   = 0,
    .pid    = TPA6130_ABDAC_PDCA_PID,
    .transfer_size  = PDCA_TRANSFER_SIZE_WORD
  };

  /* Initialize the PCDA for the ABDAC
   * The channel number can be set in the configuration file
   * with the define TPA6130_ABDAC_PDCA_CHANNEL.
   */
  pdca_init_channel(TPA6130_ABDAC_PDCA_CHANNEL,
    &tpa6130_abdac_pdca_options);
  /* Enable the PDCA channel. Since we did not provide any data
   * yet the channel is in idle mode */
  pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL);

}

/*! \brief Outputs a sample buffer to the DACs.
 * The input requires a sample buffer that consists of words (32-bit)
 * which contain two (16-bit) samples, one for each channel.
 *
 * \note The DACs must have been started beforehand.
 */
bool tpa6130_dac_output(void *sample_buffer, size_t sample_length)
{
  //int global_interrupt_enabled;

  /*Wait until the PDCA loads the reload value to its transfer
   * counter register(TCRR=0). Then we are ready to set up a new
   * transfer */
  if(!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) &
    PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
  {
    return false;
  }

  /* Nothing to do if we get no data. */
  if(sample_length)
  {

    /*TODO Do we really need to adjust the buffer for mono*/

    /* While reloading the PDC we do not need any active interrupt*/
    //if((global_interrupt_enabled = cpu_irq_is_enabled()))
    //  cpu_irq_disable();

    /*FIXME This assumes a stereo 16-bit sample size */
    // one sample here consists of 2x16-bit (16-bit stereo)
    pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,
      sample_buffer, sample_length);

    //if(global_interrupt_enabled)
    //  cpu_irq_enable();

    /*TODO enable transfer complete interrupt
     * Is it possible to move this to setup or other places?*/
    if(tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
      pdca_enable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
    if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
      pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
  }
  return true;
}

bool tpa6130_dac_is_volume_muted(void)
{
  return false;
}

void tpa6130_dac_mute(bool mute)
{
  // //1st Version Mute Audio for Play/Pause
/*  int volume=tpa6130_get_volume();
  if(mute==true) {
     //Mute volume
     volume= volume|MUTE_L|MUTE_R;
  }
  else {
     //Unmute volume
     volume= volume&(~(MUTE_L|MUTE_R));

  }
 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE,volume);
*/
  //2n Version Stop PDCA >> No lost of audio when pause
/*  if(mute==true) {
    pdca_disable(TPA6130_ABDAC_PDCA_CHANNEL);
  }
  else {
    pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL);
  }
*/

  // 3rd Version wait until the current buffers are empty and disable the interrupts
  int8_t volume = tpa6130_get_volume();
  if (mute)
  {
    uint32_t save_dac_reload_callback_opt;

    // Mute the audio stream
    volume = volume | MUTE_L | MUTE_R;
    tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
    // Disable the reload channel of the interrupt
    save_dac_reload_callback_opt = tpa6130_output_param.callback_opt;
    tpa6130_output_param.callback_opt = 0;
    // Disable the reload interruption and wait until the transfer is complete
    pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
    while (!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
    // Restore the reload callback function
    tpa6130_output_param.callback_opt = save_dac_reload_callback_opt;
  }
  else
  {
    // Re-enable the interrupts
    pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
    // Un-mute the audio stream
    volume = volume & (~(MUTE_L | MUTE_R));
    tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
  }
}
Example #15
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;	
}
Example #16
0
void aic23b_adc_start(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t arg),
                      uint32_t callback_opt,
                      uint32_t pba_hz)
{
#if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
  static const spi_options_t AIC23B_SPI_OPTIONS =
  {
    .reg          = AIC23B_SPI_NPCS,
    .baudrate     = AIC23B_SPI_MASTER_SPEED,
    .bits         = AIC23B_CTRL_SIZE,
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 0,
    .spi_mode     = 3,
    .modfdis      = 1
  };
  spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
#endif

  aic23b_adc_stop();

  gpio_enable_module(AIC23B_SSC_ADC_GPIO_MAP,
                     sizeof(AIC23B_SSC_ADC_GPIO_MAP) / sizeof(AIC23B_SSC_ADC_GPIO_MAP[0]));

  aic23b_pdc_t pdc;
  pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
  pdc.off   = 0;
  pdc.clk   = 0;
  pdc.osc   = 0;
  pdc.out   = 0;
  pdc.dac   = 1;
  pdc.adc   = 0;
#if (AIC23B_INPUT==AIC23B_INPUT_LINE)
  pdc.mic   = 1;
  pdc.line  = 0;
#elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
  pdc.mic   = 0;
  pdc.line  = 1;
#else
  #error No Input defined in file 'conf_tlv320aic23b.h'
#endif
  aic23b_set_power_down_state(pdc);

  aic23b_adc_setup(sample_rate_hz,
                   num_channels,
                   bits_per_sample,
                   swap_channels,
                   callback,
                   callback_opt,
                   pba_hz);

  aic23b_aapc_t aapc;
  aapc.data  = AIC23B_DEFAULT(AIC23B_AAPC);
#if (AIC23B_INPUT==AIC23B_INPUT_LINE)
  aapc.ste   = 0;
  aapc.dac   = 0;
  aapc.byp   = 0;
  aapc.insel = 0;
  aapc.micm  = 0;
  aapc.micb  = 0;
#elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
  aapc.ste   = 0;
  aapc.dac   = 0;
  aapc.byp   = 0;
  aapc.insel = 1;
  aapc.micm  = 0;
  aapc.micb  = 0;
#else
  #error No Input defined in file 'conf_tlv320aic23b.h'
#endif
  aic23b_set_analog_audio_path(aapc);

  aic23b_dapc_t dapc;
  dapc.data   = AIC23B_DEFAULT(AIC23B_DAPC);
  dapc.dacm   = 0;
  dapc.deemp  = AIC23B_DAPC_DEEMP_NONE;
  dapc.adchp  = 0;
  aic23b_set_digital_audio_path(dapc);


  aic23b_llicvc_t llivc;
  llivc.data  = AIC23B_DEFAULT(AIC23B_LLICVC);
  llivc.liv   = 20;
  llivc.lim   = 0;
  llivc.lrs   = 1;
  aic23b_write_reg(AIC23B_LLICVC, llivc.data);

  aic23b_rlicvc_t rlivc;
  rlivc.data  = AIC23B_DEFAULT(AIC23B_RLICVC);
  rlivc.riv   = 20;
  rlivc.rim   = 0;
  rlivc.rls   = 1;
  aic23b_write_reg(AIC23B_RLICVC, rlivc.data);

  INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler,
                          AIC23B_SSC_RX_PDCA_IRQ,
                          AIC23B_SSC_RX_PDCA_INT_LEVEL);

  aic23b_activate_dig_audio(true);

}

void aic23b_adc_setup(uint32_t sample_rate_hz,
                      uint8_t num_channels,
                      uint8_t bits_per_sample,
                      bool swap_channels,
                      void (*callback)(uint32_t arg),
                      callback_opt,
                      uint32_t pba_hz)
{
  ssc_i2s_init(AIC23B_SSC,
               sample_rate_hz,
               bits_per_sample,
               (bits_per_sample <= 16) ? 16 :
               (bits_per_sample <= 20) ? 20 :
               (bits_per_sample <= 24) ? 24 :
                                         32,
               SSC_I2S_MODE_STEREO_IN,
               pba_hz);

  pdca_channel_options_t aic23b_ssc_pdca_options =
  {
    .addr           = NULL,
    .size           = 0,
    .r_addr         = NULL,
    .r_size         = 0,
    .pid            = AIC23B_SSC_RX_PDCA_PID,
    .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
                      (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
                                                PDCA_TRANSFER_SIZE_WORD
  };
  pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options);
  pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL);

  // Set ADC frequency
  aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);

  aic23b_daif_t daif;
  daif.data   = AIC23B_DEFAULT(AIC23B_DAIF);
  daif.ms     = AIC23B_DAIF_MS_SLAVE;
  daif.lrswap = swap_channels;
  daif.lrp    = 0;
  daif.iwl    = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
                (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
                (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
                                          AIC23B_DAIF_IWL_32;
  daif.fmt    = AIC23B_DAIF_FMT_I2S;
  aic23b_write_reg(AIC23B_DAIF, daif.data);

  aic23b_output_params.num_channels              = num_channels;
  aic23b_output_params.callback                  = callback;
  aic23b_output_params.callback_opt              = callback_opt;
}

void aic23b_adc_flush(void)
{
  pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);

  while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
           PDCA_TRANSFER_COMPLETE));
}
Example #17
0
/******************************************************************************
    rn42_init
*//**
    @brief Initializes RN42 driver.

    @brief usart    Pointer to the USART hardware structure the RN42 is on.
    @brief irq      IRQ number to process interrupts on.
    @brief gpio_pin Pin connected to the RN42's status output.
******************************************************************************/
void
rn42_init(
    volatile avr32_usart_t *usart,
    uint32_t irq,
    uint32_t gpio_pin)
{ 
    static usart_options_t usart_options =
    {
        .baudrate     = 115200,
        .charlength   = 8,
        .paritytype   = USART_NO_PARITY,
        .stopbits     = USART_1_STOPBIT,
        .channelmode  = USART_NORMAL_CHMODE
    };

    static pdca_channel_options_t pdca_rx_options =
    {
        .pid = AVR32_PDCA_PID_USART3_RX,
        .addr = NULL,
        .size = 0,
        .r_addr = NULL,
        .r_size = 0,
        .transfer_size = PDCA_TRANSFER_SIZE_BYTE
    };

    static pdca_channel_options_t pdca_tx_options =
    {
        .pid = AVR32_PDCA_PID_USART3_TX,
        .addr = NULL,
        .size = 0,
        .r_addr = NULL,
        .r_size = 0,
        .transfer_size = PDCA_TRANSFER_SIZE_BYTE
    };

    /* Initialize the USART to use hardware handshaking. Without the
       handshaking, the RN42 has trouble keeping up when continuosly sending
       fairly small amounts of data. Note that when hardware handshaking is
       enabled, the PDCA must be used for receiving data.
     */
    rn42_usart = usart;
    usart_serial_init(rn42_usart, &usart_options);
    rn42_usart->mr = (rn42_usart->mr & ~0xf) | 0x02;

    /* Register the ISR for USART's DMA completion IRQs. */
    pdca_init_channel(PDCA_CHANNEL_RX, &pdca_rx_options);
    pdca_init_channel(PDCA_CHANNEL_TX, &pdca_tx_options);
    irq_register_handler(usart_isr, PDCA_IRQ, 0);

    setup_usart_rx_dma(bt_buf, sizeof(command_t));
    usart_irq_enable();
    pdca_enable(PDCA_CHANNEL_RX);
    pdca_enable(PDCA_CHANNEL_TX);

    /* Configure RN42 status GPIO. */
    gpio_configure_pin(gpio_pin, GPIO_DIR_INPUT | GPIO_PULL_DOWN);
    gpio_disable_pin_pull_up(gpio_pin);

    rn42_status_pin = gpio_pin;
}


/******************************************************************************
    rn42_connected
*//**
    @brief Returns whether the RN42 is connected by examining the status GPIO.

    The RN42's status line appears to bounce, so this function takes care of
    debouncing it.
******************************************************************************/
static bool
rn42_connected(void)
{
    bool connected1;
    bool connected2;

    do {
        connected1 = gpio_pin_is_high(rn42_status_pin);
        delay_ms(50);
        connected2 = gpio_pin_is_high(rn42_status_pin);
    } while (connected1 != connected2);

    return connected1 & connected2;
}


/******************************************************************************
    rn42_send_data
*//**
    @brief Transmits data to a Bluetooth peer over the RN42 module.

    @param[in] buf  Pointer to the data that should be sent.
    @param[in] size Number of bytes to send.
******************************************************************************/
void
rn42_send_data(uint8_t *buf, uint32_t size)
{
    uint32_t status;

    setup_usart_tx_dma(buf, size);

    while (true)
    {
        status = pdca_get_transfer_status(PDCA_CHANNEL_TX);

        if (status & PDCA_TRANSFER_COMPLETE)
        {
            break;
        }
    }
}


/******************************************************************************
    send_response
*//**
    @brief Sends a response packet to the host.

    @param[in] cmd_id       The command ID we're responding to.
    @param[in] status       The status code.
    @param[in] data         Pointer to data to send to the PC.
    @param[in] data_length  Number of bytes to send.
******************************************************************************/
static void
send_response(
    uint8_t cmd_id,
    uint8_t status,
    uint8_t *data,
    uint32_t data_length)
{
    response_t response = {
        {'C', 'C', 'M', 'D'},
        cmd_id,
        status,
    };
    storeBigU32(&response.data_length, data_length);

    rn42_send_data((uint8_t*) &response, sizeof(response));
    rn42_send_data(data, data_length);
}