LPC800-MAX RGB demo using SCT and MRT

LPC800-MAX RGB demo using State-Configurable Timer(SCT) and Multi-Rate Timer(MRT).
http://www.youtube.com/watch?v=PABxoWZB0YM

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Mon Oct 14 03:59:30 2013 +0000
Parent:
0:f86c572491c3
Commit message:
first commit

Changed in this revision

MRT.cpp Show annotated file Show diff for this revision Revisions of this file
MRT.h Show annotated file Show diff for this revision Revisions of this file
SCT_PWM.cpp Show annotated file Show diff for this revision Revisions of this file
SCT_PWM.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r f86c572491c3 -r 4e19f154ec21 MRT.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MRT.cpp	Mon Oct 14 03:59:30 2013 +0000
@@ -0,0 +1,53 @@
+#include "MRT.h"
+
+MRT::MRT(int channel)
+{
+    static bool insted = false;
+
+    if (!insted) {
+        inst();
+        insted = true;
+    }
+
+    _ch = &LPC_MRT->Channel[channel];
+    _ch->CTRL |= (1<<1); // one-shot
+}
+
+void MRT::inst()
+{
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // enable MRT
+    LPC_SYSCON->PRESETCTRL |= (1<<7); // reset MRT
+    us_clk = SystemCoreClock / 1000000;
+}
+
+void MRT::write(uint32_t interval)
+{
+    _ch->INTVAL = interval | (1<<31); // and LOAD
+    _ch->STAT |= 0x01;
+}
+
+int MRT::status()
+{
+    return (_ch->STAT & 1) ? IDLE : RUNNING;
+}
+
+void MRT::wait_ms(uint32_t timeout_ms)
+{
+    wait_raw(us_clk * 1000 * timeout_ms);
+}
+
+void MRT::wait_us(uint32_t timeout_us)
+{
+    wait_raw(us_clk * timeout_us);
+}
+
+void MRT::wait_raw(uint32_t timeout)
+{
+    write(timeout);
+    while(status() == RUNNING);
+}
+
+uint32_t MRT::read()
+{
+     return _ch->TIMER;
+}
diff -r f86c572491c3 -r 4e19f154ec21 MRT.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MRT.h	Mon Oct 14 03:59:30 2013 +0000
@@ -0,0 +1,26 @@
+#pragma once
+#include "LPC8xx.h"
+
+class MRT {
+public:
+    MRT(int channel = 0);
+    /** write down counter
+     * @param interval start count
+     */
+    void write(uint32_t interval);
+    /** read down counter
+     */
+    uint32_t read();
+    enum STAT {
+        IDLE,
+        RUNNING,
+    };
+    int status();
+    void wait_ms(uint32_t timeout_ms);
+    void wait_us(uint32_t timeout_us);
+    void wait_raw(uint32_t timeout);
+protected:
+    void inst();
+    MRT_Channel_cfg_Type* _ch;
+    int us_clk;
+};
diff -r f86c572491c3 -r 4e19f154ec21 SCT_PWM.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SCT_PWM.cpp	Mon Oct 14 03:59:30 2013 +0000
@@ -0,0 +1,99 @@
+#include "SCT_PWM.h"
+
+#define BIT_ON(A) (1<<A)
+
+// http://www.lpcware.com/content/nxpfile/lpc80-sct-cookbook-and-tutorial-code-examples
+
+SCT_PWM::SCT_PWM(int pin, int channel) : ch(channel)
+{
+    static bool insted = false;
+
+    if (!insted) {
+        inst();
+        insted = true;
+    }
+    swm(pin);
+
+    LPC_SCT->EVENT[ch + 1].STATE = LPC_SCT->EVENT[0].STATE;
+    LPC_SCT->EVENT[ch + 1].CTRL = LPC_SCT->EVENT[0].CTRL | (ch+1)<<0; // match 1...5
+
+    LPC_SCT->OUT[ch].SET = BIT_ON(0); // event 0
+    LPC_SCT->OUT[ch].CLR = BIT_ON(ch+1); // event 1...5
+}
+
+void SCT_PWM::inst()
+{
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<8); // enable SCT
+    LPC_SYSCON->PRESETCTRL |= (1<<8); // reset SCT
+
+    LPC_SCT->EVENT[0].STATE = BIT_ON(0); // state 0
+    LPC_SCT->EVENT[0].CTRL = (1<<12) | (1<<14);
+
+    LPC_SCT->LIMIT_L |= BIT_ON(0); // event 0
+
+    LPC_SCT->CONFIG |= (1<<0) | (1<<17); // unify, auto limit
+    LPC_SCT->CTRL_L |= (SystemCoreClock/1000000-1)<<5; // set prescaler, SCT clock = 1 MHz
+
+    LPC_SCT->CTRL_L &= ~(1<<2); // unhalt it by clearing bit 2 of CTRL reg
+}
+
+void SCT_PWM::swm(int pin)
+{
+    switch(ch) {
+        case 0: // CTOUT_0
+            LPC_SWM->PINASSIGN6 = (LPC_SWM->PINASSIGN6 & 0x00ffffff) | pin<<24;
+            break;
+        case 1: // CTOUT_1
+            LPC_SWM->PINASSIGN7 = (LPC_SWM->PINASSIGN7 & 0xffffff00) | pin<<0;
+            break;
+        case 2: // CTOUT_2
+            LPC_SWM->PINASSIGN7 = (LPC_SWM->PINASSIGN7 & 0xffff00ff) | pin<<8;
+            break;
+        case 3: // CTOUT_3
+            LPC_SWM->PINASSIGN7 = (LPC_SWM->PINASSIGN7 & 0xff00ffff) | pin<<16;
+            break;
+    }
+}
+
+void SCT_PWM::period(float seconds)
+{
+    period_us(seconds * 1000000);
+}
+
+void SCT_PWM::period_ms(int ms)
+{
+    period_us(ms * 1000);
+}
+
+void SCT_PWM::period_us(int us)
+{
+    LPC_SCT->MATCHREL[0].U = us - 1;
+}
+
+void SCT_PWM::pulsewidth(float seconds)
+{
+    pulsewidth_us(seconds * 1000000);
+}
+
+void SCT_PWM::pulsewidth_ms(int ms)
+{
+    pulsewidth_us(ms * 1000);
+}
+
+void SCT_PWM::pulsewidth_us(int us)
+{
+    LPC_SCT->MATCHREL[ch + 1].U = us;
+}
+
+void SCT_PWM::write(float value)
+{
+    LPC_SCT->MATCHREL[ch + 1].U = value * LPC_SCT->MATCHREL[0].U;
+}
+
+float SCT_PWM::read()
+{
+    if (LPC_SCT->MATCHREL[0].U == 0) {
+        return 0.0;
+    }
+    return (float)LPC_SCT->MATCHREL[ch + 1].U / LPC_SCT->MATCHREL[0].U;
+}
diff -r f86c572491c3 -r 4e19f154ec21 SCT_PWM.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SCT_PWM.h	Mon Oct 14 03:59:30 2013 +0000
@@ -0,0 +1,30 @@
+#pragma once
+#include "LPC8xx.h"
+
+class SCT_PWM {
+public:
+    SCT_PWM(int pin = 7, int channel = 0);
+    void period(float seconds);
+    void period_ms(int ms);
+    void period_us(int us);
+    void pulsewidth(float seconds);
+    void pulsewidth_ms(int ms);
+    void pulsewidth_us(int us);
+    void write(float value);
+    float read();
+    void swm(int pin = 7);
+
+    SCT_PWM& operator= (float value) {
+        write(value);
+        return *this;
+    }
+
+    SCT_PWM& operator= (SCT_PWM& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+protected:
+    void inst();
+    int ch;
+};
diff -r f86c572491c3 -r 4e19f154ec21 main.cpp
--- a/main.cpp	Mon Oct 15 12:19:12 2012 +0000
+++ b/main.cpp	Mon Oct 14 03:59:30 2013 +0000
@@ -1,3 +1,29 @@
+#ifdef TARGET_LPC812
+#include "mbed.h"
+#include "SCT_PWM.h"
+#include "MRT.h"
+
+SCT_PWM r (LED_RED, 0);
+SCT_PWM g (LED_GREEN, 1);
+SCT_PWM b (LED_BLUE, 2);
+
+int main()
+{
+    MRT* mrt = new MRT();
+    r.period(0.001);
+    while(1) {
+        for(float i = 0.0; i < 1.0 ; i += 0.001) {
+            float p = 3 * i;
+            r = 1.0 - ((p < 1.0) ? 1.0 - p : (p > 2.0) ? p - 2.0 : 0.0);
+            g = 1.0 - ((p < 1.0) ? p : (p > 2.0) ? 0.0 : 2.0 - p);
+            b = 1.0 - ((p < 1.0) ? 0.0 : (p > 2.0) ? 3.0 - p : p - 1.0);  ;  
+            mrt->wait_ms(10);
+        }
+    }
+}
+
+#else
+// http://mbed.org/users/chris/code/app-board-RGB/
 #include "mbed.h"
 
 PwmOut r (p23);
@@ -16,4 +42,5 @@
             wait (0.01);
         }
     }
-}
\ No newline at end of file
+}
+#endif
diff -r f86c572491c3 -r 4e19f154ec21 mbed.bld
--- a/mbed.bld	Mon Oct 15 12:19:12 2012 +0000
+++ b/mbed.bld	Mon Oct 14 03:59:30 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/cd19af002ccc
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file