ECE4760 - Laser Projector (ipb7, jcc384, pfc38)  1
Raster Laser Projection
joystick.c File Reference

Analog joystick input. More...

#include "joystick.h"

Go to the source code of this file.

Functions

void joystick_init (void)
 Initialize joystick state and peripherals. More...
 
struct joystick_vect joystick_get_pos (void)
 Get most recent recorded joystick direction. More...
 
bool joystick_pushed (void)
 Whether the joystick button is pressed. More...
 

Detailed Description

Analog joystick input.

Author
Istvan Burbank, Peter Friend, James Cassell
Date
2016-11-10 This module has no state kept in C because the ADC runs continuously as fast as possible and when the module is polled it just polls the ADC registers.

Definition in file joystick.c.

Function Documentation

§ joystick_get_pos()

struct joystick_vect joystick_get_pos ( void  )

Get most recent recorded joystick direction.

The ADC is constantly converting, this returns the most recently sampled vector of the joystick position. This should be polled as frequently as desired, there is no notion of "consuming" a value.

Definition at line 111 of file joystick.c.

111  {
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 }
#define JOYSTICK_RAW_NEG_RANGE
Definition: parameters.h:89
#define JOYSTICK_RAW_MIDDLE
Definition: parameters.h:85
#define JOYSTICK_OUTPUT_RANGE
Definition: parameters.h:92
#define JOYSTICK_RAW_POS_RANGE
Definition: parameters.h:83
int16_t x
Definition: joystick.h:41
vector representing the joystick state.
Definition: joystick.h:40

§ joystick_init()

void joystick_init ( void  )

Initialize joystick state and peripherals.

Definition at line 53 of file joystick.c.

53  {
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 }

§ joystick_pushed()

bool joystick_pushed ( void  )
inline

Whether the joystick button is pressed.

Inteded to be polled. Any event-ish view should be provided by a state machine that consumes this.

Definition at line 148 of file joystick.c.

148  {
149  return PORTReadBits(IOPORT_A, BIT_2) != 0x0;
150 }