good god / PPM

Files at this revision

API Documentation at this revision

Comitter:
goodgod
Date:
Sun Jan 08 20:17:29 2017 +0000
Commit message:
Initial ppm commit;

Changed in this revision

PPMOut.cpp Show annotated file Show diff for this revision Revisions of this file
PPMOut.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPMOut.cpp	Sun Jan 08 20:17:29 2017 +0000
@@ -0,0 +1,64 @@
+#include "mbed.h"
+#include "PPMOut.h"
+
+PpmOut::PpmOut(PinName pin, uint8_t channel_number): ppm(pin) {
+    if(channel_number > MAX_CHANNELS){
+        this->channel_number = MAX_CHANNELS;
+    }
+    this->channel_number = channel_number;
+    resetChannels();
+    pulse_out = 1;
+    ppm = pulse_out;
+    current_dot = 0;
+    timeout.attach_us(this, &PpmOut::attimeout, FRAME_LEN);
+}
+
+void PpmOut::setChannel(int channel_no, uint16_t value) {
+    //__disable_irq();     // Disable Interrupts
+    if(channel_no > channel_number-1){
+        return;
+    }
+    if(value > MAX_CHANNEL_VALUE){
+        value = MAX_CHANNEL_VALUE;
+    }
+    dots[channel_no*2] = CHANNEL_SYNC;
+    dots[channel_no*2+1] = CHANNEL_PAD_SYNC + value;
+
+    setFrameSync();
+    //__enable_irq();     // Enable Interrupts
+}
+
+void PpmOut::setFrameSync(){
+    uint16_t sum_channels = 0;
+    for(uint8_t channel = 0; channel < channel_number; channel++) {
+        sum_channels += dots[channel*2+1];
+    }
+    sum_channels += channel_number*CHANNEL_SYNC;
+    dots[channel_number*2] = CHANNEL_SYNC;
+    dots[channel_number*2+1] = FRAME_LEN - CHANNEL_SYNC - sum_channels;
+}
+
+void PpmOut::attimeout() {
+    pulse_out = !pulse_out;
+    ppm = pulse_out;
+    
+    timeout.attach_us(this, &PpmOut::attimeout, dots[current_dot]);
+    current_dot++;
+
+    if(current_dot == channel_number*2+2) { // 2 for FRAME_SYNC
+        current_dot = 0;
+    }
+}
+
+void PpmOut::resetChannels() {
+    int8_t channel;
+    uint16_t sum_channels = 0;
+
+    current_dot = 0;
+    memset(dots, 0x00, DOTS);
+    for(channel = 0; channel < channel_number; channel++) {
+        dots[channel*2] = CHANNEL_SYNC;
+        dots[channel*2+1] = CHANNEL_PAD_SYNC;
+    }
+    setFrameSync();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPMOut.h	Sun Jan 08 20:17:29 2017 +0000
@@ -0,0 +1,36 @@
+#ifndef CH_PPM_OUT
+#define CH_PPM_OUT
+
+class PpmOut{
+    public:
+        static const uint8_t MAX_CHANNELS = 8;
+        static const uint16_t CHANNEL_SYNC = 300; // us
+        static const uint16_t CHANNEL_PAD_SYNC = 1000 - CHANNEL_SYNC; // us
+        static const uint16_t FRAME_SYNC = 5000; // us
+        static const uint16_t FRAME_LEN = 22300; // us
+        static const uint16_t MAX_CHANNEL_VALUE = 1000; // us
+        static const uint16_t MIN_CHANNEL_VALUE = 0; 
+        static const uint16_t DOTS = MAX_CHANNELS*2+2; // two dots per channel + FRAME_SYNC
+
+        /* Will start the PPM output */
+        PpmOut(PinName pin, uint8_t channel_number);
+        /* Values go from MIN_CHANNEL_VALUE to MAX_CHANNEL_VALUE */
+        void setChannel(int channel_no, uint16_t value);
+
+    private:
+        /* These are the time dots where the signal changes the value 
+           from 0 to 1 and in reverse */
+        uint16_t dots[DOTS];
+        Timeout timeout;
+        DigitalOut ppm;
+        uint8_t current_dot;
+        uint8_t channel_number;
+        uint16_t frame_length;
+        uint16_t pulse_out;
+
+        void attimeout();
+        inline void resetChannels();
+        inline void setFrameSync();
+};
+
+#endif // CH_PPM_OUT
\ No newline at end of file