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