void	LLQuaternion::quantize8(F32 lower, F32 upper)
{
	mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper);
	mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper);
	mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);
	mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper);

	normQuat();
}
// Quatizations
void	LLQuaternion::quantize16(F32 lower, F32 upper)
{
	F32 x = mQ[VX];
	F32 y = mQ[VY];
	F32 z = mQ[VZ];
	F32 s = mQ[VS];

	x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper);
	y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper);
	z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper);
	s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper);

	mQ[VX] = x;
	mQ[VY] = y;
	mQ[VZ] = z;
	mQ[VS] = s;

	normQuat();
}
int main(void)
{



	//-------------------------USART INTERRUPT REGISTRATION.------------//
	// Set Clock: Oscillator needs to initialized once: First
		 pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

		 // --------------		USART INIT		-----------------------------------------------
		 static const gpio_map_t USART_GPIO_MAP =
		  {
			{AVR32_USART0_RXD_0_0_PIN, AVR32_USART0_RXD_0_0_FUNCTION},
			{AVR32_USART0_TXD_0_0_PIN, AVR32_USART0_TXD_0_0_FUNCTION}
		  };

		  // USART options.
		  static const usart_options_t USART_OPTIONS =
		  {
			.baudrate     = USART_BAUDRATE,
			.charlength   = 8,
			.paritytype   = USART_NO_PARITY,
			.stopbits     = USART_1_STOPBIT,
			.channelmode  = USART_NORMAL_CHMODE
		  };

		// Assign GPIO to USART
		gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));

		// Init USART
		usart_init_rs232(USART_0, &USART_OPTIONS, FOSC0);

		Disable_global_interrupt();
		INTC_init_interrupts();			// Init Interrupt Table: Once at first

		// Register USART Interrupt (hinzufügen)
		INTC_register_interrupt(&usart_int_handler, AVR32_USART0_IRQ, AVR32_INTC_INT0);

		USART_0->ier = AVR32_USART_IER_RXRDY_MASK; // Activate ISR on RX Line
		Enable_global_interrupt();
	// -----------------------------------------------------------------------------------

		// --------------------------		Display INIT		----------------------------------
			// Map SPI Pins
			static const gpio_map_t DIP204_SPI_GPIO_MAP =
			  {
				{DIP204_SPI_SCK_PIN,  DIP204_SPI_SCK_FUNCTION },  // SPI Clock.
				{DIP204_SPI_MISO_PIN, DIP204_SPI_MISO_FUNCTION},  // MISO.
				{DIP204_SPI_MOSI_PIN, DIP204_SPI_MOSI_FUNCTION},  // MOSI.
				{DIP204_SPI_NPCS_PIN, DIP204_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
			  };

			// add the spi options driver structure for the LCD DIP204
			  spi_options_t spiOptions =
			  {
				.reg          = DIP204_SPI_NPCS,
				.baudrate     = 1000000,
				.bits         = 8,
				.spck_delay   = 0,
				.trans_delay  = 0,
				.stay_act     = 1,
				.spi_mode     = 0,
				.modfdis      = 1
			  };


			// SPI Inits: Assign I/Os to SPI
			gpio_enable_module(DIP204_SPI_GPIO_MAP,
			                     sizeof(DIP204_SPI_GPIO_MAP) / sizeof(DIP204_SPI_GPIO_MAP[0]));

			// Initialize as master
			spi_initMaster(DIP204_SPI, &spiOptions);

			// Set selection mode: variable_ps, pcs_decode, delay
			spi_selectionMode(DIP204_SPI, 0, 0, 0);

			// Enable SPI
			spi_enable(DIP204_SPI);

			// setup chip registers
			spi_setupChipReg(DIP204_SPI, &spiOptions, FOSC0);

			// initialize delay driver: Muss vor dip204_init() ausgeführt werden
			delay_init( FOSC0 );

			// initialize LCD
			dip204_init(backlight_PWM, TRUE);
			// ---------------------------------------------------------------------------------------

			// -----------------			Timer Counter Init		---------------------------------
				// Timer Configs:  Options for waveform generation.
				static const tc_waveform_opt_t WAVEFORM_OPT =
				{
				.channel  = 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: toggle.
				.acpa     = TC_EVT_EFFECT_NOOP,                // RA compare effect on TIOA: toggle

				.wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,//  Count till RC and reset (S. 649): Waveform selection
				.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.
				};


				// TC Interrupt Enable Register
				static const tc_interrupt_t TC_INTERRUPT =
				{ .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs  = 1, .cpbs  = 0, .cpas  = 0, .lovrs = 0, .covfs = 0
				};
				// 0 = No Effect | 1 = Enable ( CPCS = 1 enables the RC Compare Interrupt )

				// *****************   Timer Setup ***********************************************
				// Initialize the timer/counter.
				tc_init_waveform(tc, &WAVEFORM_OPT);         // Initialize the timer/counter waveform.

				// Set the compare triggers.
				tc_write_rc(tc, TC_CHANNEL, RC); // Set RC value.

				tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT);

				// Start the timer/counter.
				tc_start(tc, TC_CHANNEL);                    // And start the timer/counter.
				// *******************************************************************************

				Disable_global_interrupt();
				// Register TC Interrupt
				INTC_register_interrupt(&tc_irq, AVR32_TC_IRQ0, AVR32_INTC_INT3);

				Enable_global_interrupt();
				// ---------------------------------------------------------------------------------------



				imu_init();

//-------------------------------TWI R/W ---------------------------------------------------



  sensorDaten imu_data = {0};
  char disp1[30], disp2[30], disp3[30], disp4[30];
  short GX,GY,GZ, AX, AY, AZ;			//shifted comlete Data
  RPY currMoveRPY;
  Quaternion currQuat;
  currQuat.q0 = 1.0;
  currQuat.q1 = 0;
  currQuat.q2 = 0;
  currQuat.q3 = 0;
  Quaternion deltaQuat;
  RotMatrix rot = {0};
  RPY reconverted;


  calibrate_all(&imu_data);


  while(1){
	  if(exe){
		  exe = false;
		  read_sensor(&imu_data);




		  AX = imu_data.acc_x + imu_data.acc_x_bias;
		  AY = imu_data.acc_y + imu_data.acc_y_bias;
		  AZ = imu_data.acc_z + imu_data.acc_z_bias;

		  GX = imu_data.gyro_x + imu_data.gyro_x_bias;
		  GY = imu_data.gyro_y + imu_data.gyro_y_bias;
		  GZ = imu_data.gyro_z + imu_data.gyro_z_bias;




		  //convert to 1G
		  float ax = (float)AX * (-4.0);
		  float ay = (float)AY * (-4.0); //wegen 2^11= 2048, /2 = 1024 entspricht 4G -> 1G = (1024/4)
		  float az = (float)AZ * (-4.0);


		  //convert to 1°/s
		  gx = ((float)GX/ 14.375); // in °/s
		  gy = ((float)GY/ 14.375);
		  gz = ((float)GZ/ 14.375);

		  //Integration over time
		  dGx = (gx*0.03);
		  dGy = (gy*0.03);
		  dGz = (gz*0.03);

		  currMoveRPY.pitch = -dGx;
		  currMoveRPY.roll = dGy;
		  currMoveRPY.yaw = dGz;


		  //aufaddieren auf den aktuellen Winkel IN GRAD
			gxDeg += dGx;
			gyDeg += dGy;
			gzDeg += dGz;


			//RPY in Quaternion umwandeln
			RPYtoQuat(&deltaQuat, &currMoveRPY);


			//normieren
			normQuat(&deltaQuat);


			//aufmultiplizeiren
			quatMultiplication(&deltaQuat, &currQuat, &currQuat);



			//nochmal normieren
			normQuat(&currQuat);

			//rücktransformation nicht nötig!!


			char send[80];
			sprintf(send,"$,%f,%f,%f,%f,#", currQuat.q0, currQuat.q1, currQuat.q2, currQuat.q3);
		 	usart_write_line(USART_0,send);



		   sprintf(disp1,"q0:%.3f, GX:%3.0f",currQuat.q0,gxDeg);
		   sprintf(disp2,"q1:%.3f, GY:%3.0f",currQuat.q1, gyDeg);
		   sprintf(disp3,"q2:%.3f, GZ:%3.0f",currQuat.q2, gzDeg);
		   sprintf(disp4,"q3:%.3f",currQuat.q3);



		   dip204_clear_display();

		   dip204_set_cursor_position(1,1);
		   dip204_write_string(disp1);
		   dip204_set_cursor_position(1,2);
		   dip204_write_string(disp2);
		   dip204_set_cursor_position(1,3);
		   dip204_write_string(disp3);
		   dip204_set_cursor_position(1,4);
		   dip204_write_string(disp4);











			//sprintf(data,"TEST:%s",high);
		   //print_dbg(data);
	  }

  }
}