Rev 20 | Rev 22 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 20 | Rev 21 | ||
|---|---|---|---|
| Line 57... | Line 57... | ||
| 57 | // with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000 |
57 | // with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000 |
| 58 | // freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the first pulse longer than 1/300 of a second as being a proper closure . |
58 | // freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the first pulse longer than 1/300 of a second as being a proper closure . |
| 59 | // the TIM2 counter counts in 10uS increments, |
59 | // the TIM2 counter counts in 10uS increments, |
| 60 | #define BREAKER_MIN (RPM_COUNT_RATE/300) |
60 | #define BREAKER_MIN (RPM_COUNT_RATE/300) |
| 61 | 61 | ||
| - | 62 | #define STARTER_LIMIT 5 |
|
| - | 63 | ||
| 62 | volatile char TimerFlag = 0; |
64 | volatile char TimerFlag = 0; |
| 63 | 65 | ||
| 64 | volatile char NoSerialInCTR = 0; // Missing characters coming in on USART1 |
66 | volatile char NoSerialInCTR = 0; // Missing characters coming in on USART1 |
| 65 | volatile char NoSerialIn = 0; |
67 | volatile char NoSerialIn = 0; |
| 66 | 68 | ||
| Line 81... | Line 83... | ||
| 81 | unsigned int Coded_RPM = 0; |
83 | unsigned int Coded_RPM = 0; |
| 82 | unsigned int Coded_CHT = 0; |
84 | unsigned int Coded_CHT = 0; |
| 83 | 85 | ||
| 84 | uint32_t Power_CHT_Timer; |
86 | uint32_t Power_CHT_Timer; |
| 85 | 87 | ||
| - | 88 | uint16_t Starter_Debounce = 0; |
|
| - | 89 | ||
| 86 | /* USER CODE END PV */ |
90 | /* USER CODE END PV */ |
| 87 | 91 | ||
| 88 | /* Private function prototypes -----------------------------------------------*/ |
92 | /* Private function prototypes -----------------------------------------------*/ |
| 89 | void SystemClock_Config(void); |
93 | void SystemClock_Config(void); |
| 90 | void Error_Handler(void); |
94 | void Error_Handler(void); |
| Line 205... | Line 209... | ||
| 205 | // this uses a MAX6675 which is a simple 16 bit read |
209 | // this uses a MAX6675 which is a simple 16 bit read |
| 206 | // SPI is configured for 8 bits so I can use an OLED display if I need it |
210 | // SPI is configured for 8 bits so I can use an OLED display if I need it |
| 207 | // must wait > 0.22 seconds between conversion attempts as this is the measurement time |
211 | // must wait > 0.22 seconds between conversion attempts as this is the measurement time |
| 208 | // |
212 | // |
| 209 | 213 | ||
| 210 | GPIO_PinState CHT_Enable = GPIO_PIN_SET; |
214 | FunctionalState CHT_Enable = ENABLE; |
| 211 | 215 | ||
| 212 | uint8_t CHT_Timer[2] = |
216 | uint8_t CHT_Timer[2] = |
| 213 | { 0, 0 }; // two temperature readings |
217 | { 0, 0 }; // two temperature readings |
| 214 | uint8_t CHT_Observations[2] = |
218 | uint16_t CHT_Observations[2] = |
| 215 | { 0, 0 }; |
219 | { 0, 0 }; |
| 216 | 220 | ||
| 217 | void ProcessCHT(int instance) |
221 | void ProcessCHT(int instance) |
| 218 | { |
222 | { |
| 219 | uint8_t buffer[2]; |
223 | uint8_t buffer[2]; |
| 220 | if (instance > 2) |
224 | if (instance > 2) |
| 221 | return; |
225 | return; |
| 222 | CHT_Timer[instance]++; |
226 | CHT_Timer[instance]++; |
| 223 | if ((CHT_Enable == GPIO_PIN_SET) && (CHT_Timer[instance] >= 4)) // every 300 milliseconds |
227 | if ((CHT_Enable == ENABLE) && (CHT_Timer[instance] >= 4)) // every 300 milliseconds |
| 224 | { |
228 | { |
| 225 | 229 | ||
| 226 | CHT_Timer[instance] = 0; |
230 | CHT_Timer[instance] = 0; |
| 227 | 231 | ||
| 228 | uint16_t Pin = (instance == 0) ? SPI_NS_Temp_Pin : SPI_NS_Temp2_Pin; |
232 | uint16_t Pin = (instance == 0) ? SPI_NS_Temp_Pin : SPI_NS_Temp2_Pin; |
| Line 234... | Line 238... | ||
| 234 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, Pin, GPIO_PIN_SET); |
238 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, Pin, GPIO_PIN_SET); |
| 235 | 239 | ||
| 236 | uint16_t obs = (buffer[0] << 8) | buffer[1]; |
240 | uint16_t obs = (buffer[0] << 8) | buffer[1]; |
| 237 | 241 | ||
| 238 | uint8_t good = (obs & 4) == 0; |
242 | uint8_t good = (obs & 4) == 0; |
| - | 243 | ||
| - | 244 | ||
| - | 245 | ||
| 239 | if (good) |
246 | if (good) |
| 240 | { |
247 | { |
| 241 | CHT_Observations[instance] = obs >> 5; |
248 | CHT_Observations[instance] = obs >> 5; |
| 242 | } |
249 | } |
| 243 | else |
- | |
| 244 | { |
- | |
| 245 | CHT_Observations[instance] = 1024; // signal fail |
- | |
| 246 | } |
- | |
| 247 | } |
250 | } |
| 248 | 251 | ||
| 249 | plx_sendword(PLX_X_CHT); |
252 | plx_sendword(PLX_X_CHT); |
| 250 | PutCharSerial(&uc1, instance); |
253 | PutCharSerial(&uc1, instance); |
| 251 | plx_sendword(CHT_Observations[instance]); |
254 | plx_sendword(CHT_Observations[instance]); |
| 252 | 255 | ||
| 253 | } |
256 | } |
| 254 | 257 | ||
| 255 | void EnableCHT(GPIO_PinState state) |
258 | void EnableCHT(FunctionalState state) |
| - | 259 | ||
| 256 | { |
260 | { |
| 257 | GPIO_InitTypeDef GPIO_InitStruct; |
261 | GPIO_InitTypeDef GPIO_InitStruct; |
| 258 | 262 | ||
| 259 | CHT_Enable = state; |
263 | CHT_Enable = state; |
| 260 | HAL_GPIO_WritePin(ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, state); |
- | |
| 261 | /* drive the NSS to high if the interface is enabled */ |
- | |
| - | 264 | ||
| 262 | 265 | ||
| 263 | /* enable SPI in live mode : assume it and its GPIOs are already initialised in SPI mode */ |
266 | /* enable SPI in live mode : assume it and its GPIOs are already initialised in SPI mode */ |
| 264 | if (state == GPIO_PIN_SET) |
267 | if (state == ENABLE) |
| 265 | { |
268 | { |
| 266 | - | ||
| - | 269 | HAL_GPIO_WritePin(ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_SET ); |
|
| 267 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin, GPIO_PIN_SET); |
270 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin, GPIO_PIN_SET); |
| 268 | HAL_GPIO_WritePin(SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin, |
271 | HAL_GPIO_WritePin(SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin, |
| 269 | GPIO_PIN_SET); |
272 | GPIO_PIN_SET); |
| 270 | 273 | ||
| 271 | /* put the SPI pins back into SPI AF mode */ |
274 | /* put the SPI pins back into SPI AF mode */ |
| Line 278... | Line 281... | ||
| 278 | 281 | ||
| 279 | } |
282 | } |
| 280 | else |
283 | else |
| 281 | { |
284 | { |
| 282 | /* Power down the SPI interface taking signals all low */ |
285 | /* Power down the SPI interface taking signals all low */ |
| - | 286 | HAL_GPIO_WritePin(ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_RESET ); |
|
| 283 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin, |
287 | HAL_GPIO_WritePin(SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin, |
| 284 | GPIO_PIN_RESET); |
288 | GPIO_PIN_RESET); |
| 285 | HAL_GPIO_WritePin(SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin, |
289 | HAL_GPIO_WritePin(SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin, |
| 286 | GPIO_PIN_RESET); |
290 | GPIO_PIN_RESET); |
| 287 | 291 | ||
| Line 321... | Line 325... | ||
| 321 | uint32_t ADC_VREF_MV = 3300; // 3.300V typical |
325 | uint32_t ADC_VREF_MV = 3300; // 3.300V typical |
| 322 | const uint16_t STM32REF_MV = 1224; // 1.224V typical |
326 | const uint16_t STM32REF_MV = 1224; // 1.224V typical |
| 323 | 327 | ||
| 324 | void CalibrateADC(void) |
328 | void CalibrateADC(void) |
| 325 | { |
329 | { |
| 326 | uint32_t adc_val = FILT_Samples[6]; // as set up in device config |
330 | uint32_t adc_val = FILT_Samples[5]; // as set up in device config |
| 327 | ADC_VREF_MV = (STM32REF_MV * 4096) / adc_val; |
331 | ADC_VREF_MV = (STM32REF_MV * 4096) / adc_val; |
| 328 | } |
332 | } |
| 329 | 333 | ||
| 330 | void ProcessCPUTemperature(int instance) |
334 | void ProcessCPUTemperature(int instance) |
| 331 | { |
335 | { |
| 332 | int32_t temp_val; |
336 | int32_t temp_val; |
| 333 | uint16_t TS_CAL30 = *(uint16_t *) 0x1FF8007A; /* ADC reading for temperature sensor at 30 degrees C with Vref = 3000mV */ |
337 | uint16_t TS_CAL30 = *(uint16_t *) (0x1FF8007AUL); /* ADC reading for temperature sensor at 30 degrees C with Vref = 3000mV */ |
| 334 | uint16_t TS_CAL110 = *(uint16_t *) 0x1FF8007E; /* ADC reading for temperature sensor at 110 degrees C with Vref = 3000mV */ |
338 | uint16_t TS_CAL110 = *(uint16_t *) (0x1FF8007EUL); /* ADC reading for temperature sensor at 110 degrees C with Vref = 3000mV */ |
| 335 | /* get the ADC reading corresponding to ADC channel 16 after turning on the ADC */ |
339 | /* get the ADC reading corresponding to ADC channel 16 after turning on the ADC */ |
| 336 | 340 | ||
| 337 | temp_val = FILT_Samples[5]; |
341 | temp_val = FILT_Samples[5]; |
| 338 | 342 | ||
| 339 | /* renormalise temperature value to account for different ADC Vref : normalise to that which we would get for a 3000mV reference */ |
343 | /* renormalise temperature value to account for different ADC Vref : normalise to that which we would get for a 3000mV reference */ |
| 340 | temp_val = temp_val * ADC_VREF_MV / 3000UL; |
344 | temp_val = temp_val * ADC_VREF_MV / (Scale * 3000UL); |
| 341 | 345 | ||
| 342 | int32_t result = 800 * ((int32_t) temp_val - TS_CAL30); |
346 | int32_t result = 800 * ((int32_t) temp_val - TS_CAL30); |
| 343 | result = result / (TS_CAL110 - TS_CAL30) + 300; |
347 | result = result / (TS_CAL110 - TS_CAL30) + 300; |
| 344 | 348 | ||
| 345 | if (result < 0) |
349 | if (result < 0) |
| Line 476... | Line 480... | ||
| 476 | if (HAL_GetTick() > Ticks) |
480 | if (HAL_GetTick() > Ticks) |
| 477 | { |
481 | { |
| 478 | Ticks += 100; |
482 | Ticks += 100; |
| 479 | filter_ADC_samples(); |
483 | filter_ADC_samples(); |
| 480 | // delay to calibrate ADC |
484 | // delay to calibrate ADC |
| 481 | if (CalCounter < 500) |
485 | if (CalCounter < 1000) |
| 482 | { |
486 | { |
| 483 | CalCounter += 100; |
487 | CalCounter += 100; |
| 484 | } |
488 | } |
| 485 | 489 | ||
| 486 | if (CalCounter == 400) |
490 | if (CalCounter == 900) |
| 487 | { |
491 | { |
| 488 | CalibrateADC(); |
492 | CalibrateADC(); |
| 489 | } |
493 | } |
| 490 | } |
494 | } |
| 491 | /* when the starter motor is on then power down the CHT sensors as they seem to fail */ |
495 | /* when the starter motor is on then power down the CHT sensors as they seem to fail */ |
| 492 | 496 | ||
| 493 | if (HAL_GPIO_ReadPin(STARTER_ON_GPIO_Port, STARTER_ON_Pin) |
497 | if (HAL_GPIO_ReadPin(STARTER_ON_GPIO_Port, STARTER_ON_Pin) |
| 494 | == GPIO_PIN_RESET) |
498 | == GPIO_PIN_RESET ) |
| - | 499 | { |
|
| - | 500 | if(Starter_Debounce < STARTER_LIMIT) |
|
| - | 501 | { |
|
| - | 502 | Starter_Debounce++; |
|
| - | 503 | } |
|
| - | 504 | } |
|
| - | 505 | else |
|
| - | 506 | { |
|
| - | 507 | if(Starter_Debounce > 0) |
|
| - | 508 | { |
|
| - | 509 | Starter_Debounce --; |
|
| - | 510 | } |
|
| - | 511 | } |
|
| - | 512 | ||
| - | 513 | if (Starter_Debounce == STARTER_LIMIT) |
|
| 495 | { |
514 | { |
| 496 | EnableCHT(GPIO_PIN_RESET); |
515 | EnableCHT(DISABLE); |
| 497 | Power_CHT_Timer = HAL_GetTick() + 5000; |
516 | Power_CHT_Timer = HAL_GetTick() + 5000; |
| 498 | } |
517 | } |
| 499 | else |
518 | else |
| 500 | /* if the Power_CHT_Timer is set then wait for it to timeout, then power up CHT */ |
519 | /* if the Power_CHT_Timer is set then wait for it to timeout, then power up CHT */ |
| 501 | { |
520 | { |
| 502 | if ((Power_CHT_Timer > 0) && (HAL_GetTick() > Power_CHT_Timer)) |
521 | if ((Power_CHT_Timer > 0) && (HAL_GetTick() > Power_CHT_Timer)) |
| 503 | { |
522 | { |
| 504 | EnableCHT(GPIO_PIN_SET); |
523 | EnableCHT(ENABLE); |
| 505 | Power_CHT_Timer = 0; |
524 | Power_CHT_Timer = 0; |
| 506 | } |
525 | } |
| 507 | } |
526 | } |
| 508 | 527 | ||
| 509 | // check to see if we have any incoming data, copy and append if so, if no data then create our own frames. |
528 | // check to see if we have any incoming data, copy and append if so, if no data then create our own frames. |
| Line 695... | Line 714... | ||
| 695 | hspi1.Instance = SPI1; |
714 | hspi1.Instance = SPI1; |
| 696 | hspi1.Init.Mode = SPI_MODE_MASTER; |
715 | hspi1.Init.Mode = SPI_MODE_MASTER; |
| 697 | hspi1.Init.Direction = SPI_DIRECTION_2LINES; |
716 | hspi1.Init.Direction = SPI_DIRECTION_2LINES; |
| 698 | hspi1.Init.DataSize = SPI_DATASIZE_8BIT; |
717 | hspi1.Init.DataSize = SPI_DATASIZE_8BIT; |
| 699 | hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; |
718 | hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; |
| 700 | hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; |
719 | hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; |
| 701 | hspi1.Init.NSS = SPI_NSS_SOFT; |
720 | hspi1.Init.NSS = SPI_NSS_SOFT; |
| 702 | hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; |
721 | hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; |
| 703 | hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; |
722 | hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; |
| 704 | hspi1.Init.TIMode = SPI_TIMODE_DISABLE; |
723 | hspi1.Init.TIMode = SPI_TIMODE_DISABLE; |
| 705 | hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; |
724 | hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; |