⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alt_touchscreen.c

📁 基于NIOSII软核的触摸屏驱动软体.采用的是AD7843触摸屏数字转换器
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************                                                                             ** License Agreement                                                           **                                                                             ** Copyright (c) 2007 Altera Corporation, San Jose, California, USA.           ** All rights reserved.                                                        **                                                                             ** Permission is hereby granted, free of charge, to any person obtaining a     ** copy of this software and associated documentation files (the "Software"),  ** to deal in the Software without restriction, including without limitation   ** the rights to use, copy, modify, merge, publish, distribute, sublicense,    ** and/or sell copies of the Software, and to permit persons to whom the       ** Software is furnished to do so, subject to the following conditions:        **                                                                             ** The above copyright notice and this permission notice shall be included in  ** all copies or substantial portions of the Software.                         **                                                                             ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     ** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         ** DEALINGS IN THE SOFTWARE.                                                   **                                                                             ** This agreement shall be governed in all respects by the laws of the State   ** of California and by the laws of the United States of America.              **                                                                             *******************************************************************************//***************************************************************** * * alt_touchscreen  *  *    A large comment atop the header-file describes this  *    module, its API, and its operation in gruesome detail. *  ****************************************************************/#include "alt_touchscreen.h"#include "altera_avalon_spi_regs.h"#include "altera_avalon_pio_regs.h"#include "sys/alt_irq.h"#include <stdio.h>#include <unistd.h>staticint axis_scaler_compute_output (alt_touchscreen_axis_scaler* as, int input){  int output;  int numerator   =    (input - as->input_A) * (as->output_B - as->output_A);  //                   -----------------------------------------------------  int denominator = 	           (as->input_B - as->input_A);            output  = (numerator / denominator) + as->output_A;  return output;}staticvoid surface_scaler_compute_output (alt_touchscreen_surface_scaler*  ss,				    int  input_x,  int  input_y,				    int* output_x, int* output_y){  *output_x = axis_scaler_compute_output (&(ss->x), input_x);  *output_y = axis_scaler_compute_output (&(ss->y), input_y);}				    staticvoid surface_scaler_set_lower_left (alt_touchscreen_surface_scaler*  ss,				    int input_x,   int input_y,				    int output_x,  int output_y){  ss->x.input_A  = input_x;  ss->y.input_A  = input_y;  ss->x.output_A = output_x;  ss->y.output_A = output_y;}staticvoid surface_scaler_set_upper_right (alt_touchscreen_surface_scaler*  ss,				     int input_x,   int input_y,				     int output_x,  int output_y){  ss->x.input_B  = input_x;  ss->y.input_B  = input_y;  ss->x.output_B = output_x;  ss->y.output_B = output_y;}////////////////////////////////////////////////////////////////// pen_state_init//////////////////////////////////////////////////////////////////staticvoid  pen_state_init (alt_touchscreen_pen_state* ps){  ps->pen_down           = 0;  ps->previous_pen_down  = 0;  ps->pen_detect_counter = 0;  ps->sample_number      = 0;}////////////////////////////////////////////////////////////////// pen_state_update_from_detect_sample////  You pass-in the current reading from the pen-detect PIO, //  And this makes the pen up/down determination, plus keeps //  history necessary for detecting transitions.////  You're supposed to call this whenever:////    1) You've just gathered a new sample from the ADC and checked//       the pen-state, or...////    2) You've responded to a timer-callback and, before taking a//       sample, you've noticed that the pen is up.  //// Case (1) is boring. Of course you want to update the pen-state// after gathering a fresh X/Y sample.  Case (2) is more subtle.  You// only want to update the pen-state in the timer-callback if the pen// is UP.  If you detect the pen is down, you don't want to go// promising anyone any sample-data (an implicit promise when you// declare "The pen is down!") until you've actually read the ADCs to// figure-out where the pen is.  In short: Don't call this if you've// noticed the pen is down, but you haven't actually taken a sample yet.////  Implementation note://     This actually waits for the second pen-detection event before//  declaring that "The pen is down."  I honestly don't see why this//  is ncessary--there must be some subtlety in the program-logic that//  I've missed.  I do know this:  If you don't put in a one-count//  delay, then the first pen-location your application sees is an OLD//  x-y value every time the pen goes down.  Adding a one-count delay//  in this routine fixes that problem.  Mysteriously.  I'm sure it//  all makes sense, I just can't explain it.////  NOTE: the caller must take care to grab a sample from the PIO at the//  right time.  The PIO does not contain a valid value when any//  SPI-commands are in-process to the ADC.  Read the ADC datasheet//  for a complete description.//////////////////////////////////////////////////////////////////staticvoid pen_state_update_from_detect_sample (alt_touchscreen_pen_state* ps,					  int pen_detect_sample) {  ps->sample_number++;  if (pen_detect_sample)     ps->pen_detect_counter++;  else    ps->pen_detect_counter = 0;      ps->previous_pen_down = ps->pen_down;  ps->pen_down          = ps->pen_detect_counter > 1;}////////////////////////////////////////////////////////////////// event_flag_group_init////   Simple: initializes the event-flag structure.//////////////////////////////////////////////////////////////////staticvoid  event_flag_group_init (alt_touchscreen_event_flag_group* efg){  efg->pen_up_event_flag    = 0;  efg->pen_move_event_flag  = 0;  efg->pen_down_event_flag  = 0;}////////////////////////////////////////////////////////////////// event_flag_group_update_from_pen_state////  An "event" is a change from one state to another. This routine //  can only ever SET flags.  They are CLEARED when they're//  acknowledged by the receiver in the application context.  This//  routine is supposed to be called in the interrput context.  ////  Although it's worth considering:  Should this actually be called//  in the application context?   I think not...but it's a subtle//  point and, says me, worth considering carefully.//////////////////////////////////////////////////////////////////staticvoid event_flag_group_update_from_pen_state     (alt_touchscreen_event_flag_group* efg,     alt_touchscreen_pen_state* ps){  efg->pen_up_event_flag   |=   (!ps->pen_down  &&  ps->previous_pen_down);  efg->pen_down_event_flag |=   ( ps->pen_down  && !ps->previous_pen_down);  efg->pen_move_event_flag |=     ps->pen_down;}////////////////////////////////////////////////////////////////// callback_registry_entry_init////   Simple: initializes the event-callback structure.//////////////////////////////////////////////////////////////////staticvoid callback_registry_entry_init(alt_touchscreen_callback_registry_entry* cbre) {  cbre->trigger       = ALT_TOUCHSCREEN_CALLBACK_NEVER;  cbre->callback_func = NULL;  cbre->context       = NULL;}////////////////////////////////////////////////////////////////// callback_registry_entry_test_and_do //// Check my trigger-condition against the provided trigger-condition// If it's my trigger-type...then call my callback-function.//////////////////////////////////////////////////////////////////staticvoid callback_registry_entry_do_on_trigger (		  alt_touchscreen_callback_registry_entry* cbre,		  alt_touchscreen_callback_trigger         trigger_kind,		  alt_touchscreen_scaled_pen_data*         pen_data){  if ((cbre->callback_func != NULL        ) &&       (cbre->trigger       == trigger_kind)   )    (cbre->callback_func)(pen_data->pen_down,			  pen_data->x,			  pen_data->y,			  cbre->context);}////////////////////////////////////////////////////////////////// callback_registry_entry_is_registered//// Query function: Returns true if this entry is properly-registered,// false if it's empty (unregistered).//////////////////////////////////////////////////////////////////staticint callback_registry_entry_is_registered (		   alt_touchscreen_callback_registry_entry* cbre){  return (cbre->trigger == ALT_TOUCHSCREEN_CALLBACK_NEVER);}////////////////////////////////////////////////////////////////// callback_registry_init////   Simple: initializes the event-callback registry (array).//           Just stuffs it full of initialized registry-entries.//////////////////////////////////////////////////////////////////staticvoid callback_registry_init (alt_touchscreen_callback_registry* cbr) {  int i = 0;  // Get a pointer to the first registry-entry:  alt_touchscreen_callback_registry_entry* cbre = &((cbr->registry)[0]);    for (i = 0; i < ALT_TOUCHSCREEN_CALLBACK_REGISTRY_NUM_ENTRIES; i++)     callback_registry_entry_init (cbre++);}////////////////////////////////////////////////////////////////// callback_registry_dispatch_one_type//// Check all registered callbacks against the provided trigger-condition// and event-flag.  //// If the event-flag is zero, obviously we don't want to call anybody.//// The event-flag is acknowledged (set to zero) after all callbacks.//////////////////////////////////////////////////////////////////staticvoid callback_registry_dispatch_one_type (		  alt_touchscreen_callback_registry* cbr,		  alt_touchscreen_callback_trigger   trigger_kind,		  volatile int*                      trigger_flag,		  alt_touchscreen_scaled_pen_data*   pen_data){  int i;  alt_touchscreen_callback_registry_entry* cbre = &((cbr->registry)[0]);  // If the condition isn't even asserted, don't bother with anything else.  if (*trigger_flag == 0)    return;  // We've seen the flag, so acknowledge (clear) it.  *trigger_flag = 0;  for (i = 0; i < ALT_TOUCHSCREEN_CALLBACK_REGISTRY_NUM_ENTRIES; i++)     callback_registry_entry_do_on_trigger (cbre++,  trigger_kind, pen_data);   }////////////////////////////////////////////////////////////////// callback_dispatch_from_event_flags//// Dispatches all the callbacks in the registry based on all the // events in the event-flag group.//// The event-flags are cleared after the callbacks, even if none.//////////////////////////////////////////////////////////////////staticvoid callback_registry_dispatch_from_event_flag_group (		   alt_touchscreen_callback_registry* cbr,		   alt_touchscreen_event_flag_group*  efg,		   alt_touchscreen_scaled_pen_data*   pen_data){  callback_registry_dispatch_one_type (cbr, 				       ALT_TOUCHSCREEN_CALLBACK_ON_PEN_UP,   				       &(efg->pen_up_event_flag  ),				       pen_data);  callback_registry_dispatch_one_type (cbr, 				       ALT_TOUCHSCREEN_CALLBACK_ON_PEN_DOWN, 				       &(efg->pen_down_event_flag),				       pen_data);  callback_registry_dispatch_one_type (cbr, 				       ALT_TOUCHSCREEN_CALLBACK_ON_PEN_MOVE, 				       &(efg->pen_move_event_flag),				       pen_data);}////////////////////////////////////////////////////////////////// callback_registry_get_empty_entry //// Returns a pointer to the next empty entry in the callback-registry,// or NULL if there are no empty entries.//////////////////////////////////////////////////////////////////staticalt_touchscreen_callback_registry_entry*    callback_registry_get_empty_entry (alt_touchscreen_callback_registry* cbr){  int i;  alt_touchscreen_callback_registry_entry* cbre = &((cbr->registry)[0]);  for (i = 0; i < ALT_TOUCHSCREEN_CALLBACK_REGISTRY_NUM_ENTRIES; i++) {    if (callback_registry_entry_is_registered (cbre))      return cbre;    cbre++;  }  return NULL;   // No empty entries found.}////////////////////////////////////////////////////////////////// callback_registry_register_callback// // Registers the requested callback-type.// // Returns zero if successful, nonzero on failure.//// Failure happens if you try to register too many callbacks.//////////////////////////////////////////////////////////////////staticint callback_registry_register_callback (		   alt_touchscreen_callback_registry*   cbr,		   alt_touchscreen_callback_trigger     reason,		   alt_touchscreen_event_callback_func  callback_func,		   void*                                context){  alt_touchscreen_callback_registry_entry* cbre =     callback_registry_get_empty_entry (cbr);      if (cbre == NULL)    return -1;    cbre->trigger       = reason;  cbre->callback_func = callback_func;  cbre->context       = context;  return 0;}////////////////////////////////////////////////////////////////// assemble_sample////  You have to read the 8-bit SPI rx-data register twice to get a//  full sample (because samples are 12 bits).  ////  The first 7 bits get stored in the screen's "partial_data_sample"//  field.  This combines those with a (presumptive) successive value//  from the rx-data register to form a full sample.//////////////////////////////////////////////////////////////////staticinline int assemble_sample (alt_u8 first_rxdata_value, 			    alt_u8 second_rxdata_value){  // Top-7 bits come from previous sample, bottom 5 from this one.  return   ((first_rxdata_value  << 5)       ) |            ((second_rxdata_value >> 3) & 0x1F) ;}static void sample_machine_assemble_x_y (alt_touchscreen_sample_machine* sm,				  int* x,int* y){  *x = assemble_sample ((sm->rxdata_values)[1], (sm->rxdata_values)[2]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -