ECE4760 - Laser Projector (ipb7, jcc384, pfc38)  1
Raster Laser Projection
joystick.c
Go to the documentation of this file.
1 
11 #include "joystick.h"
12 
13 /*******************************/
14 /* LOCAL Macro Definitions */
15 /*******************************/
17 
19 
20 /********************************/
21 /* LOCAL Type(def) Declarations */
22 /********************************/
24 
26 
27 /*******************************/
28 /* LOCAL Variable Definitions */
29 /*******************************/
31 
33 
34 /*******************************/
35 /* LOCAL Function Declarations */
36 /*******************************/
38 
40 
41 /*******************************/
42 /* GLOBAL Variable Definitions */
43 /*******************************/
45 
47 
48 /*******************************/
49 /* GLOBAL Function Definitions */
50 /*******************************/
52 
53 void joystick_init(void) {
54  PORTSetPinsDigitalIn(IOPORT_A, BIT_2);
55 
56  // ensure starts turned off
57  CloseADC10();
58 
59  // Open the ADC
60  uint32_t const config1 =
61  // turn on
62  ADC_MODULE_ON |
63  // for now we don't care about this value
64  ADC_IDLE_CONTINUE |
65  // result in hardware buffer registers are formatted as uint16_t
66  ADC_FORMAT_INTG16 |
67  // internal timer for when to end sampling and begin conversion
68  ADC_CLK_AUTO |
69  // ADC samples continuously, as fast as it likes
70  ADC_AUTO_SAMPLING_ON |
71  // you can tell the ADC to hold instead of sample, but we want it to sample
72  ADC_SAMP_ON;
73 
74  uint32_t const config2 =
75  // use internal VREFs
76  ADC_VREF_AVDD_AVSS |
77  // we are not doing "offset calibration", i.e. measuring a special value to
78  // compute error in normal measurements, see reference guide 17.5.4
79  ADC_OFFSET_CAL_DISABLE |
80  // scan through channels
81  ADC_SCAN_ON |
82  // interrrupt every two conversions (an interrupt per compelte joystick
83  // state)
84  ADC_SAMPLES_PER_INT_2 |
85  // don't alternate muxA and muxB, always use muxA
86  ADC_ALT_INPUT_OFF;
87 
88  uint32_t const config3 =
89  // number of ADC clock cycles to sample before beginning conversion. The
90  // particular number is choosen totally arbitrarily.
91  ADC_SAMPLE_TIME_6 |
92  // clock derived from PBCLK
93  ADC_CONV_CLK_SYSTEM |
94  // ADC clock prescaler: ADC clock period (TAD) is 2 * TPB
95  ADC_CONV_CLK_Tcy2;
96 
97  // which ports are analog inputs
98  uint32_t const configport =
99  ENABLE_AN0_ANA | ENABLE_AN1_ANA;
100 
101  // which ports we _don't_ scan (scan only AN0 and AN1)
102  uint32_t const configdontscan =
103  SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN4 | SKIP_SCAN_AN5 |
104  SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 |
105  SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 |
106  SKIP_SCAN_AN14 | SKIP_SCAN_AN15;
107 
108  OpenADC10(config1, config2, config3, configport, configdontscan);
109 }
110 
112  // the ADC is a 10 bit output, and we ask for it in "Integer 16 bit", which is
113  // implicitly unsigned (see family reference manual register 17-1).
114 
115  // these won't overflow because the ADC value is only in the bottom 10 bits
116  int16_t const x = (int16_t) ReadADC10(0);
117  int16_t const y = (int16_t) ReadADC10(1);
118 
119  int16_t const x_centered = x - JOYSTICK_RAW_MIDDLE;
120  int16_t const y_centered = y - JOYSTICK_RAW_MIDDLE;
121 
122  // these scale factors convert into a uniform scale, so that
123  // -JOYSTICK_OUTPUT_RANGE <= output <= JOYSTICK_OUTPUT_RANGE. The scale
124  // factors have to be signed so that the multiplication produces a signed
125  // value instead of converting the signed operand to an unsigned.
126  static int16_t const pos_scale_factor =
128  static int16_t const neg_scale_factor =
130 
131  struct joystick_vect current;
132 
133  if (x_centered > 0) {
134  current.x = x_centered * pos_scale_factor;
135  } else {
136  current.x = x_centered * neg_scale_factor;
137  }
138 
139  if (y_centered > 0) {
140  current.y = y_centered * pos_scale_factor;
141  } else {
142  current.y = y_centered * neg_scale_factor;
143  }
144 
145  return current;
146 }
147 
148 inline bool joystick_pushed(void) {
149  return PORTReadBits(IOPORT_A, BIT_2) != 0x0;
150 }
151 
153 
154 /*******************************/
155 /* ISR Definitions */
156 /*******************************/
158 
160 
161 /*******************************/
162 /* LOCAL Function Definitions */
163 /*******************************/
165 
#define JOYSTICK_RAW_NEG_RANGE
Definition: parameters.h:89
Analog joystick input.
#define JOYSTICK_RAW_MIDDLE
Definition: parameters.h:85
int16_t y
Definition: joystick.h:42
#define JOYSTICK_OUTPUT_RANGE
Definition: parameters.h:92
bool joystick_pushed(void)
Whether the joystick button is pressed.
Definition: joystick.c:148
#define JOYSTICK_RAW_POS_RANGE
Definition: parameters.h:83
int16_t x
Definition: joystick.h:41
struct joystick_vect joystick_get_pos(void)
Get most recent recorded joystick direction.
Definition: joystick.c:111
vector representing the joystick state.
Definition: joystick.h:40
void joystick_init(void)
Initialize joystick state and peripherals.
Definition: joystick.c:53