Wrapped Freescale Cup code for the UT CS summer boot camp.

Dependencies:   MMA8451Q mbed

Committer:
ccoleman
Date:
Fri Aug 23 00:38:23 2013 +0000
Revision:
4:4233d072b5af
Parent:
0:2010bcffbae0
Added more backend stuff.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccoleman 0:2010bcffbae0 1 #include "mbed.h"
ccoleman 0:2010bcffbae0 2 #include "TFC.h"
ccoleman 0:2010bcffbae0 3
ccoleman 0:2010bcffbae0 4 #define FTM1_CLK_PRESCALE 6// Prescale Selector value - see comments in Status Control (SC) section for more details
ccoleman 0:2010bcffbae0 5 #define SERVO_DEFAULT_PERIOD (float)(.020) // Desired Frequency of PWM Signal - Here 50Hz => 20ms period
ccoleman 0:2010bcffbae0 6 // use these to dial in servo steering to your particular servo
ccoleman 0:2010bcffbae0 7 #define SERVO_MIN_PULSE_WIDTH_DEFAULT (float)(.0005) // The number here should be be *pulse width* in seconds to move servo to its left limit
ccoleman 0:2010bcffbae0 8 #define SERVO_MAX_PULSE_WIDTH_DEFAULT (float)(.002) // The number here should be be *pulse width* in seconds to move servo to its left limit
ccoleman 0:2010bcffbae0 9
ccoleman 0:2010bcffbae0 10
ccoleman 0:2010bcffbae0 11 #define FTM0_CLOCK (SystemCoreClock/2)
ccoleman 0:2010bcffbae0 12 #define FTM0_CLK_PRESCALE (0) // Prescale Selector value - see comments in Status Control (SC) section for more details
ccoleman 0:2010bcffbae0 13 #define FTM0_DEFAULT_SWITCHING_FREQUENCY (4000.0)
ccoleman 0:2010bcffbae0 14
ccoleman 0:2010bcffbae0 15 #define ADC_MAX_CODE (255)
ccoleman 0:2010bcffbae0 16
ccoleman 0:2010bcffbae0 17 #define TAOS_CLK_HIGH PTE->PSOR = (1<<1)
ccoleman 0:2010bcffbae0 18 #define TAOS_CLK_LOW PTE->PCOR = (1<<1)
ccoleman 0:2010bcffbae0 19 #define TAOS_SI_HIGH PTD->PSOR = (1<<7)
ccoleman 0:2010bcffbae0 20 #define TAOS_SI_LOW PTD->PCOR = (1<<7)
ccoleman 0:2010bcffbae0 21
ccoleman 0:2010bcffbae0 22 #define ADC_STATE_INIT 0
ccoleman 0:2010bcffbae0 23 #define ADC_STATE_CAPTURE_POT_0 1
ccoleman 0:2010bcffbae0 24 #define ADC_STATE_CAPTURE_POT_1 2
ccoleman 0:2010bcffbae0 25 #define ADC_STATE_CAPTURE_BATTERY_LEVEL 3
ccoleman 0:2010bcffbae0 26 #define ADC_STATE_CAPTURE_LINE_SCAN 4
ccoleman 0:2010bcffbae0 27
ccoleman 0:2010bcffbae0 28
ccoleman 0:2010bcffbae0 29 #define TFC_POT_0_ADC_CHANNEL 13
ccoleman 0:2010bcffbae0 30 #define TFC_POT_1_ADC_CHANNEL 12
ccoleman 0:2010bcffbae0 31 #define TFC_BAT_SENSE_CHANNEL 4
ccoleman 0:2010bcffbae0 32 #define TFC_LINESCAN0_ADC_CHANNEL 6
ccoleman 0:2010bcffbae0 33 #define TFC_LINESCAN1_ADC_CHANNEL 7
ccoleman 0:2010bcffbae0 34
ccoleman 0:2010bcffbae0 35
ccoleman 0:2010bcffbae0 36 #define ADC0_irq_no 57
ccoleman 0:2010bcffbae0 37 #define ADC1_irq_no 58
ccoleman 0:2010bcffbae0 38
ccoleman 0:2010bcffbae0 39 #define ADC0_CHANA 19 // set to desired ADC0 channel trigger A
ccoleman 0:2010bcffbae0 40 #define ADC0_CHANB 20 // set to desired ADC0 channel trigger B
ccoleman 0:2010bcffbae0 41
ccoleman 0:2010bcffbae0 42 #define ADC1_CHANA 20 // set to desired ADC1 channel trigger A 20 defaults to potentiometer in TWRK60
ccoleman 0:2010bcffbae0 43 #define ADC1_CHANB 20 // set to desired ADC1 channel trigger B
ccoleman 0:2010bcffbae0 44
ccoleman 0:2010bcffbae0 45 #define ADC0_DLYA 0x2000 // ADC0 trigger A delay
ccoleman 0:2010bcffbae0 46 #define ADC0_DLYB 0x4000 // ADC0 trigger B delay
ccoleman 0:2010bcffbae0 47 #define ADC1_DLYA 0x6000 // ADC1 trigger A delay
ccoleman 0:2010bcffbae0 48 #define ADC1_DLYB 0x7fff // ADC1 trigger B delay
ccoleman 0:2010bcffbae0 49
ccoleman 0:2010bcffbae0 50
ccoleman 0:2010bcffbae0 51 #define ADC0A_DONE 0x01
ccoleman 0:2010bcffbae0 52 #define ADC0B_DONE 0x02
ccoleman 0:2010bcffbae0 53 #define ADC1A_DONE 0x04
ccoleman 0:2010bcffbae0 54 #define ADC1B_DONE 0x08
ccoleman 0:2010bcffbae0 55
ccoleman 0:2010bcffbae0 56
ccoleman 0:2010bcffbae0 57 // Bit shifting of bitfiled is already taken into account so
ccoleman 0:2010bcffbae0 58 // bitfiled values are always represented as relative to their position.
ccoleman 0:2010bcffbae0 59
ccoleman 0:2010bcffbae0 60 /************************* #Defines ******************************************/
ccoleman 0:2010bcffbae0 61
ccoleman 0:2010bcffbae0 62 #define A 0x0
ccoleman 0:2010bcffbae0 63 #define B 0x1
ccoleman 0:2010bcffbae0 64
ccoleman 0:2010bcffbae0 65 /////// NOTE: the following defines relate to the ADC register definitions
ccoleman 0:2010bcffbae0 66 /////// and the content follows the reference manual, using the same symbols.
ccoleman 0:2010bcffbae0 67
ccoleman 0:2010bcffbae0 68
ccoleman 0:2010bcffbae0 69 //// ADCSC1 (register)
ccoleman 0:2010bcffbae0 70
ccoleman 0:2010bcffbae0 71 // Conversion Complete (COCO) mask
ccoleman 0:2010bcffbae0 72 #define COCO_COMPLETE ADC_SC1_COCO_MASK
ccoleman 0:2010bcffbae0 73 #define COCO_NOT 0x00
ccoleman 0:2010bcffbae0 74
ccoleman 0:2010bcffbae0 75 // ADC interrupts: enabled, or disabled.
ccoleman 0:2010bcffbae0 76 #define AIEN_ON ADC_SC1_AIEN_MASK
ccoleman 0:2010bcffbae0 77 #define AIEN_OFF 0x00
ccoleman 0:2010bcffbae0 78
ccoleman 0:2010bcffbae0 79 // Differential or Single ended ADC input
ccoleman 0:2010bcffbae0 80 #define DIFF_SINGLE 0x00
ccoleman 0:2010bcffbae0 81 #define DIFF_DIFFERENTIAL ADC_SC1_DIFF_MASK
ccoleman 0:2010bcffbae0 82
ccoleman 0:2010bcffbae0 83 //// ADCCFG1
ccoleman 0:2010bcffbae0 84
ccoleman 0:2010bcffbae0 85 // Power setting of ADC
ccoleman 0:2010bcffbae0 86 #define ADLPC_LOW ADC_CFG1_ADLPC_MASK
ccoleman 0:2010bcffbae0 87 #define ADLPC_NORMAL 0x00
ccoleman 0:2010bcffbae0 88
ccoleman 0:2010bcffbae0 89 // Clock divisor
ccoleman 0:2010bcffbae0 90 #define ADIV_1 0x00
ccoleman 0:2010bcffbae0 91 #define ADIV_2 0x01
ccoleman 0:2010bcffbae0 92 #define ADIV_4 0x02
ccoleman 0:2010bcffbae0 93 #define ADIV_8 0x03
ccoleman 0:2010bcffbae0 94
ccoleman 0:2010bcffbae0 95 // Long samle time, or Short sample time
ccoleman 0:2010bcffbae0 96 #define ADLSMP_LONG ADC_CFG1_ADLSMP_MASK
ccoleman 0:2010bcffbae0 97 #define ADLSMP_SHORT 0x00
ccoleman 0:2010bcffbae0 98
ccoleman 0:2010bcffbae0 99 // How many bits for the conversion? 8, 12, 10, or 16 (single ended).
ccoleman 0:2010bcffbae0 100 #define MODE_8 0x00
ccoleman 0:2010bcffbae0 101 #define MODE_12 0x01
ccoleman 0:2010bcffbae0 102 #define MODE_10 0x02
ccoleman 0:2010bcffbae0 103 #define MODE_16 0x03
ccoleman 0:2010bcffbae0 104
ccoleman 0:2010bcffbae0 105
ccoleman 0:2010bcffbae0 106
ccoleman 0:2010bcffbae0 107 // ADC Input Clock Source choice? Bus clock, Bus clock/2, "altclk", or the
ccoleman 0:2010bcffbae0 108 // ADC's own asynchronous clock for less noise
ccoleman 0:2010bcffbae0 109 #define ADICLK_BUS 0x00
ccoleman 0:2010bcffbae0 110 #define ADICLK_BUS_2 0x01
ccoleman 0:2010bcffbae0 111 #define ADICLK_ALTCLK 0x02
ccoleman 0:2010bcffbae0 112 #define ADICLK_ADACK 0x03
ccoleman 0:2010bcffbae0 113
ccoleman 0:2010bcffbae0 114 //// ADCCFG2
ccoleman 0:2010bcffbae0 115
ccoleman 0:2010bcffbae0 116 // Select between B or A channels
ccoleman 0:2010bcffbae0 117 #define MUXSEL_ADCB ADC_CFG2_MUXSEL_MASK
ccoleman 0:2010bcffbae0 118 #define MUXSEL_ADCA 0x00
ccoleman 0:2010bcffbae0 119
ccoleman 0:2010bcffbae0 120 // Ansync clock output enable: enable, or disable the output of it
ccoleman 0:2010bcffbae0 121 #define ADACKEN_ENABLED ADC_CFG2_ADACKEN_MASK
ccoleman 0:2010bcffbae0 122 #define ADACKEN_DISABLED 0x00
ccoleman 0:2010bcffbae0 123
ccoleman 0:2010bcffbae0 124 // High speed or low speed conversion mode
ccoleman 0:2010bcffbae0 125 #define ADHSC_HISPEED ADC_CFG2_ADHSC_MASK
ccoleman 0:2010bcffbae0 126 #define ADHSC_NORMAL 0x00
ccoleman 0:2010bcffbae0 127
ccoleman 0:2010bcffbae0 128 // Long Sample Time selector: 20, 12, 6, or 2 extra clocks for a longer sample time
ccoleman 0:2010bcffbae0 129 #define ADLSTS_20 0x00
ccoleman 0:2010bcffbae0 130 #define ADLSTS_12 0x01
ccoleman 0:2010bcffbae0 131 #define ADLSTS_6 0x02
ccoleman 0:2010bcffbae0 132 #define ADLSTS_2 0x03
ccoleman 0:2010bcffbae0 133
ccoleman 0:2010bcffbae0 134 ////ADCSC2
ccoleman 0:2010bcffbae0 135
ccoleman 0:2010bcffbae0 136 // Read-only status bit indicating conversion status
ccoleman 0:2010bcffbae0 137 #define ADACT_ACTIVE ADC_SC2_ADACT_MASK
ccoleman 0:2010bcffbae0 138 #define ADACT_INACTIVE 0x00
ccoleman 0:2010bcffbae0 139
ccoleman 0:2010bcffbae0 140 // Trigger for starting conversion: Hardware trigger, or software trigger.
ccoleman 0:2010bcffbae0 141 // For using PDB, the Hardware trigger option is selected.
ccoleman 0:2010bcffbae0 142 #define ADTRG_HW ADC_SC2_ADTRG_MASK
ccoleman 0:2010bcffbae0 143 #define ADTRG_SW 0x00
ccoleman 0:2010bcffbae0 144
ccoleman 0:2010bcffbae0 145 // ADC Compare Function Enable: Disabled, or Enabled.
ccoleman 0:2010bcffbae0 146 #define ACFE_DISABLED 0x00
ccoleman 0:2010bcffbae0 147 #define ACFE_ENABLED ADC_SC2_ACFE_MASK
ccoleman 0:2010bcffbae0 148
ccoleman 0:2010bcffbae0 149 // Compare Function Greater Than Enable: Greater, or Less.
ccoleman 0:2010bcffbae0 150 #define ACFGT_GREATER ADC_SC2_ACFGT_MASK
ccoleman 0:2010bcffbae0 151 #define ACFGT_LESS 0x00
ccoleman 0:2010bcffbae0 152
ccoleman 0:2010bcffbae0 153 // Compare Function Range Enable: Enabled or Disabled.
ccoleman 0:2010bcffbae0 154 #define ACREN_ENABLED ADC_SC2_ACREN_MASK
ccoleman 0:2010bcffbae0 155 #define ACREN_DISABLED 0x00
ccoleman 0:2010bcffbae0 156
ccoleman 0:2010bcffbae0 157 // DMA enable: enabled or disabled.
ccoleman 0:2010bcffbae0 158 #define DMAEN_ENABLED ADC_SC2_DMAEN_MASK
ccoleman 0:2010bcffbae0 159 #define DMAEN_DISABLED 0x00
ccoleman 0:2010bcffbae0 160
ccoleman 0:2010bcffbae0 161 // Voltage Reference selection for the ADC conversions
ccoleman 0:2010bcffbae0 162 // (***not*** the PGA which uses VREFO only).
ccoleman 0:2010bcffbae0 163 // VREFH and VREFL (0) , or VREFO (1).
ccoleman 0:2010bcffbae0 164
ccoleman 0:2010bcffbae0 165 #define REFSEL_EXT 0x00
ccoleman 0:2010bcffbae0 166 #define REFSEL_ALT 0x01
ccoleman 0:2010bcffbae0 167 #define REFSEL_RES 0x02 /* reserved */
ccoleman 0:2010bcffbae0 168 #define REFSEL_RES_EXT 0x03 /* reserved but defaults to Vref */
ccoleman 0:2010bcffbae0 169
ccoleman 0:2010bcffbae0 170 ////ADCSC3
ccoleman 0:2010bcffbae0 171
ccoleman 0:2010bcffbae0 172 // Calibration begin or off
ccoleman 0:2010bcffbae0 173 #define CAL_BEGIN ADC_SC3_CAL_MASK
ccoleman 0:2010bcffbae0 174 #define CAL_OFF 0x00
ccoleman 0:2010bcffbae0 175
ccoleman 0:2010bcffbae0 176 // Status indicating Calibration failed, or normal success
ccoleman 0:2010bcffbae0 177 #define CALF_FAIL ADC_SC3_CALF_MASK
ccoleman 0:2010bcffbae0 178 #define CALF_NORMAL 0x00
ccoleman 0:2010bcffbae0 179
ccoleman 0:2010bcffbae0 180 // ADC to continously convert, or do a sinle conversion
ccoleman 0:2010bcffbae0 181 #define ADCO_CONTINUOUS ADC_SC3_ADCO_MASK
ccoleman 0:2010bcffbae0 182 #define ADCO_SINGLE 0x00
ccoleman 0:2010bcffbae0 183
ccoleman 0:2010bcffbae0 184 // Averaging enabled in the ADC, or not.
ccoleman 0:2010bcffbae0 185 #define AVGE_ENABLED ADC_SC3_AVGE_MASK
ccoleman 0:2010bcffbae0 186 #define AVGE_DISABLED 0x00
ccoleman 0:2010bcffbae0 187
ccoleman 0:2010bcffbae0 188 // How many to average prior to "interrupting" the MCU? 4, 8, 16, or 32
ccoleman 0:2010bcffbae0 189 #define AVGS_4 0x00
ccoleman 0:2010bcffbae0 190 #define AVGS_8 0x01
ccoleman 0:2010bcffbae0 191 #define AVGS_16 0x02
ccoleman 0:2010bcffbae0 192 #define AVGS_32 0x03
ccoleman 0:2010bcffbae0 193
ccoleman 0:2010bcffbae0 194 ////PGA
ccoleman 0:2010bcffbae0 195
ccoleman 0:2010bcffbae0 196 // PGA enabled or not?
ccoleman 0:2010bcffbae0 197 #define PGAEN_ENABLED ADC_PGA_PGAEN_MASK
ccoleman 0:2010bcffbae0 198 #define PGAEN_DISABLED 0x00
ccoleman 0:2010bcffbae0 199
ccoleman 0:2010bcffbae0 200 // Chopper stabilization of the amplifier, or not.
ccoleman 0:2010bcffbae0 201 #define PGACHP_CHOP ADC_PGA_PGACHP_MASK
ccoleman 0:2010bcffbae0 202 #define PGACHP_NOCHOP 0x00
ccoleman 0:2010bcffbae0 203
ccoleman 0:2010bcffbae0 204 // PGA in low power mode, or normal mode.
ccoleman 0:2010bcffbae0 205 #define PGALP_LOW ADC_PGA_PGALP_MASK
ccoleman 0:2010bcffbae0 206 #define PGALP_NORMAL 0x00
ccoleman 0:2010bcffbae0 207
ccoleman 0:2010bcffbae0 208 // Gain of PGA. Selectable from 1 to 64.
ccoleman 0:2010bcffbae0 209 #define PGAG_1 0x00
ccoleman 0:2010bcffbae0 210 #define PGAG_2 0x01
ccoleman 0:2010bcffbae0 211 #define PGAG_4 0x02
ccoleman 0:2010bcffbae0 212 #define PGAG_8 0x03
ccoleman 0:2010bcffbae0 213 #define PGAG_16 0x04
ccoleman 0:2010bcffbae0 214 #define PGAG_32 0x05
ccoleman 0:2010bcffbae0 215 #define PGAG_64 0x06
ccoleman 0:2010bcffbae0 216
ccoleman 0:2010bcffbae0 217
ccoleman 0:2010bcffbae0 218 #define ADC_STATE_INIT 0
ccoleman 0:2010bcffbae0 219 #define ADC_STATE_CAPTURE_POT_0 1
ccoleman 0:2010bcffbae0 220 #define ADC_STATE_CAPTURE_POT_1 2
ccoleman 0:2010bcffbae0 221 #define ADC_STATE_CAPTURE_BATTERY_LEVEL 3
ccoleman 0:2010bcffbae0 222 #define ADC_STATE_CAPTURE_LINE_SCAN 4
ccoleman 0:2010bcffbae0 223
ccoleman 0:2010bcffbae0 224
ccoleman 0:2010bcffbae0 225 /////////// The above values fit into the structure below to select ADC/PGA
ccoleman 0:2010bcffbae0 226 /////////// configuration desired:
ccoleman 0:2010bcffbae0 227
ccoleman 0:2010bcffbae0 228 typedef struct adc_cfg {
ccoleman 0:2010bcffbae0 229 uint8_t CONFIG1;
ccoleman 0:2010bcffbae0 230 uint8_t CONFIG2;
ccoleman 0:2010bcffbae0 231 uint16_t COMPARE1;
ccoleman 0:2010bcffbae0 232 uint16_t COMPARE2;
ccoleman 0:2010bcffbae0 233 uint8_t STATUS2;
ccoleman 0:2010bcffbae0 234 uint8_t STATUS3;
ccoleman 0:2010bcffbae0 235 uint8_t STATUS1A;
ccoleman 0:2010bcffbae0 236 uint8_t STATUS1B;
ccoleman 0:2010bcffbae0 237 uint32_t PGA;
ccoleman 0:2010bcffbae0 238 } *tADC_ConfigPtr, tADC_Config ;
ccoleman 0:2010bcffbae0 239
ccoleman 0:2010bcffbae0 240
ccoleman 0:2010bcffbae0 241 #define CAL_BLK_NUMREC 18
ccoleman 0:2010bcffbae0 242
ccoleman 0:2010bcffbae0 243 typedef struct adc_cal {
ccoleman 0:2010bcffbae0 244
ccoleman 0:2010bcffbae0 245 uint16_t OFS;
ccoleman 0:2010bcffbae0 246 uint16_t PG;
ccoleman 0:2010bcffbae0 247 uint16_t MG;
ccoleman 0:2010bcffbae0 248 uint8_t CLPD;
ccoleman 0:2010bcffbae0 249 uint8_t CLPS;
ccoleman 0:2010bcffbae0 250 uint16_t CLP4;
ccoleman 0:2010bcffbae0 251 uint16_t CLP3;
ccoleman 0:2010bcffbae0 252 uint8_t CLP2;
ccoleman 0:2010bcffbae0 253 uint8_t CLP1;
ccoleman 0:2010bcffbae0 254 uint8_t CLP0;
ccoleman 0:2010bcffbae0 255 uint8_t dummy;
ccoleman 0:2010bcffbae0 256 uint8_t CLMD;
ccoleman 0:2010bcffbae0 257 uint8_t CLMS;
ccoleman 0:2010bcffbae0 258 uint16_t CLM4;
ccoleman 0:2010bcffbae0 259 uint16_t CLM3;
ccoleman 0:2010bcffbae0 260 uint8_t CLM2;
ccoleman 0:2010bcffbae0 261 uint8_t CLM1;
ccoleman 0:2010bcffbae0 262 uint8_t CLM0;
ccoleman 0:2010bcffbae0 263 } tADC_Cal_Blk ;
ccoleman 0:2010bcffbae0 264
ccoleman 0:2010bcffbae0 265 typedef struct ADC_MemMap {
ccoleman 0:2010bcffbae0 266 uint32_t SC1[2]; /**< ADC Status and Control Registers 1, array offset: 0x0, array step: 0x4 */
ccoleman 0:2010bcffbae0 267 uint32_t CFG1; /**< ADC Configuration Register 1, offset: 0x8 */
ccoleman 0:2010bcffbae0 268 uint32_t CFG2; /**< ADC Configuration Register 2, offset: 0xC */
ccoleman 0:2010bcffbae0 269 uint32_t R[2]; /**< ADC Data Result Register, array offset: 0x10, array step: 0x4 */
ccoleman 0:2010bcffbae0 270 uint32_t CV1; /**< Compare Value Registers, offset: 0x18 */
ccoleman 0:2010bcffbae0 271 uint32_t CV2; /**< Compare Value Registers, offset: 0x1C */
ccoleman 0:2010bcffbae0 272 uint32_t SC2; /**< Status and Control Register 2, offset: 0x20 */
ccoleman 0:2010bcffbae0 273 uint32_t SC3; /**< Status and Control Register 3, offset: 0x24 */
ccoleman 0:2010bcffbae0 274 uint32_t OFS; /**< ADC Offset Correction Register, offset: 0x28 */
ccoleman 0:2010bcffbae0 275 uint32_t PG; /**< ADC Plus-Side Gain Register, offset: 0x2C */
ccoleman 0:2010bcffbae0 276 uint32_t MG; /**< ADC Minus-Side Gain Register, offset: 0x30 */
ccoleman 0:2010bcffbae0 277 uint32_t CLPD; /**< ADC Plus-Side General Calibration Value Register, offset: 0x34 */
ccoleman 0:2010bcffbae0 278 uint32_t CLPS; /**< ADC Plus-Side General Calibration Value Register, offset: 0x38 */
ccoleman 0:2010bcffbae0 279 uint32_t CLP4; /**< ADC Plus-Side General Calibration Value Register, offset: 0x3C */
ccoleman 0:2010bcffbae0 280 uint32_t CLP3; /**< ADC Plus-Side General Calibration Value Register, offset: 0x40 */
ccoleman 0:2010bcffbae0 281 uint32_t CLP2; /**< ADC Plus-Side General Calibration Value Register, offset: 0x44 */
ccoleman 0:2010bcffbae0 282 uint32_t CLP1; /**< ADC Plus-Side General Calibration Value Register, offset: 0x48 */
ccoleman 0:2010bcffbae0 283 uint32_t CLP0; /**< ADC Plus-Side General Calibration Value Register, offset: 0x4C */
ccoleman 0:2010bcffbae0 284 uint8_t RESERVED_0[4];
ccoleman 0:2010bcffbae0 285 uint32_t CLMD; /**< ADC Minus-Side General Calibration Value Register, offset: 0x54 */
ccoleman 0:2010bcffbae0 286 uint32_t CLMS; /**< ADC Minus-Side General Calibration Value Register, offset: 0x58 */
ccoleman 0:2010bcffbae0 287 uint32_t CLM4; /**< ADC Minus-Side General Calibration Value Register, offset: 0x5C */
ccoleman 0:2010bcffbae0 288 uint32_t CLM3; /**< ADC Minus-Side General Calibration Value Register, offset: 0x60 */
ccoleman 0:2010bcffbae0 289 uint32_t CLM2; /**< ADC Minus-Side General Calibration Value Register, offset: 0x64 */
ccoleman 0:2010bcffbae0 290 uint32_t CLM1; /**< ADC Minus-Side General Calibration Value Register, offset: 0x68 */
ccoleman 0:2010bcffbae0 291 uint32_t CLM0; /**< ADC Minus-Side General Calibration Value Register, offset: 0x6C */
ccoleman 0:2010bcffbae0 292 } volatile *ADC_MemMapPtr;
ccoleman 0:2010bcffbae0 293
ccoleman 0:2010bcffbae0 294
ccoleman 0:2010bcffbae0 295
ccoleman 0:2010bcffbae0 296 /* ADC - Register accessors */
ccoleman 0:2010bcffbae0 297 #define ADC_SC1_REG(base,index) ((base)->SC1[index])
ccoleman 0:2010bcffbae0 298 #define ADC_CFG1_REG(base) ((base)->CFG1)
ccoleman 0:2010bcffbae0 299 #define ADC_CFG2_REG(base) ((base)->CFG2)
ccoleman 0:2010bcffbae0 300 #define ADC_R_REG(base,index) ((base)->R[index])
ccoleman 0:2010bcffbae0 301 #define ADC_CV1_REG(base) ((base)->CV1)
ccoleman 0:2010bcffbae0 302 #define ADC_CV2_REG(base) ((base)->CV2)
ccoleman 0:2010bcffbae0 303 #define ADC_SC2_REG(base) ((base)->SC2)
ccoleman 0:2010bcffbae0 304 #define ADC_SC3_REG(base) ((base)->SC3)
ccoleman 0:2010bcffbae0 305 #define ADC_OFS_REG(base) ((base)->OFS)
ccoleman 0:2010bcffbae0 306 #define ADC_PG_REG(base) ((base)->PG)
ccoleman 0:2010bcffbae0 307 #define ADC_MG_REG(base) ((base)->MG)
ccoleman 0:2010bcffbae0 308 #define ADC_CLPD_REG(base) ((base)->CLPD)
ccoleman 0:2010bcffbae0 309 #define ADC_CLPS_REG(base) ((base)->CLPS)
ccoleman 0:2010bcffbae0 310 #define ADC_CLP4_REG(base) ((base)->CLP4)
ccoleman 0:2010bcffbae0 311 #define ADC_CLP3_REG(base) ((base)->CLP3)
ccoleman 0:2010bcffbae0 312 #define ADC_CLP2_REG(base) ((base)->CLP2)
ccoleman 0:2010bcffbae0 313 #define ADC_CLP1_REG(base) ((base)->CLP1)
ccoleman 0:2010bcffbae0 314 #define ADC_CLP0_REG(base) ((base)->CLP0)
ccoleman 0:2010bcffbae0 315 #define ADC_CLMD_REG(base) ((base)->CLMD)
ccoleman 0:2010bcffbae0 316 #define ADC_CLMS_REG(base) ((base)->CLMS)
ccoleman 0:2010bcffbae0 317 #define ADC_CLM4_REG(base) ((base)->CLM4)
ccoleman 0:2010bcffbae0 318 #define ADC_CLM3_REG(base) ((base)->CLM3)
ccoleman 0:2010bcffbae0 319 #define ADC_CLM2_REG(base) ((base)->CLM2)
ccoleman 0:2010bcffbae0 320 #define ADC_CLM1_REG(base) ((base)->CLM1)
ccoleman 0:2010bcffbae0 321 #define ADC_CLM0_REG(base) ((base)->CLM0)
ccoleman 0:2010bcffbae0 322
ccoleman 0:2010bcffbae0 323 #define ADC0_BASE_PTR ((ADC_MemMapPtr)0x4003B000u)
ccoleman 0:2010bcffbae0 324 /** Array initializer of ADC peripheral base pointers */
ccoleman 0:2010bcffbae0 325 #define ADC_BASE_PTRS { ADC0_BASE_PTR }
ccoleman 0:2010bcffbae0 326
ccoleman 0:2010bcffbae0 327
ccoleman 0:2010bcffbae0 328 float _ServoDutyCycleMin;
ccoleman 0:2010bcffbae0 329 float _ServoDutyCycleMax;
ccoleman 0:2010bcffbae0 330 float _ServoPeriod;
ccoleman 0:2010bcffbae0 331
ccoleman 0:2010bcffbae0 332 volatile uint16_t QueuedServo0Val;
ccoleman 0:2010bcffbae0 333 volatile uint16_t QueuedServo1Val;
ccoleman 0:2010bcffbae0 334
ccoleman 0:2010bcffbae0 335 volatile uint8_t TFC_LineScanDataReady;
ccoleman 0:2010bcffbae0 336 volatile uint8_t *LineScanImage0WorkingBuffer;
ccoleman 0:2010bcffbae0 337 volatile uint8_t *LineScanImage1WorkingBuffer;
ccoleman 0:2010bcffbae0 338
ccoleman 0:2010bcffbae0 339 volatile uint8_t LineScanImage0Buffer[2][128];
ccoleman 0:2010bcffbae0 340 volatile uint8_t LineScanImage1Buffer[2][128];
ccoleman 0:2010bcffbae0 341 volatile uint8_t LineScanWorkingBuffer;
ccoleman 0:2010bcffbae0 342
ccoleman 0:2010bcffbae0 343 volatile uint8_t PotADC_Value[2];
ccoleman 0:2010bcffbae0 344 volatile uint8_t BatSenseADC_Value;
ccoleman 0:2010bcffbae0 345 volatile uint8_t CurrentADC_State;
ccoleman 0:2010bcffbae0 346 volatile uint8_t CurrentLineScanPixel;
ccoleman 0:2010bcffbae0 347 volatile uint8_t CurrentLineScanChannel;
ccoleman 0:2010bcffbae0 348 volatile uint32_t TFC_ServoTicker;
ccoleman 0:2010bcffbae0 349 volatile uint8_t * TFC_LineScanCameraData[2];
ccoleman 0:2010bcffbae0 350
ccoleman 0:2010bcffbae0 351 void TFC_SetServoDutyCycle(uint8_t ServoNumber, float DutyCycle);
ccoleman 0:2010bcffbae0 352 void TFC_InitLineScanCamera();
ccoleman 0:2010bcffbae0 353 uint8_t ADC_Cal(ADC_MemMapPtr adcmap);
ccoleman 0:2010bcffbae0 354 void ADC_Config_Alt(ADC_MemMapPtr adcmap, tADC_ConfigPtr ADC_CfgPtr);
ccoleman 0:2010bcffbae0 355 void ADC_Read_Cal(ADC_MemMapPtr adcmap, tADC_Cal_Blk *blk);
ccoleman 0:2010bcffbae0 356 void TFC_InitADC0();
ccoleman 0:2010bcffbae0 357 void TFC_InitADC_System();
ccoleman 0:2010bcffbae0 358 void TFC_GPIO_Init();
ccoleman 0:2010bcffbae0 359 void ADC0_Handler();
ccoleman 0:2010bcffbae0 360 void TPM1_Handler();
ccoleman 0:2010bcffbae0 361
ccoleman 0:2010bcffbae0 362
ccoleman 0:2010bcffbae0 363 void TFC_Init()
ccoleman 0:2010bcffbae0 364 {
ccoleman 0:2010bcffbae0 365
ccoleman 0:2010bcffbae0 366 TFC_GPIO_Init();
ccoleman 0:2010bcffbae0 367
ccoleman 0:2010bcffbae0 368 TFC_InitADC_System(); // Always call this before the Servo init function.... The IRQ for the Servo code modifies ADC registers and the clocks need enable to the ADC peripherals 1st!
ccoleman 0:2010bcffbae0 369
ccoleman 0:2010bcffbae0 370 TFC_InitLineScanCamera();
ccoleman 0:2010bcffbae0 371
ccoleman 0:2010bcffbae0 372 TFC_InitServos(SERVO_MIN_PULSE_WIDTH_DEFAULT , SERVO_MAX_PULSE_WIDTH_DEFAULT, SERVO_DEFAULT_PERIOD);
ccoleman 4:4233d072b5af 373
ccoleman 0:2010bcffbae0 374 TFC_ServoTicker = 0;
ccoleman 0:2010bcffbae0 375
ccoleman 0:2010bcffbae0 376 TFC_InitMotorPWM(FTM0_DEFAULT_SWITCHING_FREQUENCY);
ccoleman 0:2010bcffbae0 377
ccoleman 0:2010bcffbae0 378 }
ccoleman 0:2010bcffbae0 379
ccoleman 0:2010bcffbae0 380
ccoleman 0:2010bcffbae0 381 void TFC_GPIO_Init()
ccoleman 0:2010bcffbae0 382 {
ccoleman 0:2010bcffbae0 383
ccoleman 0:2010bcffbae0 384 //enable Clocks to all ports
ccoleman 0:2010bcffbae0 385
ccoleman 0:2010bcffbae0 386 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
ccoleman 0:2010bcffbae0 387
ccoleman 0:2010bcffbae0 388 //Setup Pins as GPIO
ccoleman 0:2010bcffbae0 389 PORTE->PCR[21] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
ccoleman 0:2010bcffbae0 390 PORTE->PCR[20] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 391
ccoleman 0:2010bcffbae0 392 //Port for Pushbuttons
ccoleman 0:2010bcffbae0 393 PORTC->PCR[13] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 394 PORTC->PCR[17] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 395
ccoleman 0:2010bcffbae0 396
ccoleman 0:2010bcffbae0 397 //Ports for DIP Switches
ccoleman 0:2010bcffbae0 398 PORTE->PCR[2] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 399 PORTE->PCR[3] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 400 PORTE->PCR[4] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 401 PORTE->PCR[5] = PORT_PCR_MUX(1);
ccoleman 0:2010bcffbae0 402
ccoleman 0:2010bcffbae0 403 //Ports for LEDs
ccoleman 0:2010bcffbae0 404 PORTB->PCR[8] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
ccoleman 0:2010bcffbae0 405 PORTB->PCR[9] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
ccoleman 0:2010bcffbae0 406 PORTB->PCR[10] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
ccoleman 0:2010bcffbae0 407 PORTB->PCR[11] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
ccoleman 0:2010bcffbae0 408
ccoleman 0:2010bcffbae0 409
ccoleman 0:2010bcffbae0 410 //Setup the output pins
ccoleman 0:2010bcffbae0 411 PTE->PDDR = TFC_HBRIDGE_EN_LOC;
ccoleman 0:2010bcffbae0 412 PTB->PDDR = TFC_BAT_LED0_LOC | TFC_BAT_LED1_LOC | TFC_BAT_LED2_LOC | TFC_BAT_LED3_LOC;
ccoleman 0:2010bcffbae0 413
ccoleman 0:2010bcffbae0 414 TFC_SetBatteryLED(0);
ccoleman 0:2010bcffbae0 415 TFC_HBRIDGE_DISABLE;
ccoleman 0:2010bcffbae0 416 }
ccoleman 0:2010bcffbae0 417
ccoleman 0:2010bcffbae0 418 void TFC_SetBatteryLED(uint8_t Value)
ccoleman 0:2010bcffbae0 419 {
ccoleman 0:2010bcffbae0 420 if(Value & 0x01)
ccoleman 0:2010bcffbae0 421 TFC_BAT_LED0_ON;
ccoleman 0:2010bcffbae0 422 else
ccoleman 0:2010bcffbae0 423 TFC_BAT_LED0_OFF;
ccoleman 0:2010bcffbae0 424
ccoleman 0:2010bcffbae0 425 if(Value & 0x02)
ccoleman 0:2010bcffbae0 426 TFC_BAT_LED1_ON;
ccoleman 0:2010bcffbae0 427 else
ccoleman 0:2010bcffbae0 428 TFC_BAT_LED1_OFF;
ccoleman 0:2010bcffbae0 429
ccoleman 0:2010bcffbae0 430 if(Value & 0x04)
ccoleman 0:2010bcffbae0 431 TFC_BAT_LED2_ON;
ccoleman 0:2010bcffbae0 432 else
ccoleman 0:2010bcffbae0 433 TFC_BAT_LED2_OFF;
ccoleman 0:2010bcffbae0 434
ccoleman 0:2010bcffbae0 435 if(Value & 0x08)
ccoleman 0:2010bcffbae0 436 TFC_BAT_LED3_ON;
ccoleman 0:2010bcffbae0 437 else
ccoleman 0:2010bcffbae0 438 TFC_BAT_LED3_OFF;
ccoleman 0:2010bcffbae0 439 }
ccoleman 0:2010bcffbae0 440
ccoleman 0:2010bcffbae0 441 uint8_t TFC_GetDIP_Switch()
ccoleman 0:2010bcffbae0 442 {
ccoleman 0:2010bcffbae0 443 uint8_t DIP_Val=0;
ccoleman 0:2010bcffbae0 444
ccoleman 0:2010bcffbae0 445 DIP_Val = (PTE->PDIR>>2) & 0xF;
ccoleman 0:2010bcffbae0 446
ccoleman 0:2010bcffbae0 447 return DIP_Val;
ccoleman 0:2010bcffbae0 448 }
ccoleman 0:2010bcffbae0 449
ccoleman 0:2010bcffbae0 450 uint8_t TFC_ReadPushButton(uint8_t Index)
ccoleman 0:2010bcffbae0 451 {
ccoleman 0:2010bcffbae0 452 if(Index == 0) {
ccoleman 0:2010bcffbae0 453 return TFC_PUSH_BUTTON_0_PRESSED;
ccoleman 0:2010bcffbae0 454 } else {
ccoleman 0:2010bcffbae0 455 return TFC_PUSH_BUTTON_1_PRESSED;
ccoleman 0:2010bcffbae0 456 }
ccoleman 0:2010bcffbae0 457 }
ccoleman 0:2010bcffbae0 458
ccoleman 0:2010bcffbae0 459 extern "C" void TPM1_IRQHandler()
ccoleman 0:2010bcffbae0 460 {
ccoleman 0:2010bcffbae0 461 //Clear the overflow mask if set. According to the reference manual, we clear by writing a logic one!
ccoleman 0:2010bcffbae0 462 if(TPM1->SC & TPM_SC_TOF_MASK)
ccoleman 0:2010bcffbae0 463 TPM1->SC |= TPM_SC_TOF_MASK;
ccoleman 0:2010bcffbae0 464
ccoleman 0:2010bcffbae0 465 //Dump the queued values to the timer channels
ccoleman 0:2010bcffbae0 466 TPM1->CONTROLS[0].CnV = QueuedServo0Val;
ccoleman 0:2010bcffbae0 467 TPM1->CONTROLS[1].CnV = QueuedServo1Val;
ccoleman 0:2010bcffbae0 468
ccoleman 0:2010bcffbae0 469
ccoleman 0:2010bcffbae0 470 //Prime the next ADC capture cycle
ccoleman 0:2010bcffbae0 471 TAOS_SI_HIGH;
ccoleman 0:2010bcffbae0 472 //Prime the ADC pump and start capturing POT 0
ccoleman 0:2010bcffbae0 473 CurrentADC_State = ADC_STATE_CAPTURE_POT_0;
ccoleman 0:2010bcffbae0 474
ccoleman 0:2010bcffbae0 475 ADC0->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; //Select the A side of the mux
ccoleman 0:2010bcffbae0 476 ADC0->SC1[0] = TFC_POT_0_ADC_CHANNEL | ADC_SC1_AIEN_MASK; //Start the State machine at POT0
ccoleman 0:2010bcffbae0 477
ccoleman 0:2010bcffbae0 478 //Flag that a new cervo cycle will start
ccoleman 0:2010bcffbae0 479 if (TFC_ServoTicker < 0xffffffff)//if servo tick less than max value, count up...
ccoleman 0:2010bcffbae0 480 TFC_ServoTicker++;
ccoleman 0:2010bcffbae0 481
ccoleman 0:2010bcffbae0 482 }
ccoleman 0:2010bcffbae0 483
ccoleman 0:2010bcffbae0 484
ccoleman 0:2010bcffbae0 485 void TFC_InitServos(float PulseWidthMin, float PulseWidthMax, float ServoPeriod)
ccoleman 0:2010bcffbae0 486 {
ccoleman 0:2010bcffbae0 487
ccoleman 0:2010bcffbae0 488 _ServoPeriod = ServoPeriod;
ccoleman 0:2010bcffbae0 489 _ServoDutyCycleMin = PulseWidthMin/ServoPeriod;
ccoleman 0:2010bcffbae0 490 _ServoDutyCycleMax = PulseWidthMax/ServoPeriod;
ccoleman 0:2010bcffbae0 491
ccoleman 0:2010bcffbae0 492 //Clock Setup for the TPM requires a couple steps.
ccoleman 0:2010bcffbae0 493 SIM->SCGC6 &= ~SIM_SCGC6_TPM1_MASK;
ccoleman 0:2010bcffbae0 494 //1st, set the clock mux
ccoleman 0:2010bcffbae0 495 //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
ccoleman 0:2010bcffbae0 496 SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
ccoleman 0:2010bcffbae0 497 SIM->SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
ccoleman 0:2010bcffbae0 498 SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1);
ccoleman 0:2010bcffbae0 499
ccoleman 0:2010bcffbae0 500 //Enable the Clock to the FTM0 Module
ccoleman 0:2010bcffbae0 501 //See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
ccoleman 0:2010bcffbae0 502 SIM->SCGC6 |= SIM_SCGC6_TPM1_MASK;
ccoleman 0:2010bcffbae0 503
ccoleman 0:2010bcffbae0 504 //The TPM Module has Clock. Now set up the peripheral
ccoleman 0:2010bcffbae0 505
ccoleman 0:2010bcffbae0 506 //Blow away the control registers to ensure that the counter is not running
ccoleman 0:2010bcffbae0 507 TPM1->SC = 0;
ccoleman 0:2010bcffbae0 508 TPM1->CONF = 0;
ccoleman 0:2010bcffbae0 509
ccoleman 0:2010bcffbae0 510 //While the counter is disabled we can setup the prescaler
ccoleman 0:2010bcffbae0 511
ccoleman 0:2010bcffbae0 512 TPM1->SC = TPM_SC_PS(FTM1_CLK_PRESCALE);
ccoleman 0:2010bcffbae0 513 TPM1->SC |= TPM_SC_TOIE_MASK; //Enable Interrupts for the Timer Overflow
ccoleman 0:2010bcffbae0 514
ccoleman 0:2010bcffbae0 515 //Setup the mod register to get the correct PWM Period
ccoleman 0:2010bcffbae0 516
ccoleman 0:2010bcffbae0 517 TPM1->MOD = (SystemCoreClock/(1<<(FTM1_CLK_PRESCALE))) * _ServoPeriod;
ccoleman 0:2010bcffbae0 518 //Setup Channels 0 and 1
ccoleman 0:2010bcffbae0 519
ccoleman 0:2010bcffbae0 520 TPM1->CONTROLS[0].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
ccoleman 0:2010bcffbae0 521 TPM1->CONTROLS[1].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
ccoleman 0:2010bcffbae0 522
ccoleman 0:2010bcffbae0 523
ccoleman 0:2010bcffbae0 524 //Set the Default duty cycle to servo neutral
ccoleman 0:2010bcffbae0 525 TFC_SetServo(0, 0.0);
ccoleman 0:2010bcffbae0 526 TFC_SetServo(1, 0.0);
ccoleman 0:2010bcffbae0 527
ccoleman 0:2010bcffbae0 528 //Enable the TPM COunter
ccoleman 0:2010bcffbae0 529 TPM1->SC |= TPM_SC_CMOD(1);
ccoleman 0:2010bcffbae0 530
ccoleman 0:2010bcffbae0 531 //Enable TPM1 IRQ on the NVIC
ccoleman 0:2010bcffbae0 532
ccoleman 0:2010bcffbae0 533 //NVIC_SetVector(TPM1_IRQn,(uint32_t)TPM1_Handler);
ccoleman 0:2010bcffbae0 534 NVIC_EnableIRQ(TPM1_IRQn);
ccoleman 0:2010bcffbae0 535
ccoleman 0:2010bcffbae0 536 //Enable the FTM functions on the the port
ccoleman 0:2010bcffbae0 537
ccoleman 0:2010bcffbae0 538 PORTB->PCR[0] = PORT_PCR_MUX(3);
ccoleman 0:2010bcffbae0 539 PORTB->PCR[1] = PORT_PCR_MUX(3);
ccoleman 0:2010bcffbae0 540
ccoleman 0:2010bcffbae0 541 }
ccoleman 0:2010bcffbae0 542
ccoleman 0:2010bcffbae0 543
ccoleman 0:2010bcffbae0 544 void TFC_SetServoDutyCycle(uint8_t ServoNumber, float DutyCycle)
ccoleman 0:2010bcffbae0 545 {
ccoleman 0:2010bcffbae0 546 switch(ServoNumber) {
ccoleman 0:2010bcffbae0 547 default:
ccoleman 0:2010bcffbae0 548 case 0:
ccoleman 0:2010bcffbae0 549
ccoleman 0:2010bcffbae0 550 QueuedServo0Val = TPM1->MOD * DutyCycle;
ccoleman 0:2010bcffbae0 551
ccoleman 0:2010bcffbae0 552 break;
ccoleman 0:2010bcffbae0 553
ccoleman 0:2010bcffbae0 554 case 1:
ccoleman 0:2010bcffbae0 555
ccoleman 0:2010bcffbae0 556 QueuedServo1Val = TPM1->MOD * DutyCycle;
ccoleman 0:2010bcffbae0 557
ccoleman 0:2010bcffbae0 558 break;
ccoleman 0:2010bcffbae0 559 }
ccoleman 0:2010bcffbae0 560 }
ccoleman 0:2010bcffbae0 561
ccoleman 0:2010bcffbae0 562 void TFC_SetServo(uint8_t ServoNumber, float Position)
ccoleman 0:2010bcffbae0 563 {
ccoleman 0:2010bcffbae0 564 TFC_SetServoDutyCycle(ServoNumber ,
ccoleman 0:2010bcffbae0 565 ((Position + 1.0)/2) * ((_ServoDutyCycleMax - _ServoDutyCycleMin)+_ServoDutyCycleMin) );
ccoleman 0:2010bcffbae0 566
ccoleman 0:2010bcffbae0 567 }
ccoleman 0:2010bcffbae0 568
ccoleman 0:2010bcffbae0 569 //********************************************************************************************************
ccoleman 0:2010bcffbae0 570 //********************************************************************************************************
ccoleman 0:2010bcffbae0 571 //********************************************************************************************************
ccoleman 0:2010bcffbae0 572 // _____ _____ ______ _ _ _ _ _____ _______ _____ ____ _ _ _____
ccoleman 0:2010bcffbae0 573 // /\ | __ \ / ____| | ____| | | | \ | |/ ____|__ __|_ _/ __ \| \ | |/ ____|
ccoleman 0:2010bcffbae0 574 // / \ | | | | | | |__ | | | | \| | | | | | || | | | \| | (___
ccoleman 0:2010bcffbae0 575 // / /\ \ | | | | | | __| | | | | . ` | | | | | || | | | . ` |\___ \
ccoleman 0:2010bcffbae0 576 // / ____ \| |__| | |____ | | | |__| | |\ | |____ | | _| || |__| | |\ |____) |
ccoleman 0:2010bcffbae0 577 // /_/ \_\_____/ \_____| |_| \____/|_| \_|\_____| |_| |_____\____/|_| \_|_____/
ccoleman 0:2010bcffbae0 578 // ********************************************************************************************************
ccoleman 0:2010bcffbae0 579 // ********************************************************************************************************
ccoleman 0:2010bcffbae0 580 // ********************************************************************************************************
ccoleman 0:2010bcffbae0 581
ccoleman 0:2010bcffbae0 582
ccoleman 0:2010bcffbae0 583
ccoleman 0:2010bcffbae0 584
ccoleman 0:2010bcffbae0 585
ccoleman 0:2010bcffbae0 586 uint8_t ADC_Cal(ADC_MemMapPtr adcmap)
ccoleman 0:2010bcffbae0 587 {
ccoleman 0:2010bcffbae0 588
ccoleman 0:2010bcffbae0 589 uint16_t cal_var;
ccoleman 0:2010bcffbae0 590
ccoleman 0:2010bcffbae0 591 ADC_SC2_REG(adcmap) &= ~ADC_SC2_ADTRG_MASK ; // Enable Software Conversion Trigger for Calibration Process - ADC0_SC2 = ADC0_SC2 | ADC_SC2_ADTRGW(0);
ccoleman 0:2010bcffbae0 592 ADC_SC3_REG(adcmap) &= ( ~ADC_SC3_ADCO_MASK & ~ADC_SC3_AVGS_MASK ); // set single conversion, clear avgs bitfield for next writing
ccoleman 0:2010bcffbae0 593 ADC_SC3_REG(adcmap) |= ( ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(AVGS_32) ); // Turn averaging ON and set at max value ( 32 )
ccoleman 0:2010bcffbae0 594
ccoleman 0:2010bcffbae0 595
ccoleman 0:2010bcffbae0 596 ADC_SC3_REG(adcmap) |= ADC_SC3_CAL_MASK ; // Start CAL
ccoleman 0:2010bcffbae0 597 while ( (ADC_SC1_REG(adcmap,A) & ADC_SC1_COCO_MASK ) == COCO_NOT ); // Wait calibration end
ccoleman 0:2010bcffbae0 598
ccoleman 0:2010bcffbae0 599 if ((ADC_SC3_REG(adcmap)& ADC_SC3_CALF_MASK) == CALF_FAIL ) {
ccoleman 0:2010bcffbae0 600 return(1); // Check for Calibration fail error and return
ccoleman 0:2010bcffbae0 601 }
ccoleman 0:2010bcffbae0 602 // Calculate plus-side calibration
ccoleman 0:2010bcffbae0 603 cal_var = 0x00;
ccoleman 0:2010bcffbae0 604
ccoleman 0:2010bcffbae0 605 cal_var = ADC_CLP0_REG(adcmap);
ccoleman 0:2010bcffbae0 606 cal_var += ADC_CLP1_REG(adcmap);
ccoleman 0:2010bcffbae0 607 cal_var += ADC_CLP2_REG(adcmap);
ccoleman 0:2010bcffbae0 608 cal_var += ADC_CLP3_REG(adcmap);
ccoleman 0:2010bcffbae0 609 cal_var += ADC_CLP4_REG(adcmap);
ccoleman 0:2010bcffbae0 610 cal_var += ADC_CLPS_REG(adcmap);
ccoleman 0:2010bcffbae0 611
ccoleman 0:2010bcffbae0 612 cal_var = cal_var/2;
ccoleman 0:2010bcffbae0 613 cal_var |= 0x8000; // Set MSB
ccoleman 0:2010bcffbae0 614
ccoleman 0:2010bcffbae0 615 ADC_PG_REG(adcmap) = ADC_PG_PG(cal_var);
ccoleman 0:2010bcffbae0 616
ccoleman 0:2010bcffbae0 617
ccoleman 0:2010bcffbae0 618 // Calculate minus-side calibration
ccoleman 0:2010bcffbae0 619 cal_var = 0x00;
ccoleman 0:2010bcffbae0 620
ccoleman 0:2010bcffbae0 621 cal_var = ADC_CLM0_REG(adcmap);
ccoleman 0:2010bcffbae0 622 cal_var += ADC_CLM1_REG(adcmap);
ccoleman 0:2010bcffbae0 623 cal_var += ADC_CLM2_REG(adcmap);
ccoleman 0:2010bcffbae0 624 cal_var += ADC_CLM3_REG(adcmap);
ccoleman 0:2010bcffbae0 625 cal_var += ADC_CLM4_REG(adcmap);
ccoleman 0:2010bcffbae0 626 cal_var += ADC_CLMS_REG(adcmap);
ccoleman 0:2010bcffbae0 627
ccoleman 0:2010bcffbae0 628 cal_var = cal_var/2;
ccoleman 0:2010bcffbae0 629
ccoleman 0:2010bcffbae0 630 cal_var |= 0x8000; // Set MSB
ccoleman 0:2010bcffbae0 631
ccoleman 0:2010bcffbae0 632 ADC_MG_REG(adcmap) = ADC_MG_MG(cal_var);
ccoleman 0:2010bcffbae0 633
ccoleman 0:2010bcffbae0 634 ADC_SC3_REG(adcmap) &= ~ADC_SC3_CAL_MASK ; /* Clear CAL bit */
ccoleman 0:2010bcffbae0 635
ccoleman 0:2010bcffbae0 636 return(0);
ccoleman 0:2010bcffbae0 637 }
ccoleman 0:2010bcffbae0 638
ccoleman 0:2010bcffbae0 639
ccoleman 0:2010bcffbae0 640 void ADC_Config_Alt(ADC_MemMapPtr adcmap, tADC_ConfigPtr ADC_CfgPtr)
ccoleman 0:2010bcffbae0 641 {
ccoleman 0:2010bcffbae0 642 ADC_CFG1_REG(adcmap) = ADC_CfgPtr->CONFIG1;
ccoleman 0:2010bcffbae0 643 ADC_CFG2_REG(adcmap) = ADC_CfgPtr->CONFIG2;
ccoleman 0:2010bcffbae0 644 ADC_CV1_REG(adcmap) = ADC_CfgPtr->COMPARE1;
ccoleman 0:2010bcffbae0 645 ADC_CV2_REG(adcmap) = ADC_CfgPtr->COMPARE2;
ccoleman 0:2010bcffbae0 646 ADC_SC2_REG(adcmap) = ADC_CfgPtr->STATUS2;
ccoleman 0:2010bcffbae0 647 ADC_SC3_REG(adcmap) = ADC_CfgPtr->STATUS3;
ccoleman 0:2010bcffbae0 648 //ADC_PGA_REG(adcmap) = ADC_CfgPtr->PGA;
ccoleman 0:2010bcffbae0 649 ADC_SC1_REG(adcmap,A)= ADC_CfgPtr->STATUS1A;
ccoleman 0:2010bcffbae0 650 ADC_SC1_REG(adcmap,B)= ADC_CfgPtr->STATUS1B;
ccoleman 0:2010bcffbae0 651 }
ccoleman 0:2010bcffbae0 652
ccoleman 0:2010bcffbae0 653
ccoleman 0:2010bcffbae0 654 void ADC_Read_Cal(ADC_MemMapPtr adcmap, tADC_Cal_Blk *blk)
ccoleman 0:2010bcffbae0 655 {
ccoleman 0:2010bcffbae0 656 blk->OFS = ADC_OFS_REG(adcmap);
ccoleman 0:2010bcffbae0 657 blk->PG = ADC_PG_REG(adcmap);
ccoleman 0:2010bcffbae0 658 blk->MG = ADC_MG_REG(adcmap);
ccoleman 0:2010bcffbae0 659 blk->CLPD = ADC_CLPD_REG(adcmap);
ccoleman 0:2010bcffbae0 660 blk->CLPS = ADC_CLPS_REG(adcmap);
ccoleman 0:2010bcffbae0 661 blk->CLP4 = ADC_CLP4_REG(adcmap);
ccoleman 0:2010bcffbae0 662 blk->CLP3 = ADC_CLP3_REG(adcmap);
ccoleman 0:2010bcffbae0 663 blk->CLP2 = ADC_CLP2_REG(adcmap);
ccoleman 0:2010bcffbae0 664 blk->CLP1 = ADC_CLP1_REG(adcmap);
ccoleman 0:2010bcffbae0 665 blk->CLP0 = ADC_CLP0_REG(adcmap);
ccoleman 0:2010bcffbae0 666 blk->CLMD = ADC_CLMD_REG(adcmap);
ccoleman 0:2010bcffbae0 667 blk->CLMS = ADC_CLMS_REG(adcmap);
ccoleman 0:2010bcffbae0 668 blk->CLM4 = ADC_CLM4_REG(adcmap);
ccoleman 0:2010bcffbae0 669 blk->CLM3 = ADC_CLM3_REG(adcmap);
ccoleman 0:2010bcffbae0 670 blk->CLM2 = ADC_CLM2_REG(adcmap);
ccoleman 0:2010bcffbae0 671 blk->CLM1 = ADC_CLM1_REG(adcmap);
ccoleman 0:2010bcffbae0 672 blk->CLM0 = ADC_CLM0_REG(adcmap);
ccoleman 0:2010bcffbae0 673
ccoleman 0:2010bcffbae0 674 }
ccoleman 0:2010bcffbae0 675
ccoleman 0:2010bcffbae0 676
ccoleman 0:2010bcffbae0 677 void TFC_InitADC0()
ccoleman 0:2010bcffbae0 678 {
ccoleman 0:2010bcffbae0 679 tADC_Config Master_Adc0_Config;
ccoleman 0:2010bcffbae0 680
ccoleman 0:2010bcffbae0 681
ccoleman 0:2010bcffbae0 682 SIM->SCGC6 |= (SIM_SCGC6_ADC0_MASK);
ccoleman 0:2010bcffbae0 683
ccoleman 0:2010bcffbae0 684 //Lets calibrate the ADC. 1st setup how the channel will be used.
ccoleman 0:2010bcffbae0 685
ccoleman 0:2010bcffbae0 686
ccoleman 0:2010bcffbae0 687 Master_Adc0_Config.CONFIG1 = ADLPC_NORMAL //No low power mode
ccoleman 0:2010bcffbae0 688 | ADC_CFG1_ADIV(ADIV_4) //divide input by 4
ccoleman 0:2010bcffbae0 689 | ADLSMP_LONG //long sample time
ccoleman 0:2010bcffbae0 690 | ADC_CFG1_MODE(MODE_8)//single ended 8-bit conversion
ccoleman 0:2010bcffbae0 691 | ADC_CFG1_ADICLK(ADICLK_BUS);
ccoleman 0:2010bcffbae0 692
ccoleman 0:2010bcffbae0 693 Master_Adc0_Config.CONFIG2 = MUXSEL_ADCA // select the A side of the ADC channel.
ccoleman 0:2010bcffbae0 694 | ADACKEN_DISABLED
ccoleman 0:2010bcffbae0 695 | ADHSC_HISPEED
ccoleman 0:2010bcffbae0 696 | ADC_CFG2_ADLSTS(ADLSTS_2);//Extra long sample Time (20 extra clocks)
ccoleman 0:2010bcffbae0 697
ccoleman 0:2010bcffbae0 698
ccoleman 0:2010bcffbae0 699 Master_Adc0_Config.COMPARE1 = 00000; // Comparators don't matter for calibration
ccoleman 0:2010bcffbae0 700 Master_Adc0_Config.COMPARE1 = 0xFFFF;
ccoleman 0:2010bcffbae0 701
ccoleman 0:2010bcffbae0 702 Master_Adc0_Config.STATUS2 = ADTRG_HW //hardware triggers for calibration
ccoleman 0:2010bcffbae0 703 | ACFE_DISABLED //disable comparator
ccoleman 0:2010bcffbae0 704 | ACFGT_GREATER
ccoleman 0:2010bcffbae0 705 | ACREN_ENABLED
ccoleman 0:2010bcffbae0 706 | DMAEN_DISABLED //Disable DMA
ccoleman 0:2010bcffbae0 707 | ADC_SC2_REFSEL(REFSEL_EXT); //External Reference
ccoleman 0:2010bcffbae0 708
ccoleman 0:2010bcffbae0 709 Master_Adc0_Config.STATUS3 = CAL_OFF
ccoleman 0:2010bcffbae0 710 | ADCO_SINGLE
ccoleman 0:2010bcffbae0 711 | AVGE_ENABLED
ccoleman 0:2010bcffbae0 712 | ADC_SC3_AVGS(AVGS_4);
ccoleman 0:2010bcffbae0 713
ccoleman 0:2010bcffbae0 714 Master_Adc0_Config.PGA = 0; // Disable the PGA
ccoleman 0:2010bcffbae0 715
ccoleman 0:2010bcffbae0 716
ccoleman 0:2010bcffbae0 717 // Configure ADC as it will be used, but because ADC_SC1_ADCH is 31,
ccoleman 0:2010bcffbae0 718 // the ADC will be inactive. Channel 31 is just disable function.
ccoleman 0:2010bcffbae0 719 // There really is no channel 31.
ccoleman 0:2010bcffbae0 720
ccoleman 0:2010bcffbae0 721 Master_Adc0_Config.STATUS1A = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(31);
ccoleman 0:2010bcffbae0 722
ccoleman 0:2010bcffbae0 723
ccoleman 0:2010bcffbae0 724 ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc0_Config); // config ADC
ccoleman 0:2010bcffbae0 725
ccoleman 0:2010bcffbae0 726 // Calibrate the ADC in the configuration in which it will be used:
ccoleman 0:2010bcffbae0 727 ADC_Cal(ADC0_BASE_PTR); // do the calibration
ccoleman 0:2010bcffbae0 728
ccoleman 0:2010bcffbae0 729
ccoleman 0:2010bcffbae0 730 Master_Adc0_Config.STATUS2 = ACFE_DISABLED //disable comparator
ccoleman 0:2010bcffbae0 731 | ACFGT_GREATER
ccoleman 0:2010bcffbae0 732 | ACREN_ENABLED
ccoleman 0:2010bcffbae0 733 | DMAEN_DISABLED //Disable DMA
ccoleman 0:2010bcffbae0 734 | ADC_SC2_REFSEL(REFSEL_EXT); //External Reference
ccoleman 0:2010bcffbae0 735
ccoleman 0:2010bcffbae0 736 Master_Adc0_Config.STATUS3 = CAL_OFF
ccoleman 0:2010bcffbae0 737 | ADCO_SINGLE;
ccoleman 0:2010bcffbae0 738
ccoleman 0:2010bcffbae0 739
ccoleman 0:2010bcffbae0 740
ccoleman 0:2010bcffbae0 741 ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc0_Config);
ccoleman 0:2010bcffbae0 742 }
ccoleman 0:2010bcffbae0 743
ccoleman 0:2010bcffbae0 744
ccoleman 0:2010bcffbae0 745 void TFC_InitADC_System()
ccoleman 0:2010bcffbae0 746 {
ccoleman 0:2010bcffbae0 747
ccoleman 0:2010bcffbae0 748 TFC_InitADC0();
ccoleman 0:2010bcffbae0 749
ccoleman 0:2010bcffbae0 750
ccoleman 0:2010bcffbae0 751 //All Adc processing of the Pots and linescan will be done in the ADC0 IRQ!
ccoleman 0:2010bcffbae0 752 //A state machine will scan through the channels.
ccoleman 0:2010bcffbae0 753 //This is done to automate the linescan capture on Channel 0 to ensure that timing is very even
ccoleman 0:2010bcffbae0 754 CurrentADC_State = ADC_STATE_INIT;
ccoleman 0:2010bcffbae0 755
ccoleman 0:2010bcffbae0 756 //The pump will be primed with the TPM1 interrupt. upon timeout/interrupt it will set the SI signal high
ccoleman 0:2010bcffbae0 757 //for the camera and then start the conversions for the pots.
ccoleman 0:2010bcffbae0 758
ccoleman 4:4233d072b5af 759 // NVIC_SetVector(ADC0_IRQn,(uint32_t)ADC0_Handler);
ccoleman 0:2010bcffbae0 760 NVIC_EnableIRQ(ADC0_IRQn);
ccoleman 0:2010bcffbae0 761
ccoleman 0:2010bcffbae0 762 }
ccoleman 0:2010bcffbae0 763
ccoleman 0:2010bcffbae0 764 extern "C" void ADC0_IRQHandler()
ccoleman 0:2010bcffbae0 765 {
ccoleman 0:2010bcffbae0 766 uint8_t Junk;
ccoleman 0:2010bcffbae0 767
ccoleman 0:2010bcffbae0 768 switch(CurrentADC_State) {
ccoleman 0:2010bcffbae0 769 default:
ccoleman 0:2010bcffbae0 770 Junk = ADC0->R[0];
ccoleman 0:2010bcffbae0 771 break;
ccoleman 0:2010bcffbae0 772
ccoleman 0:2010bcffbae0 773 case ADC_STATE_CAPTURE_POT_0:
ccoleman 0:2010bcffbae0 774
ccoleman 0:2010bcffbae0 775 PotADC_Value[0] = ADC0->R[0];
ccoleman 0:2010bcffbae0 776 ADC0->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; //Select the A side of the mux
ccoleman 0:2010bcffbae0 777 ADC0->SC1[0] = TFC_POT_1_ADC_CHANNEL | ADC_SC1_AIEN_MASK;
ccoleman 0:2010bcffbae0 778 CurrentADC_State = ADC_STATE_CAPTURE_POT_1;
ccoleman 0:2010bcffbae0 779
ccoleman 0:2010bcffbae0 780 break;
ccoleman 0:2010bcffbae0 781
ccoleman 0:2010bcffbae0 782 case ADC_STATE_CAPTURE_POT_1:
ccoleman 0:2010bcffbae0 783
ccoleman 0:2010bcffbae0 784 PotADC_Value[1] = ADC0->R[0];
ccoleman 0:2010bcffbae0 785 ADC0->CFG2 |= ADC_CFG2_MUXSEL_MASK; //Select the B side of the mux
ccoleman 0:2010bcffbae0 786 ADC0->SC1[0] = TFC_BAT_SENSE_CHANNEL| ADC_SC1_AIEN_MASK;
ccoleman 0:2010bcffbae0 787 CurrentADC_State = ADC_STATE_CAPTURE_BATTERY_LEVEL;
ccoleman 0:2010bcffbae0 788
ccoleman 0:2010bcffbae0 789 break;
ccoleman 0:2010bcffbae0 790
ccoleman 0:2010bcffbae0 791 case ADC_STATE_CAPTURE_BATTERY_LEVEL:
ccoleman 0:2010bcffbae0 792
ccoleman 0:2010bcffbae0 793 BatSenseADC_Value = ADC0->R[0];
ccoleman 0:2010bcffbae0 794
ccoleman 0:2010bcffbae0 795 //Now we will start the sequence for the Linescan camera
ccoleman 0:2010bcffbae0 796
ccoleman 0:2010bcffbae0 797 TAOS_CLK_HIGH;
ccoleman 0:2010bcffbae0 798
ccoleman 0:2010bcffbae0 799 for(Junk = 0; Junk<50; Junk++) {
ccoleman 0:2010bcffbae0 800 }
ccoleman 0:2010bcffbae0 801
ccoleman 0:2010bcffbae0 802 TAOS_SI_LOW;
ccoleman 0:2010bcffbae0 803
ccoleman 0:2010bcffbae0 804
ccoleman 0:2010bcffbae0 805 CurrentLineScanPixel = 0;
ccoleman 0:2010bcffbae0 806 CurrentLineScanChannel = 0;
ccoleman 0:2010bcffbae0 807 CurrentADC_State = ADC_STATE_CAPTURE_LINE_SCAN;
ccoleman 0:2010bcffbae0 808 ADC0->CFG2 |= ADC_CFG2_MUXSEL_MASK; //Select the B side of the mux
ccoleman 0:2010bcffbae0 809 ADC0->SC1[0] = TFC_LINESCAN0_ADC_CHANNEL | ADC_SC1_AIEN_MASK;
ccoleman 0:2010bcffbae0 810
ccoleman 0:2010bcffbae0 811 break;
ccoleman 0:2010bcffbae0 812
ccoleman 0:2010bcffbae0 813 case ADC_STATE_CAPTURE_LINE_SCAN:
ccoleman 0:2010bcffbae0 814
ccoleman 0:2010bcffbae0 815 if(CurrentLineScanPixel<129) {
ccoleman 0:2010bcffbae0 816 if(CurrentLineScanChannel == 0) {
ccoleman 0:2010bcffbae0 817 LineScanImage0WorkingBuffer[CurrentLineScanPixel] = ADC0->R[0];
ccoleman 0:2010bcffbae0 818 ADC0->SC1[0] = TFC_LINESCAN1_ADC_CHANNEL | ADC_SC1_AIEN_MASK;
ccoleman 0:2010bcffbae0 819 CurrentLineScanChannel = 1;
ccoleman 0:2010bcffbae0 820
ccoleman 0:2010bcffbae0 821 } else {
ccoleman 0:2010bcffbae0 822 LineScanImage1WorkingBuffer[CurrentLineScanPixel] = ADC0->R[0];
ccoleman 0:2010bcffbae0 823 ADC0->SC1[0] = TFC_LINESCAN0_ADC_CHANNEL | ADC_SC1_AIEN_MASK;
ccoleman 0:2010bcffbae0 824 CurrentLineScanChannel = 0;
ccoleman 0:2010bcffbae0 825 CurrentLineScanPixel++;
ccoleman 0:2010bcffbae0 826
ccoleman 0:2010bcffbae0 827 TAOS_CLK_LOW;
ccoleman 0:2010bcffbae0 828 for(Junk = 0; Junk<50; Junk++) {
ccoleman 0:2010bcffbae0 829 }
ccoleman 0:2010bcffbae0 830 TAOS_CLK_HIGH;
ccoleman 0:2010bcffbae0 831
ccoleman 0:2010bcffbae0 832 }
ccoleman 0:2010bcffbae0 833
ccoleman 0:2010bcffbae0 834 } else {
ccoleman 0:2010bcffbae0 835 // done with the capture sequence. we can wait for the PIT0 IRQ to restart
ccoleman 0:2010bcffbae0 836
ccoleman 0:2010bcffbae0 837 TAOS_CLK_HIGH;
ccoleman 0:2010bcffbae0 838
ccoleman 0:2010bcffbae0 839 for(Junk = 0; Junk<50; Junk++) {
ccoleman 0:2010bcffbae0 840 }
ccoleman 0:2010bcffbae0 841
ccoleman 0:2010bcffbae0 842 TAOS_CLK_LOW;
ccoleman 0:2010bcffbae0 843 CurrentADC_State = ADC_STATE_INIT;
ccoleman 0:2010bcffbae0 844
ccoleman 0:2010bcffbae0 845 //swap the buffer
ccoleman 0:2010bcffbae0 846
ccoleman 0:2010bcffbae0 847 if(LineScanWorkingBuffer == 0) {
ccoleman 0:2010bcffbae0 848 LineScanWorkingBuffer = 1;
ccoleman 0:2010bcffbae0 849
ccoleman 0:2010bcffbae0 850 LineScanImage0WorkingBuffer = &LineScanImage0Buffer[1][0];
ccoleman 0:2010bcffbae0 851 LineScanImage1WorkingBuffer = &LineScanImage1Buffer[1][0];
ccoleman 0:2010bcffbae0 852
ccoleman 0:2010bcffbae0 853 TFC_LineScanCameraData[0] = &LineScanImage0Buffer[0][0];
ccoleman 0:2010bcffbae0 854 TFC_LineScanCameraData[1] = &LineScanImage1Buffer[0][0];
ccoleman 0:2010bcffbae0 855 } else {
ccoleman 0:2010bcffbae0 856 LineScanWorkingBuffer = 0;
ccoleman 0:2010bcffbae0 857 LineScanImage0WorkingBuffer = &LineScanImage0Buffer[0][0];
ccoleman 0:2010bcffbae0 858 LineScanImage1WorkingBuffer = &LineScanImage1Buffer[0][0];
ccoleman 0:2010bcffbae0 859
ccoleman 0:2010bcffbae0 860 TFC_LineScanCameraData[0] = &LineScanImage0Buffer[1][0];
ccoleman 0:2010bcffbae0 861 TFC_LineScanCameraData[1] = &LineScanImage1Buffer[1][0];
ccoleman 0:2010bcffbae0 862 }
ccoleman 0:2010bcffbae0 863
ccoleman 0:2010bcffbae0 864 TFC_LineScanDataReady++;
ccoleman 0:2010bcffbae0 865 }
ccoleman 0:2010bcffbae0 866
ccoleman 0:2010bcffbae0 867 break;
ccoleman 0:2010bcffbae0 868 }
ccoleman 0:2010bcffbae0 869
ccoleman 0:2010bcffbae0 870 }
ccoleman 0:2010bcffbae0 871
ccoleman 0:2010bcffbae0 872 void TFC_InitLineScanCamera()
ccoleman 0:2010bcffbae0 873 {
ccoleman 0:2010bcffbae0 874 SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTD_MASK; //Make sure the clock is enabled for PORTE;
ccoleman 0:2010bcffbae0 875 PORTE->PCR[1] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK; //Enable GPIO on on the pin for the CLOCK Signal
ccoleman 0:2010bcffbae0 876 PORTD->PCR[7] = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK; //Enable GPIO on on the pin for SI signal
ccoleman 0:2010bcffbae0 877
ccoleman 0:2010bcffbae0 878 PORTD->PCR[5] = PORT_PCR_MUX(0); //Make sure AO signal goes to an analog input
ccoleman 0:2010bcffbae0 879 PORTD->PCR[6] = PORT_PCR_MUX(0); //Make sure AO signal goes to an analog input
ccoleman 0:2010bcffbae0 880
ccoleman 0:2010bcffbae0 881 //Make sure the Clock and SI pins are outputs
ccoleman 0:2010bcffbae0 882 PTD->PDDR |= (1<<7);
ccoleman 0:2010bcffbae0 883 PTE->PDDR |= (1<<1);
ccoleman 0:2010bcffbae0 884
ccoleman 0:2010bcffbae0 885 TAOS_CLK_LOW;
ccoleman 0:2010bcffbae0 886 TAOS_SI_LOW;
ccoleman 0:2010bcffbae0 887
ccoleman 0:2010bcffbae0 888 LineScanWorkingBuffer = 0;
ccoleman 0:2010bcffbae0 889
ccoleman 0:2010bcffbae0 890 LineScanImage0WorkingBuffer = &LineScanImage0Buffer[LineScanWorkingBuffer][0];
ccoleman 0:2010bcffbae0 891 LineScanImage1WorkingBuffer = &LineScanImage1Buffer[LineScanWorkingBuffer][0];
ccoleman 0:2010bcffbae0 892
ccoleman 0:2010bcffbae0 893 TFC_LineScanCameraData[0] = &LineScanImage0Buffer[1][0];
ccoleman 0:2010bcffbae0 894 TFC_LineScanCameraData[1] = &LineScanImage1Buffer[1][0];
ccoleman 0:2010bcffbae0 895 }
ccoleman 0:2010bcffbae0 896
ccoleman 0:2010bcffbae0 897
ccoleman 0:2010bcffbae0 898
ccoleman 0:2010bcffbae0 899
ccoleman 0:2010bcffbae0 900
ccoleman 0:2010bcffbae0 901 /** Initialized TPM0 to be used for generating PWM signals for the the dual drive motors. This method is called in the TFC constructor with a default value of 4000.0Hz
ccoleman 0:2010bcffbae0 902 *
ccoleman 0:2010bcffbae0 903 * @param SwitchingFrequency PWM Switching Frequency in floating point format. Pick something between 1000 and 9000. Maybe you can modulate it and make a tune.
ccoleman 0:2010bcffbae0 904 */
ccoleman 0:2010bcffbae0 905 void TFC_InitMotorPWM(float SwitchingFrequency)
ccoleman 0:2010bcffbae0 906 {
ccoleman 0:2010bcffbae0 907 //Clock Setup for the TPM requires a couple steps.
ccoleman 0:2010bcffbae0 908
ccoleman 0:2010bcffbae0 909
ccoleman 0:2010bcffbae0 910 //1st, set the clock mux
ccoleman 0:2010bcffbae0 911 //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
ccoleman 4:4233d072b5af 912 // SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
ccoleman 4:4233d072b5af 913 // SIM->SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
ccoleman 4:4233d072b5af 914 // SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); //We want the MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
ccoleman 0:2010bcffbae0 915
ccoleman 0:2010bcffbae0 916
ccoleman 0:2010bcffbae0 917 //Enable the Clock to the FTM0 Module
ccoleman 0:2010bcffbae0 918 //See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
ccoleman 0:2010bcffbae0 919 SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK;
ccoleman 0:2010bcffbae0 920
ccoleman 0:2010bcffbae0 921 //The TPM Module has Clock. Now set up the peripheral
ccoleman 0:2010bcffbae0 922
ccoleman 0:2010bcffbae0 923 //Blow away the control registers to ensure that the counter is not running
ccoleman 0:2010bcffbae0 924 TPM0->SC = 0;
ccoleman 0:2010bcffbae0 925 TPM0->CONF = 0;
ccoleman 0:2010bcffbae0 926
ccoleman 0:2010bcffbae0 927 //While the counter is disabled we can setup the prescaler
ccoleman 0:2010bcffbae0 928
ccoleman 0:2010bcffbae0 929 TPM0->SC = TPM_SC_PS(FTM0_CLK_PRESCALE);
ccoleman 0:2010bcffbae0 930
ccoleman 0:2010bcffbae0 931 //Setup the mod register to get the correct PWM Period
ccoleman 0:2010bcffbae0 932
ccoleman 0:2010bcffbae0 933 TPM0->MOD = (uint32_t)((float)(FTM0_CLOCK/(1<<FTM0_CLK_PRESCALE))/SwitchingFrequency);
ccoleman 0:2010bcffbae0 934
ccoleman 0:2010bcffbae0 935 //Setup Channels 0,1,2,3
ccoleman 0:2010bcffbae0 936 TPM0->CONTROLS[0].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
ccoleman 0:2010bcffbae0 937 TPM0->CONTROLS[1].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; // invert the second PWM signal for a complimentary output;
ccoleman 0:2010bcffbae0 938 TPM0->CONTROLS[2].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
ccoleman 0:2010bcffbae0 939 TPM0->CONTROLS[3].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; // invert the second PWM signal for a complimentary output;
ccoleman 0:2010bcffbae0 940
ccoleman 0:2010bcffbae0 941 //Enable the Counter
ccoleman 0:2010bcffbae0 942
ccoleman 0:2010bcffbae0 943 //Set the Default duty cycle to 50% duty cycle
ccoleman 0:2010bcffbae0 944 TFC_SetMotorPWM(0.0,0.0);
ccoleman 0:2010bcffbae0 945
ccoleman 0:2010bcffbae0 946 //Enable the TPM COunter
ccoleman 0:2010bcffbae0 947 TPM0->SC |= TPM_SC_CMOD(1);
ccoleman 0:2010bcffbae0 948
ccoleman 0:2010bcffbae0 949 //Enable the FTM functions on the the port
ccoleman 0:2010bcffbae0 950 PORTC->PCR[1] = PORT_PCR_MUX(4);
ccoleman 0:2010bcffbae0 951 PORTC->PCR[2] = PORT_PCR_MUX(4);
ccoleman 0:2010bcffbae0 952 PORTC->PCR[3] = PORT_PCR_MUX(4);
ccoleman 0:2010bcffbae0 953 PORTC->PCR[4] = PORT_PCR_MUX(4);
ccoleman 0:2010bcffbae0 954
ccoleman 0:2010bcffbae0 955 }
ccoleman 0:2010bcffbae0 956
ccoleman 0:2010bcffbae0 957 void TFC_SetMotorPWM(float MotorA , float MotorB)
ccoleman 0:2010bcffbae0 958 {
ccoleman 0:2010bcffbae0 959 if(MotorA>1.0)
ccoleman 0:2010bcffbae0 960 MotorA = 1.0;
ccoleman 0:2010bcffbae0 961 else if(MotorA<-1.0)
ccoleman 0:2010bcffbae0 962 MotorA = -1.0;
ccoleman 0:2010bcffbae0 963
ccoleman 0:2010bcffbae0 964 if(MotorB>1.0)
ccoleman 0:2010bcffbae0 965 MotorB = 1.0;
ccoleman 0:2010bcffbae0 966 else if(MotorB<-1.0)
ccoleman 0:2010bcffbae0 967 MotorB = -1.0;
ccoleman 0:2010bcffbae0 968
ccoleman 0:2010bcffbae0 969 TPM0->CONTROLS[2].CnV = (uint16_t) ((float)TPM0->MOD * (float)((MotorA + 1.0)/2.0));
ccoleman 0:2010bcffbae0 970 TPM0->CONTROLS[3].CnV = TPM0->CONTROLS[2].CnV;
ccoleman 0:2010bcffbae0 971 TPM0->CONTROLS[0].CnV = (uint16_t) ((float)TPM0->MOD * (float)((MotorB + 1.0)/2.0));
ccoleman 0:2010bcffbae0 972 TPM0->CONTROLS[1].CnV = TPM0->CONTROLS[0].CnV;
ccoleman 0:2010bcffbae0 973
ccoleman 0:2010bcffbae0 974 }
ccoleman 0:2010bcffbae0 975
ccoleman 0:2010bcffbae0 976 //Pot Reading is Scaled to return a value of -1.0 to 1.0
ccoleman 0:2010bcffbae0 977 float TFC_ReadPot(uint8_t Channel)
ccoleman 0:2010bcffbae0 978 {
ccoleman 0:2010bcffbae0 979 if(Channel == 0)
ccoleman 0:2010bcffbae0 980 return ((float)PotADC_Value[0]/-127.5)+1.0;
ccoleman 0:2010bcffbae0 981 else
ccoleman 0:2010bcffbae0 982 return ((float)PotADC_Value[1]/-127.5)+1.0;;
ccoleman 0:2010bcffbae0 983 }
ccoleman 0:2010bcffbae0 984
ccoleman 0:2010bcffbae0 985 float TFC_ReadBatteryVoltage()
ccoleman 0:2010bcffbae0 986 {
ccoleman 0:2010bcffbae0 987 return (((float)BatSenseADC_Value/(float)(ADC_MAX_CODE)) * 3.0);// * ((47000.0+10000.0)/10000.0);
ccoleman 0:2010bcffbae0 988 }
ccoleman 4:4233d072b5af 989
ccoleman 4:4233d072b5af 990 extern volatile uint8_t TFC_LineScanCameraDataReady;
ccoleman 4:4233d072b5af 991
ccoleman 4:4233d072b5af 992 Serial pc2(USBTX,USBRX);
ccoleman 4:4233d072b5af 993 float init2()
ccoleman 4:4233d072b5af 994 {
ccoleman 4:4233d072b5af 995 pc2.baud(38400);
ccoleman 4:4233d072b5af 996 return 0;
ccoleman 4:4233d072b5af 997 }
ccoleman 4:4233d072b5af 998
ccoleman 4:4233d072b5af 999 float getLine()
ccoleman 4:4233d072b5af 1000 {
ccoleman 4:4233d072b5af 1001 // if (TFC_LineScanCameraDataReady != 0)
ccoleman 4:4233d072b5af 1002 // return -1;
ccoleman 4:4233d072b5af 1003 static int count = 0;
ccoleman 4:4233d072b5af 1004 // count++;
ccoleman 4:4233d072b5af 1005 int channel = TFC_PUSH_BUTTON_0_PRESSED ? 1 : 0;
ccoleman 4:4233d072b5af 1006 int flip = TFC_PUSH_BUTTON_1_PRESSED ? 1 : 0;
ccoleman 4:4233d072b5af 1007 // uint8_t* parray = TFC_LineScanCameraData(array);
ccoleman 4:4233d072b5af 1008 for (int i=0; i<128; i++) {
ccoleman 4:4233d072b5af 1009 uint8_t n = TFC_LineScanCameraData[0][i];
ccoleman 4:4233d072b5af 1010 if (n==2)
ccoleman 4:4233d072b5af 1011 pc2.printf(" ") ;
ccoleman 4:4233d072b5af 1012 else
ccoleman 4:4233d072b5af 1013 pc2.printf("%d",n) ;
ccoleman 4:4233d072b5af 1014 }
ccoleman 4:4233d072b5af 1015 pc2.printf("\r\n");
ccoleman 4:4233d072b5af 1016 for (int i=0; i<128; i++) {
ccoleman 4:4233d072b5af 1017 uint8_t n = TFC_LineScanCameraData[0][i];
ccoleman 4:4233d072b5af 1018 if (n==2)
ccoleman 4:4233d072b5af 1019 pc2.printf(" ") ;
ccoleman 4:4233d072b5af 1020 else
ccoleman 4:4233d072b5af 1021 pc2.printf("%d",n) ;
ccoleman 4:4233d072b5af 1022 }
ccoleman 4:4233d072b5af 1023 pc2.printf("\r\n");
ccoleman 4:4233d072b5af 1024
ccoleman 4:4233d072b5af 1025 return 0;
ccoleman 4:4233d072b5af 1026 }