A PPM driver for the K64F that uses the CMT module

PPMout.cpp

Committer:
Padman
Date:
2016-09-02
Revision:
1:9b1734761ce3
Parent:
0:04365c9c9994

File content as of revision 1:9b1734761ce3:

#include "PPMout.h"

void PPMout::CMT_IRQHandler() {
         
     uint8_t tmp = CMT_MSC;  // reset interrupt
     counter = (counter + 1)%ARRAY_SIZE;
     CMT_CMD1 = (count_array[counter] >> 8) & 0xFF;
     CMT_CMD2 = count_array[counter] & 0xFF;
}

PPMout::PPMout() {
    
    // Fill the count array with initial values
    for (int i = 0; i < CHANNELS; i++) {

        count_array[i] = (int) (RANGE_STEPS*0.5 + ZERO_STEPS);
    }

    set_sync_length();
    init();
}

void PPMout::update_channel(int channel, float value) {
    
    // Constrain value between 0 and 1
    value = PIN(value, 0, 1);

    // Constrain channel
    channel = PIN(channel, 0, (CHANNELS-1));
    
    // Correction
    channel = (channel*2 + 1)%CHANNELS;

    // Calculate new step value
    int steps = (int) (RANGE_STEPS*value + ZERO_STEPS);

    // Insert new value into array
    count_array[channel] = steps;

    set_sync_length();
}
    
void PPMout::init() {
    
    SIM_SCGC4 |= (1 << SIM_SCGC4_CMT_SHIFT);
    SIM_SOPT2 |= (1 << SIM_SOPT2_PTD7PAD_SHIFT);   // drive strength
    SIM_SCGC5 |= (1 << SIM_SCGC5_PORTD_SHIFT);  // power PORTD
    PORTD_PCR7 = PORT_PCR_MUX(2)|(1<< PORT_PCR_DSE_SHIFT)|(1 << PORT_PCR_SRE_SHIFT);
    CMT_PPS = CMT_PPS_VAL;    // 5 mhz
    CMT_CGH1 = 1;
    CMT_CGL1 = 1;
    CMT_CMD1 = (count_array[counter] >> 8) & 0xFF;
    CMT_CMD2 = count_array[counter] & 0xFF;
    CMT_CMD3 = (GAP_STEPS >> 8) & 0xFF;
    CMT_CMD4 = GAP_STEPS & 0xFF;
    CMT_OC = 0x60;     // enable IRO
    CMT_MSC = (1 << 3) | (1 << 1) | (1 << 0);     // enable CMT, interrupt and baseband
    
    NVIC_SetVector(CMT_IRQn, (uint32_t) &PPMout::CMT_IRQHandler);
    NVIC_EnableIRQ(CMT_IRQn);
}

void PPMout::set_sync_length() {

    int total = 0;

    for (int i = 0; i < CHANNELS; i++) {

        total += count_array[i];
    }

    // Update sync length to ensure it lasts 20ms
    count_array[CHANNELS] = MAX_NON_GAP_STEPS - total;
}

int PPMout::count_array[ARRAY_SIZE] = {};
int PPMout::counter = 0;