A PPM driver for the K64F that uses the CMT module

Committer:
Padman
Date:
Fri Sep 02 16:01:52 2016 +0000
Revision:
1:9b1734761ce3
Parent:
0:04365c9c9994
Some adjustments to correct channel number error

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 1:9b1734761ce3 30
Padman 1:9b1734761ce3 31 // Correction
Padman 1:9b1734761ce3 32 channel = (channel*2 + 1)%CHANNELS;
Padman 0:04365c9c9994 33
Padman 0:04365c9c9994 34 // Calculate new step value
Padman 0:04365c9c9994 35 int steps = (int) (RANGE_STEPS*value + ZERO_STEPS);
Padman 0:04365c9c9994 36
Padman 0:04365c9c9994 37 // Insert new value into array
Padman 0:04365c9c9994 38 count_array[channel] = steps;
Padman 0:04365c9c9994 39
Padman 0:04365c9c9994 40 set_sync_length();
Padman 0:04365c9c9994 41 }
Padman 0:04365c9c9994 42
Padman 0:04365c9c9994 43 void PPMout::init() {
Padman 0:04365c9c9994 44
Padman 0:04365c9c9994 45 SIM_SCGC4 |= (1 << SIM_SCGC4_CMT_SHIFT);
Padman 0:04365c9c9994 46 SIM_SOPT2 |= (1 << SIM_SOPT2_PTD7PAD_SHIFT); // drive strength
Padman 0:04365c9c9994 47 SIM_SCGC5 |= (1 << SIM_SCGC5_PORTD_SHIFT); // power PORTD
Padman 0:04365c9c9994 48 PORTD_PCR7 = PORT_PCR_MUX(2)|(1<< PORT_PCR_DSE_SHIFT)|(1 << PORT_PCR_SRE_SHIFT);
Padman 0:04365c9c9994 49 CMT_PPS = CMT_PPS_VAL; // 5 mhz
Padman 0:04365c9c9994 50 CMT_CGH1 = 1;
Padman 0:04365c9c9994 51 CMT_CGL1 = 1;
Padman 0:04365c9c9994 52 CMT_CMD1 = (count_array[counter] >> 8) & 0xFF;
Padman 0:04365c9c9994 53 CMT_CMD2 = count_array[counter] & 0xFF;
Padman 0:04365c9c9994 54 CMT_CMD3 = (GAP_STEPS >> 8) & 0xFF;
Padman 0:04365c9c9994 55 CMT_CMD4 = GAP_STEPS & 0xFF;
Padman 0:04365c9c9994 56 CMT_OC = 0x60; // enable IRO
Padman 0:04365c9c9994 57 CMT_MSC = (1 << 3) | (1 << 1) | (1 << 0); // enable CMT, interrupt and baseband
Padman 0:04365c9c9994 58
Padman 0:04365c9c9994 59 NVIC_SetVector(CMT_IRQn, (uint32_t) &PPMout::CMT_IRQHandler);
Padman 0:04365c9c9994 60 NVIC_EnableIRQ(CMT_IRQn);
Padman 0:04365c9c9994 61 }
Padman 0:04365c9c9994 62
Padman 0:04365c9c9994 63 void PPMout::set_sync_length() {
Padman 0:04365c9c9994 64
Padman 0:04365c9c9994 65 int total = 0;
Padman 0:04365c9c9994 66
Padman 0:04365c9c9994 67 for (int i = 0; i < CHANNELS; i++) {
Padman 0:04365c9c9994 68
Padman 0:04365c9c9994 69 total += count_array[i];
Padman 0:04365c9c9994 70 }
Padman 0:04365c9c9994 71
Padman 0:04365c9c9994 72 // Update sync length to ensure it lasts 20ms
Padman 0:04365c9c9994 73 count_array[CHANNELS] = MAX_NON_GAP_STEPS - total;
Padman 0:04365c9c9994 74 }
Padman 0:04365c9c9994 75
Padman 0:04365c9c9994 76 int PPMout::count_array[ARRAY_SIZE] = {};
Padman 0:04365c9c9994 77 int PPMout::counter = 0;