int main(void)
{
  void (*applptr)( void ) = 0x0000;
  MCUCR = _BV(IVCE);  // enable wechsel der Interrupt Vectoren
  MCUCR = _BV(IVSEL); // Interrupts auf Boot Section umschalten
#if MITLED
  LEDDDR |= _BV(LEDPIN);  //LED pin auf ausgang
  blink(2, 20, 20);
#endif
  init_twi();
 

  while (1) { /* Endlosschleife weil 1 immer WAHR*/

    /* Bootloader Quit und sprung zur App */
    if(kommando == 0xFE || timeout == 0xFFFE){

      // Turn off the I2C interrupts
      TWCR = 0;

#if MITLED
      blink(5, 5, 10);
#endif
      cli();
      MCUCR = _BV(IVCE);  // enable wechsel der Interrupt Vectoren
      MCUCR = 0x00; // Interrupts auf Application Section umschalten
      applptr(); // Rücksprung zur Application
    }
    /* Datenblock (64byte) in Flash schreiben */
    if(kommando == 0x04){
#if MITLED
      STATUSLED(1);//PORTB |= _BV(PB0);
#endif
      boot_program_page (pageaddr);
#if MITLED
      STATUSLED(0);//PORTB &= ~_BV(PB0);
#endif
      kommando = 0x00;

      /* TWI wieder aktivieren */
      TWCR |= (1<<TWINT); 
    }
    if(TWSR == 0x00){
      init_twi();
    }
    if(timeout != 0xFFFF){
      timeout++;
      _delay_us(50);
    }

  }

  return 0;
}
Beispiel #2
0
void 
i2c_slave_core_periodic(void)
{
  /* error detection on i2c bus */
  if((TWSR & 0xF8) == 0x00)
    init_twi();
}
Beispiel #3
0
int main(){

    uint8_t rd_buf[1];

    char str[6];

    // Initialize UART
    UART_Init(MY_UBRR);

    init_twi();	

    sei();
        
    init_LSM6DS3();
    
    rd_buf[0] = check_bit(CTRL9_XL,SOFT_EN);
    sprintf(str,"%02X\r\n",rd_buf[0]);
    UART_Transmit_String(str);

    set_bits(CTRL9_XL, SOFT_EN);
    rd_buf[0] = check_bit(CTRL9_XL,SOFT_EN);
    sprintf(str,"%02X\r\n",rd_buf[0]);
    UART_Transmit_String(str);

    clear_bits(CTRL9_XL, SOFT_EN);
    rd_buf[0] = check_bit(CTRL9_XL,SOFT_EN);
    sprintf(str,"%02X\r\n",rd_buf[0]);
    UART_Transmit_String(str);
    
    return 0;
}
Beispiel #4
0
uint8_t main()
{
	//initialization
	uint16_t lm73_temp;
	init_twi();
	uart_init();

	//set LM73 mode for reading temperature by loading pointer register
	//this is done outside of the normal interrupt mode of operation 
	lm73_wr_buf[0] = LM73_PTR_TEMP; //load lm73_wr_buf[0] 
					//with temperature pointer address
	twi_start_wr(LM73_WRITE, lm73_wr_buf, 2); //start the TWI write process
	sei();             //enable interrupts to allow start_wr to finish

	while(1)
	{
		//read temperature data from LM73  (2 Bytes)
		twi_start_rd(LM73_READ, lm73_rd_buf, 2);
		_delay_ms(2);    //wait for it to finish

		//now assemble the two bytes read back into one 16-bit value
		lm73_temp = lm73_rd_buf[0]<<8;  //save high temperature byte 
		lm73_temp |= lm73_rd_buf[1];//"OR" in the low temp byte to lm73_temp 
		lm73_temp = lm73_temp >>7; //parse out decimal place
		itoa(lm73_temp, temp_val, 10); //convert to string in array 
		uart_puts(temp_val);
	}
}
Beispiel #5
0
void start_sound()
{
	
	start_dactimer() ;
	init_dac() ;
	init_twi() ;
	setVolume( 2 ) ;

#ifdef REVB
#ifndef REVX	
	register Pio *pioptr ;
	pioptr = PIOA ;
	pioptr->PIO_CODR = 0x02000000L ;	// Set bit A25 OFF
	pioptr->PIO_PER = 0x02000000L ;		// Enable bit A25 (Stock buzzer)
	pioptr->PIO_OER = 0x02000000L ;		// Set bit A25 as output
#endif
#else
	register Pio *pioptr ;
	pioptr = PIOA ;
	pioptr->PIO_CODR = 0x00010000L ;	// Set bit A16 OFF
	pioptr->PIO_PER = 0x00010000L ;		// Enable bit A16 (Stock buzzer)
	pioptr->PIO_OER = 0x00010000L ;		// Set bit A16 as output
#endif
#ifdef REVX	
	configure_pins( PIO_PC26, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTC | PIN_NO_PULLUP ) ;
	audioOn() ;
#endif
}
int main(void)
{
	SREG = 0x80;	/*ENABLE GLOBAL INTERRUPTS*/
	init_oscillator();
	init_usart();
	init_twi();
 //TWI_MASTER_t twi;
 //PMIC_CTRL= //interrupt
 
	PORTC.DIR |= PIN6_bm;
	
	if(( TWIC_MASTER_STATUS & TWI_MASTER_BUSSTATE_gm) == TWI_MASTER_BUSSTATE_IDLE_gc)
{	
	//TWIC_MASTER_ADDR =0x00; 
	TWIC_MASTER_CTRLC = TWI_MASTER_CMD_REPSTART_gc;
	//TWIC_MASTER_CTRLC = TWI_MASTER_CMD_NOACT_gc;   //read data
	TWIC_MASTER_ADDR = 0xEC;  // R/W bit low to write the reg number from where we want to read
	TWIC_MASTER_ADDR = 0xA0;
	TWIC_MASTER_CTRLC = TWI_MASTER_CMD_REPSTART_gc;
	TWIC_MASTER_ADDR = 0xED; // R/W bit high indicating a read operation 
    TWIC_MASTER_CTRLC = TWI_MASTER_CMD_STOP_gc;
	 int DATA=TWIC_MASTER_DATA;
	//sendChar(DATA);
	uint16_t buffer;
	itoa(DATA, buffer, 10);
	sendString(buffer);
	sendString("\n");
	
}

		//while(TWIC_MASTER_STATUS & 0x10)  //ack/NACK recieved from slave
 
//    TWIC_MASTER_ADDR =0x00; 
//    _delay_ms(100);
//    TWIC_MASTER_ADDR = 0xE7;
//      TWIC_MASTER_ADDR = 0xE5;
// 	 _delay_ms(100);
// TWIC_MASTER_ADDR = 0xA0;
    while(1)
	//for(int i=1; i<=5 ; i++)
    {
    
	 PORTC.OUT &= ~PIN6_bm;
  //  sendString("Test\n");
	_delay_ms(1000);
	PORTC.OUT |= PIN6_bm;
	_delay_ms(1000);
 
   //TWIC_MASTER_CTRLC = TWI_MASTER_CMD_REPSTART_gc;

   int DATA=TWIC_MASTER_DATA;
	//sendChar(DATA);
	uint16_t buffer;
	itoa(DATA, buffer, 10);
//	sendString(buffer);
    }
}
Beispiel #7
0
/* main function */
int main(void)
{
    /* ============================== */
    /* initialization =============== */
    /* ============================== */
    
    WDT_EnableAndSetTimeout(WDT_PER_512CLK_gc);

    /* set up LED pins */
    init_leds();

    /* set up I2C as slave */
    init_twi();

    /* set up our clocks */
    init_clock();
    
    /* set up sensors */
    init_sensors();

    /* set up motors */
    init_motors();

    /* set up crude digital outputs */
    init_digout();

    /* Flash all the LEDs for two and a half seconds to make sure
     * they're hooked up */
    led_orders->behavior = LED_BEHAVIOR_TIMED;
    led_orders->time = 4000;
    led_error1->behavior = LED_BEHAVIOR_TIMED;
    led_error1->time = 6000;
    led_error2->behavior = LED_BEHAVIOR_TIMED;
    led_error2->time = 8000;
    led_mota->behavior = LED_BEHAVIOR_TIMED;
    led_mota->time = 10000;
    led_motb->behavior = LED_BEHAVIOR_TIMED;
    led_motb->time = 12000;

    /* motA.duty = 4000; */
    /* motA.direction = 1; */
    /* motB.duty = 16000; */
    /* motB.direction = 1; */

    /* enable interrupts - things start ticking now */
    sei();


    /* ============================== */
    /* main loop ==================== */
    /* ============================== */
    for(;;)
    {
        _delay_us(10);
        WDT_Reset();
    }
}
int
main(void)
{
  void (*bootptr)( void ) = (void *) 0x0C00;
  DDRB |= _BV(PB0); //LED pin auf ausgang
  init_twi();
  runbootload = 0;
  blink(3, 20, 20);
  sei();
  TWCR |= (1<<TWINT); //TWI-Modul aktiv

  while (1) { /* Endlosschleife weil 1 immer WAHR*/
    /* donothingloop ;-) */
    if (runbootload == 3){
      //blink(4, 2, 10);
      runbootload = 0;
      bootptr();
    }
  }

  return 0;
}
Beispiel #9
0
/******************************************************************************
*                                    MAIN                                     *
*******************************************************************************
* Description: Firmware Project start.  This project:
*              (1) blinks the Mavric LED every .5 seconds
*
*   Arguments: None
*
*      Return: None
******************************************************************************/
int main(void)
{    
    ptrRxBufStart  = 0;
    ptrRxBufEnd    = 0;
    ptrCmdBuf      = 0;
    rxBuf[0]       = '\0';
        
    init_timers();
    init_usart0();
    init_twi();
    
    // enable printf
    stdout=stdin=&uartstr;
      
    // enable interrupts
    sei();
    
    initMux();

    DDRB = 0x01;    // enable PORTB 1 as an output (LED)
    
    printf("\r\n\r\nAerosole Devices Manufacturing Test Program\r\n");
    displaySerialCmdHelp();
    printf(">");

    while (1)
    {
        // blink LED if time has elapsed
        if(ms_count > 250)
        {
            ms_count = 0;
            toggleLED(); 
        } 
        
        getCommandData();           
    }
    
    return 0;
}
Beispiel #10
0
int main ()
{     
   uint16_t lm73_temp;  //a place to assemble the temperature from the lm73

   spi_init();   //initalize SPI 
   lcd_init();   //initalize LCD (lcd_functions.h)
   init_twi();   //initalize TWI (twi_master.h)  

   lm73_resolution_config();

   //set LM73 mode for reading temperature by loading pointer register
   //this is done outside of the normal interrupt mode of operation 
   //load lm73_wr_buf[0] with temperature pointer address
   lm73_wr_buf[0] = LM73_PTR_TEMP; 
   //start the TWI write process (twi_start_wr())
   twi_start_wr(LM73_ADDRESS, lm73_wr_buf, 1); 

   //enable interrupts to allow start_wr to finish
   sei();             

   clear_display();   //clean up the display

   while(1){          //main while loop
      _delay_ms(100);  //tenth second wait
      clear_display(); //wipe the display

      //read temperature data from LM73 (2 bytes)  (twi_start_rd())
      twi_start_rd(LM73_ADDRESS, lm73_rd_buf, 2); 
      _delay_ms(2);    //wait for it to finish
      //now assemble the two bytes read back into one 16-bit value
      lm73_temp = lm73_rd_buf[0]; //save high temperature byte into lm73_temp
      lm73_temp <<= 8; //shift it into upper byte 
      lm73_temp |= lm73_rd_buf[1]; //"OR" in the low temp byte to lm73_temp 
      itoa(lm73_temp, lcd_string_array, 2); //convert to string in array with itoa() from avr-libc                           
      string2lcd(lcd_string_array); //send the string to LCD (lcd_functions)
   } //while
} //main
Beispiel #11
0
/*! \brief Main function. Execution starts here.
 *
 * \retval 42 Fatal error.
 */
int main(void)
{
    init_hmatrix();

    // Configure standard I/O streams as unbuffered.
#if (defined __GNUC__) && (defined __AVR32__)
    setbuf(stdin, NULL);
#endif
    setbuf(stdout, NULL);

#if (defined USB_RESYNC_METHOD) && (USB_RESYNC_METHOD == USB_RESYNC_METHOD_EXT_CLOCK_SYNTHESIZER)
    // Initialize the TWI using the internal RCOSC
    init_twi_CS2200(AVR32_PM_RCOSC_FREQUENCY);

    // Initialize the CS2200 and produce a default 11.2896 MHz frequency
    cs2200_setup(11289600, FOSC0);
#endif

    // Initializes the MCU system clocks
    init_sys_clocks();

    // Initialize the TWI
    init_twi(FPBA_HZ);

    audio_mixer_enable_dacs(DEFAULT_DACS);
    audio_mixer_dacs_start(DEFAULT_DAC_SAMPLE_RATE_HZ,
                           DEFAULT_DAC_NUM_CHANNELS,
                           DEFAULT_DAC_BITS_PER_SAMPLE,
                           DEFAULT_DAC_SWAP_CHANNELS);

    // Initialize the display
    et024006_Init(  FCPU_HZ, FHSB_HZ);

    // Set Backlight
    gpio_set_gpio_pin(ET024006DHU_BL_PIN);

    // Clear the display
    et024006_DrawFilledRect(0, 0, ET024006_WIDTH, ET024006_HEIGHT, WHITE );

    // Display a logo.
    et024006_PutPixmap(avr32_logo, AVR32_LOGO_WIDTH, 0, 0
                       ,(ET024006_WIDTH - AVR32_LOGO_WIDTH)/2
                       ,(ET024006_HEIGHT - AVR32_LOGO_HEIGHT)/2, AVR32_LOGO_WIDTH, AVR32_LOGO_HEIGHT);

    et024006_PrintString(AUDIO_DEMO_STRING, (const unsigned char *)&FONT8x16, 30, 5, BLACK, -1);
    et024006_PrintString("Please plug the USB.", (const unsigned char *)&FONT8x8, 30, 30, BLACK, -1);

    // Initialize USB task
    usb_task_init();

    // Initialize Controller
    controller_init(FCPU_HZ, FHSB_HZ, FPBB_HZ, FPBA_HZ);

#if USB_DEVICE_FEATURE == true
    // Initialize device audio USB task
    device_audio_task_init();

    // Initialize the HID USB task
    device_hid_task_init();
#endif
#if USB_HOST_FEATURE == true
    // Initialize host audio USB task
    host_audio_task_init();
#endif

#ifdef FREERTOS_USED
    // Start OS scheduler
    vTaskStartScheduler();
    portDBG_TRACE("FreeRTOS returned.");
    return 42;
#else
    // No OS here. Need to call each task in round-robin mode.
    while (true)
    {
        usb_task();
#if USB_DEVICE_FEATURE == true
        device_audio_task();
        device_hid_task();
#endif
#if USB_HOST_FEATURE == true
        host_audio_task();
#endif
    }
#endif  // FREERTOS_USED
}
Beispiel #12
0
void 
i2c_slave_core_init(uip_udp_conn_t *conn)
{
  init_twi();
  i2c_slave_conn = conn;
}
Beispiel #13
0
/*! \brief Main function. Execution starts here.
 *
 * \retval 42 Fatal error.
 */
int main(void)
{
  uint32_t iter=0;
  uint32_t cs2200_out_freq=11289600;
  static bool b_sweep_up=true;
  static uint32_t freq_step=0;

  // USART options.
  static usart_serial_options_t USART_SERIAL_OPTIONS =
  {
    .baudrate     = USART_SERIAL_EXAMPLE_BAUDRATE,
    .charlength   = USART_SERIAL_CHAR_LENGTH,
    .paritytype   = USART_SERIAL_PARITY,
    .stopbits     = USART_SERIAL_STOP_BIT
  };

  // Initialize the TWI using the internal RCOSC
  init_twi(AVR32_PM_RCOSC_FREQUENCY);

  // Initialize the CS2200 and produce a default frequency.
  cs2200_setup(11289600, FOSC0);

  sysclk_init();

  // Initialize the board.
  // The board-specific conf_board.h file contains the configuration of the board
  // initialization.
  board_init();

  // Initialize the TWI
  init_twi(sysclk_get_pba_hz());

  // Initialize Serial Interface using Stdio Library
  stdio_serial_init(USART_SERIAL_EXAMPLE,&USART_SERIAL_OPTIONS);

  // Initialize the HMatrix.
  init_hmatrix();

  print_dbg("\r\nCS2200 Example\r\n");

  // Generate a 12.288 MHz frequency out of the CS2200.
  print_dbg("Output 12.288 MHz\r\n");
  cs2200_freq_clk_out(_32_BITS_RATIO(12288000, FOSC0));
  cpu_delay_ms( 10000, sysclk_get_cpu_hz());

  // Generate a 11.2896 MHz frequency out of the CS2200.
  print_dbg("Output 11.2896 MHz\r\n");
  cs2200_freq_clk_out(_32_BITS_RATIO(cs2200_out_freq, FOSC0));
  cpu_delay_ms( 10000, sysclk_get_cpu_hz());

  print_dbg("Sweep from 11.2896 MHz steps of 100 PPM\r\n");
  freq_step = PPM(cs2200_out_freq, 100);

  while(1)
  {
    uint32_t ratio;

    if(b_sweep_up)
    {
      if( iter<=10 )
      {
        print_dbg("Add 100 PPM\r\n");
        iter++;
        cs2200_out_freq += freq_step;
        ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0);
        cs2200_freq_clk_adjust((uint16_t)ratio);
        cpu_delay_ms( 1000, sysclk_get_cpu_hz());
        while( twi_is_busy() );
      }
      else
        b_sweep_up=false;
    }

    if(!b_sweep_up)
    {
      if( iter>0 )
      {
        print_dbg("Sub 100 PPM\r\n");
        iter--;
        cs2200_out_freq -= freq_step;
        ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0);
        cs2200_freq_clk_adjust((uint16_t)ratio);
        cpu_delay_ms( 1000, sysclk_get_cpu_hz());
        while( twi_is_busy() );
      }
      else
        b_sweep_up=true;
    }
  }
}
Beispiel #14
0
int main()
{

//uint8_t test_result=0;
//************************( 1 )*******************************************************
DDRD|=(1<<6)|(1<<7);//set LED pins as output
//PORTD&=~(1<<3);//vibration off
uart_init();//Keep this as first init so that text can be sent out in others
uart_puts("Starting up....");
_delay_ms(500);
PORTD|=1<<6;
_delay_ms(500);
PORTD&=~(1<<6);
spi_init(); //initialize SPI bus as master
init_tcnt2();//set up timer (RTC)
init_twi(); //initialize TWI interface
sei();
uart_puts("Pre Init...");
  
PORTB&=~(1<<sensor1_cs);//select sensor
SPIinit_MPU(MPU9250_FULL_SCALE_4G,MPU9250_GYRO_FULL_SCALE_500DPS);//init sensor
PORTB|=(1<<sensor1_cs);//deselect sensor
//init_MPU(MPU9250_FULL_SCALE_4G,MPU9250_GYRO_FULL_SCALE_500DPS, MPU9250_DEFAULT_ADDRESS); //initialize the 9axis sensor
//init_MPU(0,0, 0xD1); //initialize the 9axis sensor
//init_MPU(MPU9250_FULL_SCALE_4G,MPU9250_GYRO_FULL_SCALE_500DPS, MPU9250_DEFAULT_ADDRESS); //initialize the 9axis sensor
sram_init();//initialize sram
uart_puts("Post Init...");
//vibrate(100);	//Send feedback showing complete setup
PORTD |=(1<<6)|(1<<7);
PORTD &=~(1<<7);
_delay_ms(200);
PORTD |=(1<<7);
PORTD &=~(1<<6);// blinks both lights to show the program is starting
_delay_ms(200);
PORTD |=(1<<6);
_delay_ms(1000);
record_shot();
while(1){}        //*****************STOP POINT**********************
/*
test_result = test_com(0, MPU9250_DEFAULT_ADDRESS);
if(test_result)
{
uart_puts("MPU Status: OK\n");
}
else
uart_puts("MPU Status: FAILURE... You suck!\n");
*/
char rx_char;
uint16_t i=0;//used for for loops
//*****Fix me*******  
//should set to int 0 not char '0' but the ascii zero prints better for now
for(i=0;i<512;i++){sd_buf[i]='0';}//sets inital buffer to zero values
uint16_t shot_count=0;
while(1)
{
//************************( 2 )*******************************************************

PORTD &=~(1<<7);
_delay_ms(2000);//Show red light for 2 sec, then turn green and start shot
PORTD |=(1<<7);
PORTD &=~(1<<6);
//************************( 3 )*******************************************************
//vibrate(100);

record_shot();//record a shot
char shots_s[10];
itoa(num_records,shots_s,10);
uart_puts("In 20 seconds The number of records was: ");
uart_puts(shots_s);
uart_putc('\n');

print_shot();
shot_count++;
itoa(shot_count,shots_s,10);
uart_puts("Shot Number: ");
uart_puts(shots_s);
uart_putc('\n');
//print_shot();


PORTD |=(1<<6);//turn off light
//vibrate(100);_delay_ms(100);vibrate(100);  //Double vibration showing end of shot
//check_voltage();//Check system voltage
_delay_ms(5000);//wait 60 seconds
//************************( 6 )*******************************************************
continue; //start over and take another shot

  uart_puts("Starting Testing\n\n");
  uart_putc('\r');
  rx_char=uart_getc(); 
  if(rx_char=='c')
  {
    uart_puts("Command line:\n\n");
    rx_char=uart_getc();
    while(rx_char!='c')
    {
      if(rx_char=='s'){}
     if(rx_char=='w'){}
      if(rx_char=='r'){}//buffer gets set to sector!!
      if(rx_char=='i'){}
      rx_char=uart_getc();
    }
  }
 // uint8_t i=0;
  //Load values into 10 memory locations
  //Zero is only skipped to avoid loading zero into the byte
  //since when the byte is read back, zero could also mean communication failed

  for(i=48;i<=57;i++)
  {
    sram_write(i,add_m,add_h,i);//only lower address byte is incremented 
    //uart_putc(i);
  }//end loading for loop

  //change value in one spot in array as build in "error"
  sram_write(50,add_m,add_h,100);

  //check values in first 10 memory locations, one should be "wrong"
  for(i=48;i<57;i++)
  {
    _delay_ms(100);
    PORTB |=(1<<1)|(1<<2);
    _delay_ms(100);
    if (sram_read(i,add_m,add_h)==i)
    {
      PORTB &=~(1<<1);
      uart_puts("passed\n");
    }//Byte read back correct  GREEN light
    else{PORTB &=~(1<<2);uart_puts("FAILED!!\n");}//Byte Read back was incorrect   RED light
  }//end for loop for checking values

  PORTB |=(1<<1)|(1<<2);//both lights off

  uart_puts("****Tesst finished*****\r\r");
  _delay_ms(1500);//wait 1.5 seconds before starting again
} //end while 
} //end main
Beispiel #15
0
// Called every 5mS from interrupt routine
void sound_5ms()
{
	register Dacc *dacptr ;

	if ( CoProcTimer )
	{
		if ( --CoProcTimer == 0 )
		{
//			Debug_I2C_restart += 1 ;
			init_twi() ;
		}
	}

	dacptr = DACC ;

	if ( Sound_g.Tone_ms_timer > 0 )
	{
		Sound_g.Tone_ms_timer -= 1 ;
	}
		
	if ( Sound_g.Tone_ms_timer == 0 )
	{
		if ( Sound_g.VoiceRequest )
		{
			// audioOn() ;
			dacptr->DACC_IDR = DACC_IDR_ENDTX ;	// Disable interrupt
			Sound_g.Sound_time = 0 ;						// Remove any pending tone requests
			if ( dacptr->DACC_ISR & DACC_ISR_TXBUFE )	// All sent
			{
				// Now we can send the voice file
				Sound_g.VoiceRequest = 0 ;
				Sound_g.VoiceActive = 1 ;

				set_frequency( VoiceBuffer[0].frequency ? VoiceBuffer[0].frequency : 15999 ) ;
#ifndef SIMU
				dacptr->DACC_PTCR = DACC_PTCR_TXTDIS ;
				dacptr->DACC_TPR = (uint32_t) VoiceBuffer[0].dataw ;
				dacptr->DACC_TCR = VoiceBuffer[0].count / 2 ;		// words, 100 16 bit values
	
				if ( VoiceCount > 1 )
				{
					dacptr->DACC_TNPR = (uint32_t) VoiceBuffer[1].dataw ;
					dacptr->DACC_TNCR = VoiceBuffer[1].count / 2 ;		// words, 100 16 bit values
				}
				dacptr->DACC_PTCR = DACC_PTCR_TXTEN ;
#endif
				dacptr->DACC_IER = DACC_IER_ENDTX ;
			}
			return ;
		}
		
		if ( ( Sound_g.VoiceActive ) || ( ( Voice.VoiceQueueCount ) && sd_card_ready() ) )
		{
			Sound_g.Sound_time = 0 ;						// Remove any pending tone requests
			return ;
		}
				
		if ( Sound_g.Sound_time )
		{
			// audioOn() ;
			Sound_g.Tone_ms_timer = ( Sound_g.Sound_time + 4 ) / 5 ;
			if ( Sound_g.Next_freq )		// 0 => silence for time
			{
				Sound_g.Frequency = Sound_g.Next_freq ;
				Sound_g.Frequency_increment = Sound_g.Next_frequency_increment ;
				set_frequency( Sound_g.Frequency * 100 ) ;
#ifndef SIMU
				dacptr->DACC_TPR = (uint32_t) Sine_values ;
				dacptr->DACC_TNPR = (uint32_t) Sine_values ;
#endif
				dacptr->DACC_TCR = 50 ;		// words, 100 16 bit values
				dacptr->DACC_TNCR = 50 ;	// words, 100 16 bit values
				tone_start( 0 ) ;
			}
			else
			{
				dacptr->DACC_IDR = DACC_IDR_ENDTX ;		// Silence
			}
			Sound_g.Sound_time = 0 ;
		}
		else
		{
			dacptr->DACC_IDR = DACC_IDR_ENDTX ;	// Disable interrupt
			Sound_g.Tone_timer = 0 ;
			// audioOff() ;
		}
	}
	else if ( ( Sound_g.Tone_ms_timer & 1 ) == 0 )		// Every 10 mS
	{
		if ( Sound_g.Frequency )
		{
			if ( Sound_g.Frequency_increment )
			{
				Sound_g.Frequency += Sound_g.Frequency_increment ;
				set_frequency( Sound_g.Frequency * 100 ) ;
			}
		}
	}
}