Example #1
0
void app_touch_task(void)
{
	uint16_t status_flag;
	uint16_t burst_flag;

#ifdef _DEBUG_INTERFACE_
	/* Process commands from PC */
	QDebug_ProcessCommands();
#endif

	if (time_to_measure_touch) {
		time_to_measure_touch = false;
		do {
			status_flag = qt_measure_sensors(current_time_ms_touch);
			burst_flag = status_flag & QTLIB_BURST_AGAIN;

#ifdef _DEBUG_INTERFACE_
			QDebug_SendData(status_flag);
#endif

			/*
			 * Time-critical host application code should be placed
			 *here since
			 * a full burst cycle may delay critical task in the
			 *main application
			 */
		} while (burst_flag);

#ifdef _DEBUG_INTERFACE_
		/* Process commands from PC */
		QDebug_ProcessCommands();
#endif
	}
}
Example #2
0
/*! \brief Self Cap measure complete callback function.
 *
 * This function is called by the library when the touch measurement
 * process for Self Cap sensors is completed.
 *
 * \param p_measure_data   Base address of touch_measure_data_t instance.
 * \note A touch_selfcap_measure_complete_callback() call signifies that fresh
 * values of touch status, rotor/slider position, measured signals,
 * references and Sensor data is available.
 * The Self Cap measured data can be accessed using the p_measure_data
 * pointer.
 */
void touch_selfcap_measure_complete_callback( void )
{
#if DEF_TOUCH_QDEBUG_ENABLE == 1

	/* Send out the Touch debug information data each time when Touch
	 *   measurement process is completed .
	 *   The Touch Signal and Touch Delta values are always sent.
	 *   Touch Status change, Rotor-Slider Position change and Sensor
	 * Reference
	 *   values can be optionally sent using the masks below.
	 */
	QDebug_SendData( TOUCH_CHANNEL_REF_CHANGE |
			TOUCH_ROTOR_SLIDER_POS_CHANGE |
			TOUCH_STATUS_CHANGE );

	/* QT600 two-way QDebug communication application Example. */
	/* Process any commands received from QTouch Studio. */
	QDebug_ProcessCommands();
#endif

	if (!(p_selfcap_measure_data->acq_status & TOUCH_BURST_AGAIN)) {
		/* Set the QTouch measurement done flag. */
		p_selfcap_measure_data->measurement_done_touch = 1u;
	}
}
Example #3
0
/*============================================================================
Name    :   touch_measure
------------------------------------------------------------------------------
Purpose :   This will call all the functions for touch related measurement.
Input   :   n/a
Output  :   n/a
Notes   :
============================================================================*/
void touch_measure()
{
   /*status flags to indicate the re-burst for library*/
   static uint16_t status_flag = 0u;
   static uint16_t burst_flag = 0u;

	  if( time_to_measure_touch )
        {

            /*  clear flag: it's time to measure touch  */
            time_to_measure_touch = 0u;

            do {
				#ifdef _DEBUG_INTERFACE_
				#ifdef _QDEBUG_TIME_STAMPS_
						TIMESTAMP0;
				#endif
				#endif
                /*  one time measure touch sensors    */
                status_flag = qt_measure_sensors( current_time_ms_touch );

				#ifdef _DEBUG_INTERFACE_
				#ifdef _QDEBUG_TIME_STAMPS_
					  TIMESTAMP2;
				#endif
				#endif
                burst_flag = status_flag & QTLIB_BURST_AGAIN;
				
				if (burst_flag != QTLIB_NO_ACTIVITY)
				{
					printf("\nburst = %d", burst_flag);
				}
				
				#ifdef _DEBUG_INTERFACE_
                /* send debug data */
                QDebug_SendData(status_flag);
				/* Process commands from PC */
            	QDebug_ProcessCommands();
				#endif
				#ifdef _DEBUG_INTERFACE_
				#ifdef _QDEBUG_TIME_STAMPS_
							TIMESTAMP3;
				#endif
				#endif

                /* Time-critical host application code goes here */

            } while (burst_flag);

        }


}
Example #4
0
/**
 * \brief Check if user is pressing the touch key
 *
 * \retval true if key is pressed.
 * \retval false if key is not pressed.
 */
bool touch_key_is_pressed(void)
{
	uint16_t status_flag;
	uint16_t burst_flag;

#ifdef _DEBUG_INTERFACE_
	/* Process commands from PC */
	QDebug_ProcessCommands();
#endif

	if (time_to_measure_touch) {
		time_to_measure_touch = false;

		do {
			status_flag = qt_measure_sensors(current_time_ms_touch);
			burst_flag = status_flag & QTLIB_BURST_AGAIN;

#ifdef _DEBUG_INTERFACE_
			QDebug_SendData(status_flag);
#endif
		/* Time-critical host application code should be placed here since
		 * a full burst cycle may delay critical task in the main application
		 */

		} while (burst_flag);

#ifdef _DEBUG_INTERFACE_
		/* Process commands from PC */
		QDebug_ProcessCommands();
#endif
	}

	if (TOUCH_GET_SENSOR_STATE(0)) {
		return 0;
	} else {
		return 1;
	}
}
Example #5
0
void touch_init( void )
{

    /* Configure the Sensors as keys or Keys With Rotor/Sliders in this function */
    config_sensors();

    /* initialise touch sensing */
    qt_init_sensing();

    /*  Set the parameters like recalibration threshold, Max_On_Duration etc in this function by the user */
    qt_set_parameters( );

    /*  Address to pass address of user functions   */
    /*  This function is called after the library has made capacitive measurements,
    *   but before it has processed them. The user can use this hook to apply filter
    *   functions to the measured signal values.(Possibly to fix sensor layout faults)    */
	   #ifdef _DEBUG_INTERFACE_
       #ifdef _QDEBUG_TIME_STAMPS_
              qt_filter_callback = &set_timestamp1;
       #else
              qt_filter_callback = 0;
       #endif
       #else
              qt_filter_callback = 0;
       #endif

#ifdef _DEBUG_INTERFACE_
    /* Initialize debug protocol */
    QDebug_Init();
#endif

    /* enable interrupts */
    __enable_interrupt();


#ifdef _DEBUG_INTERFACE_
    /* Process commands from PC */
    QDebug_ProcessCommands();
#endif

}
Example #6
0
/**
 * \brief Measure touch sensors and do appropriate action
 */
void touch_handler(void)
{
	uint16_t qt_measurement_status;

	if (time_to_measure_touch) {
		time_to_measure_touch = false;

		do {
			qt_measurement_status =
				qt_measure_sensors(current_time_ms);

#ifdef _DEBUG_INTERFACE_
			QDebug_SendData(qt_measurement_status);
#endif
		} while (qt_measurement_status & QTLIB_BURST_AGAIN);

#ifdef _DEBUG_INTERFACE_
		QDebug_ProcessCommands();
#endif

		if (qt_measure_data.qt_touch_status.sensor_states[0] & 0x01) {
			LED_On(LED1);
		}
		else {
			LED_Off(LED1);
		}

		if (qt_measure_data.qt_touch_status.sensor_states[0] & 0x02) {
			uint8_t slider_pos =
				qt_measure_data.qt_touch_status.rotor_slider_values[0];
			tc_write_rb(&AVR32_TC0, 0, (slider_pos + 1));

			LED_On(LED2);
		}
		else {
			LED_Off(LED2);
		}
	}
}
Example #7
0
int main( void )
{
    /*status flags to indicate the re-burst for library*/
    uint16_t status_flag = 0u;
    uint16_t burst_flag = 0u;
    /* initialise host app, pins, watchdog, etc */
    init_system();

    /* Configure the Sensors as keys or Keys With Rotor/Sliders in this function */
    config_sensors();

    /* initialise touch sensing */
    qt_init_sensing();

    /*  Set the parameters like recalibration threshold, Max_On_Duration etc in this function by the user */
    qt_set_parameters( );

    /* configure timer ISR to fire regularly */
    init_timer_isr();
#ifdef _DEBUG_INTERFACE_
    timestamp1_hword = current_time_ms_touch;
    timestamp1_lword = (uint16_t)TIMER_COUNTER_L;
    timestamp1_lword |= (uint16_t)(TIMER_COUNTER_H << 8);
#endif
    /*  Address to pass address of user functions   */
    /*  This function is called after the library has made capacitive measurements,
    *   but before it has processed them. The user can use this hook to apply filter
    *   functions to the measured signal values.(Possibly to fix sensor layout faults)    */
    qt_filter_callback = 0;
#ifdef _DEBUG_INTERFACE_
		QDebug_Init();
#endif

    /* enable interrupts */
    __enable_interrupt();
#ifdef _DEBUG_INTERFACE_
  /* Process commands from PC */
    QDebug_ProcessCommands();
#endif

    /* loop forever */
   for( ; ; )
   {
      if( time_to_measure_touch )
      {
         /*  clear flag: it's time to measure touch  */
         time_to_measure_touch = 0u;

         do {
 #ifdef _DEBUG_INTERFACE_           
	 	timestamp2_hword = current_time_ms_touch;
        timestamp2_lword = (uint16_t)TIMER_COUNTER_L;
        timestamp2_lword |= (uint16_t)(TIMER_COUNTER_H << 8);
#endif
            /*  one time measure touch sensors    */
            status_flag = qt_measure_sensors( current_time_ms_touch );
 #ifdef _DEBUG_INTERFACE_
		timestamp3_hword = current_time_ms_touch;
        timestamp3_lword = (uint16_t)TIMER_COUNTER_L;
        timestamp3_lword |= (uint16_t)(TIMER_COUNTER_H << 8);
#endif
            burst_flag = status_flag & QTLIB_BURST_AGAIN;
#ifdef _DEBUG_INTERFACE_   
		/* send debug data */ 
        QDebug_SendData(status_flag);
#endif
            /*Time critical host application code goes here*/

         }while (  burst_flag) ;
      }
#ifdef _DEBUG_INTERFACE_
  			/* Process commands from PC */
            QDebug_ProcessCommands();
#endif

      /*  Time Non-critical host application code goes here  */

   }
}
/*! \brief Example application entry function.
 */
int
main (void)
{

/*  BEFORE USING THE EXAMPLE PROJECTS.

1. For support queries on,
     - QTouch Library usage
     - Capacitive Touch Sensor Tuning
     - Capacitive Touch Schematic design
     - Capacitive Touch Sensor design
   refer to http://www.atmel.com/design-support/

2. For more QTouch Library documentation,
   refer Atmel QTouch Library User Guide doc8207.pdf.

   For Capacitive Touch Sensor tuning guidelines,
   refer QTAN0062: QTouch and QMatrix Sensitivity Tuning for Keys, Sliders and Wheels.

   For Capacitive Touch Sensor design,
   refer doc10620.pdf: Touch Sensors Design Guide.

   http://www.atmel.com/dyn/products/app_notes.asp?family_id=697

3. The Example application uses a CPU, PBA and PBB clock of 48MHz.
   When using a different frequency setting, the following parameters must be
   changed accordingly to ensure proper QTouch operation.
   a. QTx_CAT_CLK_DIV.
   b. TOUCH_SPREAD_SPECTRUM_MAX_DEV, when Spread spectrum is enabled.
   c. PBA_HZ, when using qdebug/SPI_Master.c
   d. TARGET_PBA_FREQ_HZ and TARGET_CPU_FREQ_HZ, when using qdebug/SERIAL.c

4. STK600-QTouch Test setup pin information.
   The following table indicates the STK600 pin connections for the STK600-QTouch
   test setup.

   Important Note: The (csa1/csab1) and (csa2/csb2) Touch channel connections are
   multiplexed with the JTAG pins.  So, when using the JTAG debugging mode, these
   Touch channel connections MUST be removed. In the Flash mode, this will not
   cause any issues.

        ----------------------------------------------
	CAT CSA/CSB name - STK600 board Port-pin name
	----------------------------------------------
	ROTOR/WHEEL
	csa1 		 - 	pa1 (This pair is multiplexed with JTAG pins.
	csb1 		 - 	pa6  Remove Touch connections on these pins during JTAG debug mode.)

	csa2 		 - 	pa0 (This pair is multiplexed with JTAG pins.
	csb2 		 - 	pa7  Remove Touch connections on these pins during JTAG debug mode.)

	csa5 		 - 	pb2
	csb5 		 - 	pb4

	SLIDER
	csa9 		 - 	pd0
	csb9 		 - 	pd1

	csa7 		 - 	pa4
	csb7 		 - 	pa5

	csa8 		 - 	pc0
	csb8 		 - 	pc1

	KEY 1
	csa15 		 - 	pe4
	csb15 		 - 	pe1

	KEY 2
	csa16 		 - 	pe3
	csb16 		 - 	pe2

    ----------------------------------------------
	QT600 USB Bridge
	'TOUCH DATA' Header Pin name - STK600 board Port-pin name
	----------------------------------------------
	PA22 - 'TOUCH DATA' header pin 8 - clk 	 - pc6
	PA21 - 'TOUCH DATA' header pin 7 - miso	 - pc5
	PA20 - 'TOUCH DATA' header pin 6 - mosi  - pc4
	PA14 - 'TOUCH DATA' header pin 5 - nss 	 - pb6

5. When two or more acquisition methods are used, care must be taken such that a
   given port pin is not used by more than one method at the same time.  The following
   pin configuration options available in touch_config_at32uc3l.h must be carefully
   chosen to avoid any overlapping.
   a. QMatrix Pin Configuration Options.
   b. Autonomous QTouch Pin Configuration Options.
   c. QTouch Group A Pin Configuration Options.
   d. QTouch Group B Pin Configuration Options.
   e. Touch Sync Pin option.
*/

  touch_ret_t touch_ret = TOUCH_SUCCESS;
  touch_qt_dma_t qt_dma_ch;

  /* Initialize host clock, pins, watchdog, etc. */
  init_system ();

  /* Disable interrupts. */
  Disable_global_interrupt ();

  /* The INTC driver has to be used only for GNU GCC for AVR32. */
#if (defined __GNUC__)

  /* initialize interrupt vectors. */
  INTC_init_interrupts ();

  /* Register the Timer interrupt handler to the interrupt controller. */
  INTC_register_interrupt (&tc_irq, EXAMPLE_TC_IRQ, AVR32_INTC_INT0);

  /* Register the Touch Library CAT interrupt handler to the interrupt controller.
     Note: This interrupt registration is a MUST before using the Touch Library
     with the GCC compiler.

     For the case of IAR the registration of interrupt is automatically taken
     care by the compiler. The Touch Libary CAT interrupt level for the case
     of IAR is fixed to Interrupt level 3. */
  INTC_register_interrupt (&touch_acq_done_irq, AVR32_CAT_IRQ,
			   AVR32_INTC_INT3);

#endif

  /* Enable interrupts. */
  Enable_global_interrupt ();

  /* Configure timer to fire ISR regularly. */
  init_timer ();

  /* Initialize touch library and uc3l cat module for QTouch Group A operation. */
  touch_ret = touch_qt_sensors_init (TOUCH_QT_GRP_A, &touch_config);
  if (touch_ret != TOUCH_SUCCESS)
    {
      while (1u);		/* Check API Error return code. */
    }

#if DEF_TOUCH_QDEBUG_ENABLE == 1
  /* Initialize the debug interface. */
  QDebug_Init ();
#endif

  /* configure the touch library sensors. */
  touch_ret = config_qt_grp_a_touch_sensors ();
  if (touch_ret != TOUCH_SUCCESS)
    {
      while (1u);		/* Check API Error return code. */
    }

  /* Initialize touch sensing. */
  touch_ret = touch_qt_sensors_calibrate (TOUCH_QT_GRP_A);
  if (touch_ret != TOUCH_SUCCESS)
    {
      while (1u);		/* Check API Error return code. */
    }

  /* Provide the dma channel to be used by the CAT module.  For each
     acquisition cycle, any different dma channel from 0 to 11 can be provided.
     The touch library can handle a different dma channel for each call of the
     touch_qt_sensors_start_acquisition API. */
  qt_dma_ch = QTA_DMA_CHANNEL_0;


  /* Loop forever */
  for (;;)
    {
      /* Process touch library events. The touch_event_dispatcher API needs to
         be called as frequently as possible in order to have a good touch response. */
      touch_event_dispatcher ();

      if (time_to_measure_touch == 1u)
	{
	  /* Clear flag: it's time to measure touch */
	  time_to_measure_touch = 0u;

	  /* Start a touch sensors measurement process. */
	  touch_ret = touch_qt_sensors_start_acquisition (TOUCH_QT_GRP_A,
							  current_time_ms_touch,
							  qt_dma_ch,
							  NORMAL_ACQ_MODE,
							  touch_qta_measure_complete_callback);
	  if ((touch_ret != TOUCH_SUCCESS) &&
	      (touch_ret != TOUCH_ACQ_INCOMPLETE))
	    {
	      while (1);
	      /* Reaching this point can be due to -
	         1. The api has retured an error due to a invalid input parameter.
	         2. The api has been called during a invalid Touch Library state. */
	    }
	}


      /* Host application code goes here */


      if (qta_measurement_done_touch == 1u)
	{
	  /* Clear flag: QTouch Group A measurement complete. */
	  qta_measurement_done_touch = 0u;

#if DEF_TOUCH_QDEBUG_ENABLE == 1
	  /* QT600 two-way QDebug communication application Example. */
	  /* Process any commands received from QTouch Studio. */
	  QDebug_ProcessCommands ();

	  /* Send out the Touch debug information data each time when Touch
	     measurement process is completed . */
	  QDebug_SendData (p_qta_measure_data->acq_status);
#endif

	}
    }				/* Loop forever */

}
Example #9
0
void vendor_data_ind(uint8_t PairingRef, profile_id_t ProfileId, uint16_t VendorId,
                          uint8_t nsduLength, uint8_t *nsdu, uint8_t RxLinkQuality,
                          uint8_t RxFlags)
{
    /* Check if vendor id matches.
       Handle here only vendor data from same vendor */
    uint16_t v_id = PGM_READ_WORD(&VendorIdentifier);
    if ((VendorId == v_id) && (RxFlags & RX_FLAG_WITH_SEC))
    {
	switch (nsdu[0])    // vendor-specific command id
        {
          
#ifdef _DEBUG_INTERFACE_
        case 0x1B:  
          {
              int i;
              for (i = 0; i < nsduLength;) 
              {
                  RxHandler(nsdu[i++]); 
              }
             
               RX_index = 4;	// Next GetChar() will get the command id
          
              /* Call QDebug_Process */
              QDebug_ProcessCommands();
              return;
          }
          break;
          
#endif
          
#ifdef TFA_BAT_MON
            case BATTERY_STATUS_REQ:
                {
                    uint16_t voltage = tfa_get_batmon_voltage();
                    nsdu[0] = BATTERY_STATUS_RESP;
                    nsdu[1] = (uint8_t)voltage;    // LSB
                    nsdu[2] = (uint8_t)(voltage >> 8);    // MSB
                    nsduLength = 3;
                }
                break;
#endif
            case ALIVE_REQ:  /* Alive request */
                vendor_app_alive_req();
                /* Send alive response */
                nsdu[0] = ALIVE_RESP;
                nsduLength = 1;
                break;

            case FW_VERSION_REQ:
                {
                    /* Send alive response */
                    nsdu[0] = FW_VERSION_RESP;
                    nsdu[1] = FW_VERSION_MAJOR;    // major version number
                    nsdu[2] = FW_VERSION_MINOR;    // minor version number
                    nsdu[3] = FW_VERSION_REV;    // revision version number
                    nsduLength = 4;
                }
                break;

            case RX_ON_REQ:
                {
                    uint32_t duration = 0;

                    memcpy(&duration, &nsdu[1], 3);
                    if (!nlme_rx_enable_request(duration))
                    {
                        /*
                         * RX enable could not been added to the queue.
                         * Therefore do not send response message.
                         */
                        return;
                    }
                    /* Send response */
                    nsdu[0] = RX_ON_RESP;
                    nsduLength = 1;
                }
                break;

#ifdef FLASH_SUPPORT
            case FW_DATA_REQ:
                {
                    fw_data_frame_t *fw_frame;
                    vendor_status_t status = VD_SUCCESS;

                    fw_frame = (fw_data_frame_t *)nsdu;

                    /* Verify data chunk size */
                    uint8_t fw_data_size = nsduLength - 5;  // 5 = header len
                    if (fw_data_size > 64)
                    {
                        status = VD_UNSUPPORTED_SIZE;
                    }
                    else
                    {
                        /* Fill temporary page buffer */
                        uint16_t start_addr = (fw_frame->frame_cnt - 1) % 4;
                        flash_fill_page_buffer(start_addr * (SPM_PAGESIZE / 4), fw_data_size, &fw_frame->fw_data[0]);
                        /* Write flash page */
                        if ((fw_frame->frame_cnt % 4) == 0)
                        {
                            uint32_t page_start_addr;
                            page_start_addr = IMAGE_START_ADDR + ((uint32_t)SPM_PAGESIZE * ((fw_frame->frame_cnt / 4) - 1));
                            flash_program_page(page_start_addr);
                        }
                        else if (fw_frame->frame_cnt == fw_frame->total_num_frames)
                        {
                            uint32_t page_start_addr;
                            page_start_addr = IMAGE_START_ADDR + ((uint32_t)SPM_PAGESIZE * (fw_frame->frame_cnt / 4));
                            flash_program_page(page_start_addr);
                        }
                    }
                    /* Send response */
                    nsdu[0] = FW_DATA_RESP;
                    nsdu[1] = status;
                    nsduLength = 2;
                }
                break;
#endif  /* #ifdef FLASH_SUPPORT */

#ifdef FLASH_SUPPORT
            case FW_SWAP_REQ:
                flash_swap(IMAGE_START_ADDR, IMAGE_SIZE);
                /* Do not send response message */
                return;
#endif  /* #ifdef FLASH_SUPPORT */

            default:
                {
                    /* Send response */
                    nsdu[0] = FW_DATA_RESP;
                    nsdu[1] = VD_NOT_SUPPORTED_ATTRIBUTE;
                    nsduLength = 2;
                }
                break;
        }

        /* Transmit response message */
        nlde_data_request(PairingRef, PROFILE_ID_VENDOR_DATA, VendorId,
                        nsduLength, nsdu,
                        TXO_UNICAST | TXO_DST_ADDR_NET | TXO_ACK_REQ | TXO_SEC_REQ | TXO_MULTI_CH | TXO_CH_NOT_SPEC | TXO_VEND_SPEC);

        /* Keep compiler happy */
        UNUSED(ProfileId);
        UNUSED(RxLinkQuality);
        UNUSED(RxFlags);
    }
}
Example #10
0
/*============================================================================
Name    :   main
------------------------------------------------------------------------------
Purpose :   main code entry point.
Input   :   n/a
Output  :   n/a
Notes   :
============================================================================*/
int main( void )
{

/*  BEFORE USING THE EXAMPLE PROJECTS.

1. The Example application uses a CPU, PBA and PBB clock of 48MHz.
   When using a different frequency setting, the following parameters must be
   changed accordingly to ensure proper QMatrix operation.
   a. QM_GCLK_CAT_DIV.
   b. QM_CAT_CLK_DIV.
   c. TOUCH_SPREAD_SPECTRUM_MAX_DEV, when Spread spectrum is enabled.
   d. PBA_HZ, when using QDebug/SPI_Master.c
   e. TARGET_PBA_FREQ_HZ and TARGET_CPU_FREQ_HZ, when using QDebug/SERIAL.c

2. In the UC3L-Evaluation kit (Rev2), the R42 and R54 (both 470KOhm) resistors
   MUST be replaced to 910KOhms.

3. The QTouch library uses PDCA channels 0 and 1.
   (QM_DMA_CHANNEL_0, QM_DMA_CHANNEL_1).
   Similarly, the QDebug/SERIAL.c uses PDCA channels 2 and 3.
   (PDCA_CHANNEL_RX_USART, PDCA_CHANNEL_TX_USART)

4. For QMatrix operation, the Analog comparators channels are used (using the
   ACIFB interface) depending on the Y Lines enabled.  For example, when
   Y lines Y2 and Y7 are enabled the Analog comparator channels 2 and 7
   are used by the CAT module for QMatrix operation.  The user can uses the rest
   of the Analog comparator channels in the main application. The QTouch Library
   enables the ACIFB using the Control register (if not already enabled by the main
   application) when the touch_qm_sensors_init API is called.

5. When two or more acquisition methods are used, care must be taken such that a
   given port pin is not used by more than one method at the same time.  The following
   pin configuration options available in touch_config_at32uc3l.h must be carefully
   chosen to avoid any overlapping.
   a. QMatrix Pin Configuration Options.
   b. Autonomous QTouch Pin Configuration Options.
   c. QTouch Group A Pin Configuration Options.
   d. QTouch Group B Pin Configuration Options.
   e. Touch Sync Pin option.
*/

  touch_ret_t touch_ret = TOUCH_SUCCESS;
  touch_qm_dma_t qm_dma;

  /* Initialize host clock, pins, watchdog, etc. */
  init_system();

  /* Disable interrupts. */
  Disable_global_interrupt();

  /* The INTC driver has to be used only for GNU GCC for AVR32. */
#if (defined __GNUC__)

  /* initialize interrupt vectors. */
  INTC_init_interrupts();

  /* Register the Timer interrupt handler to the interrupt controller. */
  INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, AVR32_INTC_INT1);

  /* Register the Touch Library CAT interrupt handler to the interrupt controller.
     Note: This interrupt registration is a MUST before using the Touch Library
     with the GCC compiler.

     For the case of IAR the registration of interrupt is automatically taken
     care by the compiler. The Touch Library CAT interrupt level for the case
     of IAR is fixed to Interrupt level 3. */
  INTC_register_interrupt(&touch_acq_done_irq, AVR32_CAT_IRQ, AVR32_INTC_INT3);

#endif

  /* Enable interrupts. */
  Enable_global_interrupt();

  /* Configure timer to fire ISR regularly. */
  init_timer();

  /* Initialize touch library and uc3l cat module for QMatrix operation.
     Note: Set up the GCLK_CAT for proper QMatrix operation.  Refer init_system(). */
  touch_ret = touch_qm_sensors_init( &touch_config );
  if(touch_ret != TOUCH_SUCCESS)
  {
    while(1u); /* Check API Error return code. */
  }

#if DEF_TOUCH_QDEBUG_ENABLE == 1
  /* Initialize the debug interface. */
  QDebug_Init();
#endif

  /* configure the touch library sensors. */
  touch_ret = config_uc3lek_touch_sensors();
  if(touch_ret != TOUCH_SUCCESS)
  {
    while(1u); /* Check API Error return code. */
  }

  /* Initialize touch sensing. */
  touch_ret = touch_qm_sensors_calibrate();
  if(touch_ret != TOUCH_SUCCESS)
  {
    while(1u); /* Check API Error return code. */
  }

  /* Provide the dma channels to be used by the CAT module.  For each
     acquisition cycle, any different combination of dma channels from 0 to 11
     can be provided. The touch library can also handle a different combination
     of dma channels for each call of the touch_qm_sensors_start_acquisition API. */
  qm_dma.dma_ch1 = QM_DMA_CHANNEL_0;
  qm_dma.dma_ch2 = QM_DMA_CHANNEL_1;

  // Initialize the PWMA module
  demo_init_pwma();

  // At the start of the demo, automatically change several times the PWMA duty
  // cycle (i.e. the intensity) of all LEDs.
  demo_automatic_ledshow_play(DEMO_INIT_NB_AUTOMATIC_CHANGES);

  /* Loop forever */
  for( ; ; )
  {
    /* Process touch library events. The touch_event_dispatcher API needs to
       be called as frequently as possible in order to have a good touch response. */
    touch_event_dispatcher();

    if( time_to_measure_touch == 1u )
    {
      /* Clear flag: it's time to measure touch */
      time_to_measure_touch = 0u;

      /* Start a touch sensors measurement process. */
      touch_ret = touch_qm_sensors_start_acquisition( current_time_ms_touch,
                                                      &qm_dma,
                                                      NORMAL_ACQ_MODE,
                                                      touch_qm_measure_complete_callback);
      if( (touch_ret != TOUCH_SUCCESS)       &&
          (touch_ret != TOUCH_ACQ_INCOMPLETE) )
      {
        gpio_clr_gpio_pin(LED0_GPIO);  // LED0
        gpio_clr_gpio_pin(LED1_GPIO);  // LED1
        gpio_clr_gpio_pin(LED2_GPIO);  // LED2
        gpio_clr_gpio_pin(LED3_GPIO);  // LED3
        do{
            delay_ms(50);
            gpio_tgl_gpio_pin(LED0_GPIO); gpio_tgl_gpio_pin(LED1_GPIO);
            gpio_tgl_gpio_pin(LED2_GPIO); gpio_tgl_gpio_pin(LED3_GPIO);
        }while(1);
       /* Reaching this point can be due to -
          1. The api has returned an error due to a invalid input parameter.
          2. The api has been called during a invalid Touch Library state. */
      }
    }


    /* Host application code goes here */


    /* Led demo application. */
    if(qm_measurement_done_touch == 1u)
    {
#if DEF_TOUCH_QDEBUG_ENABLE == 1
      /* UC3L_EK two-way QDebug communication application Example. */
      /* Process any commands received from QTouch Studio. */
      QDebug_ProcessCommands();

      /* Send out the Touch debug information data each time when Touch */
      /* measurement process is completed . */
      QDebug_SendData(p_qm_measure_data->acq_status);
#endif
      // New touch data measurement are available.
      process_qtouchlib_data();
      /* Clear flag: QMatrix measurement complete. */
      qm_measurement_done_touch = 0u;

      // Once the latest touch data measurements have been processed, clear them.
      // Here we clear only the measurements that are used by the application.
      p_qm_measure_data->p_sensor_states[0] = 0;
      p_qm_measure_data->acq_status = TOUCH_NO_ACTIVITY;
      p_qm_measure_data->p_rotor_slider_values[0] = 0;
    }
    else
      process_qtouchlib_data();
    // Note: we cannot go deeper than the IDLE sleep mode because the QMatrix lib
    // uses the PDMA.
    SLEEP(AVR32_PM_SMODE_IDLE);
  }
}
Example #11
0
touch_ret_t
touch_sensors_measure (void)
{
    touch_ret_t touch_ret = TOUCH_SUCCESS;
    touch_qt_dma_t qt_dma_ch;

    /* Provide the dma channels to be used by the CATB module.  For each
       acquisition cycle, any different two different dma channel can be provided.
       The touch library can handle different dma channels for each call of the
       touch_qt_sensors_start_acquisition API. */
    qt_dma_ch.dma_ch1 = QT_DMA_CHANNEL_0;
    qt_dma_ch.dma_ch2 = QT_DMA_CHANNEL_1;

    /* Process touch library events. The touch_event_dispatcher API needs to
       be called as frequently as possible in order to have a good touch response. */
    touch_event_dispatcher ();

    if (touch_qt_time.time_to_measure_touch == 1u)
    {
        /* Clear flag: it's time to measure touch */
        touch_qt_time.time_to_measure_touch = 0u;

        /* Start a touch sensors measurement process. */
        touch_ret = touch_qt_sensors_start_acquisition (touch_qt_time.current_time_ms,
                    qt_dma_ch,
                    NORMAL_ACQ_MODE,
                    touch_qt_measure_complete_callback);
        if ((touch_ret != TOUCH_SUCCESS) &&
                (touch_ret != TOUCH_ACQ_INCOMPLETE))
        {
            while (1);
            /* Reaching this point can be due to -
                   1. The api has retured an error due to a invalid input parameter.
                   2. The api has been called during a invalid Touch Library state. */
        }
    }


    if (touch_qt_time.measurement_done_touch == 1u)
    {
        /* Clear flag: QTouch Library measurement complete. */
        touch_qt_time.measurement_done_touch = 0u;

        /* Use Touch Status. */
        //uint8_t touch_status_sensor0 = GET_SENSOR_STATE(SENSOR_NUMBER);

        /* Use Rotor/Slider Position. */
        //uint8_t rotor_slider_position = GET_ROTOR_SLIDER_POSITION(ROTOR_SLIDER_NUMBER);

#if DEF_TOUCH_QDEBUG_ENABLE == 1
        /* QT600 two-way QDebug communication application Example. */
        /* Process any commands received from QTouch Studio. */
        QDebug_ProcessCommands ();

        /* Send out the Touch debug information data each time when Touch
               measurement process is completed .

               The Touch Signal and Touch Delta values are always sent.
               Touch Status change, Rotor-Slider Position change and Sensor Reference
               values can be optionally sent using the masks below.
               */
        QDebug_SendData ( TOUCH_CHANNEL_REF_CHANGE |
                          TOUCH_ROTOR_SLIDER_POS_CHANGE |
                          TOUCH_STATUS_CHANGE );
#endif
    }


    return (touch_ret);
}
Example #12
0
/**
 * \brief Main Application Code
 *  - Initialize the system clocks
 *  - Initialize the touch functions
 *  - Initialize the timer 
 *  - if debug interface is enabled, initialize the qdebug commmands
 *  - When touch status in detect, Set the led & send data to QTouch Studio
 */
int main (void)
{
	// status flags to indicate the re-burst for library
	uint16_t status_flag = 0u;
	uint16_t burst_flag = 0u;
	/**
	* \brief Initialize the system clock 
	* Clock settings are done in cof_clock.h
	* It sets the cpu to run at crystal frequency 
	* which uses OSC0 as souce
	*/
	sysclk_init(); 

	//! Initializes the functions necessary for QTouch
	qtouch_init();

	//! Configure the timer ISR to fire regularly for QTouch Acquisition
	init_timer_isr();


	//! Address to pass address of user functions 
	/** 
	* \brief This function is called after the library has made 
	* capacitive measurements, but before it has processed them. 
	* The user can use this hook to apply filter functions to the measured 
	* signal values.(Possibly to fix sensor layout faults) 
	*/
    qt_filter_callback = 0;

#ifdef _DEBUG_INTERFACE_
	// Initialize QDebug protocol
	QDebug_Init();
#endif

	// Enable global interrupts
	cpu_irq_enable();

#ifdef _DEBUG_INTERFACE_
	// Process commands from PC
	QDebug_ProcessCommands();
#endif

	// loop forever 
	for( ; ; ) {
		if( time_to_measure_touch ) {
			if( qt_measure_data.qt_touch_status.sensor_states[0]) {
				gpio_clr_gpio_pin(STATUS_LED);
			} else {
				gpio_set_gpio_pin(STATUS_LED);
			}

			// clear flag: it's time to measure touch
			time_to_measure_touch = 0u;

			do {
				// one time measure touch sensors
				status_flag = qt_measure_sensors( current_time_ms_touch );
				burst_flag = status_flag & QTLIB_BURST_AGAIN;

				/*Time critical host application code goes here*/

#ifdef _DEBUG_INTERFACE_
				// send debug data 
				QDebug_SendData(status_flag);
#endif

			} while (burst_flag) ;
#ifdef _DEBUG_INTERFACE_
			// Process commands from PC
			QDebug_ProcessCommands();
#endif
		}

	// Time Non-critical host application code goes here
	}  //end of loop forever
	
} // end of main
Example #13
0
/**
 * \brief Initializes the touch measurement timer.
 *
 * We need a timer that triggers approx. every millisecond.
 * The touch library seems to need this as time-base.
 */
static void init_timer(void)
{
	volatile avr32_tc_t *tc = TOUCH_MEASUREMENT_TC;

	const tc_waveform_opt_t waveform_options = {
		.channel  = TOUCH_MEASUREMENT_TC_CHANNEL,
		//! Software trigger effect on TIOB.
		.bswtrg   = TC_EVT_EFFECT_NOOP,
		//! External event effect on TIOB.
		.beevt    = TC_EVT_EFFECT_NOOP,
		//! RC compare effect on TIOB.
		.bcpc     = TC_EVT_EFFECT_NOOP,
		//! RB compare effect on TIOB.
		.bcpb     = TC_EVT_EFFECT_NOOP,
		//! Software trigger effect on TIOA.
		.aswtrg   = TC_EVT_EFFECT_NOOP,
		//! External event effect on TIOA.
		.aeevt    = TC_EVT_EFFECT_NOOP,
		//! RC compare effect on TIOA: toggle.
		.acpc     = TC_EVT_EFFECT_NOOP,
		//! RA compare effect on TIOA: toggle.
		.acpa     = TC_EVT_EFFECT_NOOP,
		//! Waveform selection
		.wavsel   = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,
		//! External event trigger enable.
		.enetrg   = 0,
		//! External event selection.
		.eevt     = 0,
		//! External event edge selection.
		.eevtedg  = TC_SEL_NO_EDGE,
		//! Counter disable when RC compare.
		.cpcdis   = 0,
		//! Counter clock stopped with RC compare.
		.cpcstop  = 0,
		//! Burst signal selection.
		.burst    = 0,
		//! Clock inversion selection.
		.clki     = 0,
		//! Internal source clock 3 (fPBA / 8).
		.tcclks   = TC_CLOCK_SOURCE_TC3
	};

	const tc_interrupt_t tc_interrupt = {
		.etrgs = 0,
		.ldrbs = 0,
		.ldras = 0,
		.cpcs  = 1,
		.cpbs  = 0,
		.cpas  = 0,
		.lovrs = 0,
		.covfs = 0,
	};

#if (defined __GNUC__)
	Disable_global_interrupt();
	INTC_register_interrupt(&tc_irq, TOUCH_MEASUREMENT_TC_IRQ,
			AVR32_INTC_INT0);
	Enable_global_interrupt();
#endif

	/* initialize the timer/counter. */
	sysclk_enable_peripheral_clock(&AVR32_TC1);
	tc_init_waveform(tc, &waveform_options);

	/* set the compare triggers. */
	tc_write_rc(tc, TOUCH_MEASUREMENT_TC_CHANNEL,
			(sysclk_get_pba_hz() / 8) / 1000);

	tc_configure_interrupts(tc, TOUCH_MEASUREMENT_TC_CHANNEL,
			&tc_interrupt);
	tc_start(tc, TOUCH_MEASUREMENT_TC_CHANNEL);
}

/**
 * \brief Initializes the touch library configuration.
 *
 * Sets the correct configuration for the QTouch library.
 */
static void qt_set_parameters(void)
{
	/* This will be modified by the user to different values. */
	qt_config_data.qt_di              = DEF_QT_DI;
	qt_config_data.qt_neg_drift_rate  = DEF_QT_NEG_DRIFT_RATE;
	qt_config_data.qt_pos_drift_rate  = DEF_QT_POS_DRIFT_RATE;
	qt_config_data.qt_max_on_duration = DEF_QT_MAX_ON_DURATION;
	qt_config_data.qt_drift_hold_time = DEF_QT_DRIFT_HOLD_TIME;
	qt_config_data.qt_recal_threshold = DEF_QT_RECAL_THRESHOLD;
	qt_config_data.qt_pos_recal_delay = DEF_QT_POS_RECAL_DELAY;

	/*
	 * This function is called after the library has made capacitive
	 * measurements, but before it has processed them. The user can use
	 * this hook to apply filter functions to the measured signal
	 * values. (Possibly to fix sensor layout faults).
	 */
	qt_filter_callback = NULL;
}

/**
 * \brief Initialize touch sensors
 *
 * The touch channels are connected on the GPIO controller 4 which is a part of
 * port X
 *
 * Touch Button:
 * GPIO
 * 98           SNSK1           CHANNEL1_SNS
 * 99           SNS1            CHANNEL1_SNSK
 *
 * Touch Slider:
 * 100          SNS0	        CHANNEL2_SNS
 * 101          SNSK0           CHANNEL2_SNSK
 * 102          SNS1            CHANNEL3_SNS
 * 103          SNSK1		CHANNEL3_SNSK
 * 104          SNS2            CHANNEL4_SNS
 * 105          SNSK2           CHANNEL4_SNSK
 */
void touch_init(void)
{
	/*
	 * Reset sensing is only needed when doing re-initialization during
	 * run-time
	 */
	// qt_reset_sensing();
	qt_enable_key(CHANNEL_1, NO_AKS_GROUP, 30u, HYST_12_5);

	/*
	 * Position hysteresis is not used in QTouch slider so this value will
	 * be ignored
	 */
	qt_enable_slider(CHANNEL_2, CHANNEL_4, NO_AKS_GROUP, 20u, HYST_12_5,
			RES_8_BIT, 0);

	qt_init_sensing();
	qt_set_parameters();

#ifdef _DEBUG_INTERFACE_
	sysclk_enable_peripheral_clock(&AVR32_SPI0);

	/* Initialize debug protocol */
	QDebug_Init();

	/* Process commands from PC */
	QDebug_ProcessCommands();
#endif

	init_timer();
}
Example #14
0
/**
 * \brief Main Application Routine
 *  - Initialize the system clocks
 *  - Initialize the sleep manager
 *  - Initialize the power save measures
 *  - Initialize the touch library and sensors
 *  - Initialize the AST to trigger CAT at regular intervals
 *  - Go to STATIC sleep mode and wake up on a touch status change
 */
int main(void)
{
#if DEF_TOUCH_QDEBUG_ENABLE == 1
	uint32_t delay_counter;
#endif
	uint32_t i;
	/* Switch on the STATUS LED */
	gpio_clr_gpio_pin(STATUS_LED);
	/* Switch off the error LED. */
	gpio_set_gpio_pin(ERROR_LED);

	/*
	 * Initialize the system clock.
	 * Note: Clock settings are specified in conf_clock.h
	 */
	sysclk_init();

	/*
	 * Initialize the sleep manager.
	 * Note: CONFIG_SLEEPMGR_ENABLE should have been defined in conf_sleepmgr.h
	 */
	sleepmgr_init();
	/* Lock required sleep mode. */
	sleepmgr_lock_mode(SLEEPMGR_STATIC);

	/* Initialize the power saving features */
	power_save_measures_init();

	/* Switch off the error LED. */
	gpio_set_gpio_pin(ERROR_LED);

#if DEF_TOUCH_QDEBUG_ENABLE == 0
	/* Initialize the AST peripheral */
	if (ast_init() != STATUS_OK) {
		/* Error initializing the AST peripheral */
		while (1) {
			for (i = 0; i < 10000; i++) {
			}
			gpio_tgl_gpio_pin(ERROR_LED);
		}
	}

#endif

	/* Initialize the touch library */
	if (touch_api_init() != STATUS_OK) {
		/* Error initializing the touch sensors */
		while (1) {
			for (i = 0; i < 10000; i++) {
			}
			gpio_tgl_gpio_pin(ERROR_LED);
		}
	}

#if DEF_TOUCH_QDEBUG_ENABLE == 1
	/* Enable PBA clock for AST clock to switch its source */
	sysclk_enable_peripheral_clock(QDEBUG_USART);
	/* 
	 * Initialize the QDebug interface.
	 * QT600 USB Bridge two-way QDebug communication.
	 */
	QDebug_Init();
#endif

	/* Turn OFF the Status LED */
	gpio_set_gpio_pin(STATUS_LED);

	/* Loop forever */
	while (1) {
#if DEF_TOUCH_QDEBUG_ENABLE == 1
		/* Process any commands received from QTouch Studio. */
		QDebug_ProcessCommands();

		/*
		 * Send out the Touch debug information data each time when
		 * Touch measurement process is completed.
		 * param - 0x000A -> Enable TOUCH_STATUS_CHANGE &
		 * TOUCH_CHANNEL_REF_CHANGE
		 * qt_lib_flags always for Autonomous QTouch.
		 */
		QDebug_SendData(0x000A);

		/* Delay to avoid sending the data to QTouch Studio too frequently. */
		for (delay_counter = 0u; delay_counter < 1200u;
				delay_counter++) {
		}

#else
		/* Enable Asynchronous Wakeup for CAT module */
		pm_asyn_wake_up_enable(AVR32_PM_AWEN_CATWEN_MASK);
		/* Disable GPIO clock after waking from sleep mode */
		sysclk_disable_pba_module(SYSCLK_GPIO);

		/* Enter STATIC sleep mode */
		sleepmgr_enter_sleep();

		/* Disable Asynchronous Wakeup for CAT module. */
		pm_asyn_wake_up_disable(AVR32_PM_AWEN_CATWEN_MASK);

		/* Clear All AST Interrupt request and clear SR */
		ast_clear_all_status_flags(&AVR32_AST);

		/**
		 * When woken up by Autonomous QTouch interrupt, the
		 * touch_at_status_change_interrupt_callback() is called that
		 * updates the autonomous_qtouch_in_touch status flag.
		 */

		/* Host application code goes here */
#endif
	}
} /* End of main() */