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 } }
/*! \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; } }
/*============================================================================ 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); } }
/** * \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; } }
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 }
/** * \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); } } }
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 */ }
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); } }
/*============================================================================ 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); } }
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); }
/** * \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
/** * \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(); }
/** * \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() */