A PPM driver for the K64F that uses the CMT module

Committer:
Padman
Date:
Fri Sep 02 11:48:31 2016 +0000
Revision:
0:04365c9c9994
Child:
1:9b1734761ce3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Padman 0:04365c9c9994 1 #include "PPMout.h"
Padman 0:04365c9c9994 2
Padman 0:04365c9c9994 3 void PPMout::CMT_IRQHandler() {
Padman 0:04365c9c9994 4
Padman 0:04365c9c9994 5 uint8_t tmp = CMT_MSC; // reset interrupt
Padman 0:04365c9c9994 6 counter = (counter + 1)%ARRAY_SIZE;
Padman 0:04365c9c9994 7 CMT_CMD1 = (count_array[counter] >> 8) & 0xFF;
Padman 0:04365c9c9994 8 CMT_CMD2 = count_array[counter] & 0xFF;
Padman 0:04365c9c9994 9 }
Padman 0:04365c9c9994 10
Padman 0:04365c9c9994 11 PPMout::PPMout() {
Padman 0:04365c9c9994 12
Padman 0:04365c9c9994 13 // Fill the count array with initial values
Padman 0:04365c9c9994 14 for (int i = 0; i < CHANNELS; i++) {
Padman 0:04365c9c9994 15
Padman 0:04365c9c9994 16 count_array[i] = (int) (RANGE_STEPS*0.5 + ZERO_STEPS);
Padman 0:04365c9c9994 17 }
Padman 0:04365c9c9994 18
Padman 0:04365c9c9994 19 set_sync_length();
Padman 0:04365c9c9994 20 init();
Padman 0:04365c9c9994 21 }
Padman 0:04365c9c9994 22
Padman 0:04365c9c9994 23 void PPMout::update_channel(int channel, float value) {
Padman 0:04365c9c9994 24
Padman 0:04365c9c9994 25 // Constrain value between 0 and 1
Padman 0:04365c9c9994 26 value = PIN(value, 0, 1);
Padman 0:04365c9c9994 27
Padman 0:04365c9c9994 28 // Constrain channel
Padman 0:04365c9c9994 29 channel = PIN(channel, 0, (CHANNELS-1));
Padman 0:04365c9c9994 30
Padman 0:04365c9c9994 31 // Calculate new step value
Padman 0:04365c9c9994 32 int steps = (int) (RANGE_STEPS*value + ZERO_STEPS);
Padman 0:04365c9c9994 33
Padman 0:04365c9c9994 34 // Insert new value into array
Padman 0:04365c9c9994 35 count_array[channel] = steps;
Padman 0:04365c9c9994 36
Padman 0:04365c9c9994 37 set_sync_length();
Padman 0:04365c9c9994 38 }
Padman 0:04365c9c9994 39
Padman 0:04365c9c9994 40 void PPMout::init() {
Padman 0:04365c9c9994 41
Padman 0:04365c9c9994 42 SIM_SCGC4 |= (1 << SIM_SCGC4_CMT_SHIFT);
Padman 0:04365c9c9994 43 SIM_SOPT2 |= (1 << SIM_SOPT2_PTD7PAD_SHIFT); // drive strength
Padman 0:04365c9c9994 44 SIM_SCGC5 |= (1 << SIM_SCGC5_PORTD_SHIFT); // power PORTD
Padman 0:04365c9c9994 45 PORTD_PCR7 = PORT_PCR_MUX(2)|(1<< PORT_PCR_DSE_SHIFT)|(1 << PORT_PCR_SRE_SHIFT);
Padman 0:04365c9c9994 46 CMT_PPS = CMT_PPS_VAL; // 5 mhz
Padman 0:04365c9c9994 47 CMT_CGH1 = 1;
Padman 0:04365c9c9994 48 CMT_CGL1 = 1;
Padman 0:04365c9c9994 49 CMT_CMD1 = (count_array[counter] >> 8) & 0xFF;
Padman 0:04365c9c9994 50 CMT_CMD2 = count_array[counter] & 0xFF;
Padman 0:04365c9c9994 51 CMT_CMD3 = (GAP_STEPS >> 8) & 0xFF;
Padman 0:04365c9c9994 52 CMT_CMD4 = GAP_STEPS & 0xFF;
Padman 0:04365c9c9994 53 CMT_OC = 0x60; // enable IRO
Padman 0:04365c9c9994 54 CMT_MSC = (1 << 3) | (1 << 1) | (1 << 0); // enable CMT, interrupt and baseband
Padman 0:04365c9c9994 55
Padman 0:04365c9c9994 56 NVIC_SetVector(CMT_IRQn, (uint32_t) &PPMout::CMT_IRQHandler);
Padman 0:04365c9c9994 57 NVIC_EnableIRQ(CMT_IRQn);
Padman 0:04365c9c9994 58 }
Padman 0:04365c9c9994 59
Padman 0:04365c9c9994 60 void PPMout::set_sync_length() {
Padman 0:04365c9c9994 61
Padman 0:04365c9c9994 62 int total = 0;
Padman 0:04365c9c9994 63
Padman 0:04365c9c9994 64 for (int i = 0; i < CHANNELS; i++) {
Padman 0:04365c9c9994 65
Padman 0:04365c9c9994 66 total += count_array[i];
Padman 0:04365c9c9994 67 }
Padman 0:04365c9c9994 68
Padman 0:04365c9c9994 69 // Update sync length to ensure it lasts 20ms
Padman 0:04365c9c9994 70 count_array[CHANNELS] = MAX_NON_GAP_STEPS - total;
Padman 0:04365c9c9994 71 }
Padman 0:04365c9c9994 72
Padman 0:04365c9c9994 73 int PPMout::count_array[ARRAY_SIZE] = {};
Padman 0:04365c9c9994 74 int PPMout::counter = 0;