DMX interface (DMX in/out, Art-Net in/out, DMX patch) http://mbed.org/users/okini3939/notebook/dmx-platform/

Dependencies:   ChaNFSSD EthernetNetIf mbed ConfigFile ChaNFS DmxArtNet

Revision:
0:41b699bbda83
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 01 01:40:07 2012 +0000
@@ -0,0 +1,253 @@
+/*
+ * DMX Station - mbed DMX Platform
+ * Copyright (c) 2012 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief DMX Station
+ */
+
+/*
+ * "Node" Device
+ * "Universe" 512 DMX datas
+ * "Sub-Net" 16 Universe
+ * "Server" Controller
+ *
+ * can use over 40 Sub-Net on network.
+ */
+
+#include "dbg.h"
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "DmxArtNet.h"
+#include "DMX.h"
+#include "NEC950MHz.h"
+#include "dmx_patch.h"
+
+#define LED_NET_ACT_ON led_yk = 0
+#define LED_NET_ACT_OFF led_yk = 1
+#define LED_NET_G_ON led_gayk = 1; led_gkya = 0
+#define LED_NET_Y_ON led_gayk = 0; led_gkya = 1
+#define LED_NET_GY_OFF led_gayk = 0; led_gkya = 0
+
+// for Touchable Fountains (Juco)
+#define UDP_PORT 10465
+#define RF_CH 31
+
+DigitalOut led_red(p22), led_yellow(p23);
+DigitalOut led_gayk(p24),led_gkya(p25), led_yk(p26);
+DigitalIn eth_link(P1_25), eth_speed(P1_26);
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+EthernetNetIf *eth;
+Serial pc(USBTX, USBRX);
+
+DmxArtNet art;
+DMX dmx1(p13, p14);
+DMX dmx2(p28, p27);
+
+UDPSocket udp;
+
+volatile int patch_update = 0;
+volatile int art_update[2] = {0, 0};
+volatile int rf_update = 0, rf_flg = 0;
+char dmx_art[2][512] __attribute__((section("AHBSRAM0")));
+char dmx_udp[512] __attribute__((section("AHBSRAM0")));
+char dmx_rf[512] __attribute__((section("AHBSRAM0")));
+
+
+extern "C" void mbed_mac_address(char *s);
+
+void no_memory () {
+    led_red = 1;
+    printf("panic: can't allocate to memory!\r\n");
+    exit(-1);
+}
+
+void shutdown () {
+    art.ArtPollReply.NumPorts = 0;
+    strcpy(art.ArtPollReply.NodeReport, "Shutdown");
+    art.SendArtPollReply();
+    art.Done();
+}
+
+void isr_udp (UDPSocketEvent e) {
+    int len;
+    Host remote;
+
+    if (e == UDPSOCKET_READABLE) {
+        // UDP2DMX
+        LED_NET_ACT_ON;
+        led_yellow = 1;
+        led3 = 1;
+        len = udp.recvfrom((char*)dmx_udp, sizeof(dmx_udp), &remote);
+        DBG("recv udp %d\r\n", len);
+        patch_update = 5;
+    }
+}
+
+void isr_timer () {
+    led_yellow = 0;
+    LED_NET_ACT_OFF;
+    led1 = 0; led2 = 0; led3 = 0; led4 = 0;
+}
+
+int init_artnet (IpAddr *ip) {
+    char mac[6];
+    EthernetErr ethErr;
+
+    eth_link.mode(PullUp);
+    eth_speed.mode(PullUp);
+
+    if (! eth_link) {
+        LED_NET_G_ON;
+    }
+    LED_NET_ACT_ON;
+
+    // create ip address from mac address
+    mbed_mac_address(mac);
+    *ip = IpAddr(2, mac[3], mac[4], mac[5]);
+    eth = new EthernetNetIf(*ip, IpAddr(255,0,0,0), IpAddr(0,0,0,0), IpAddr(0,0,0,0));
+    ethErr = eth->setup();
+    if (ethErr) {
+        LED_NET_Y_ON;
+        led_red = 1;
+        return -1;
+    }
+
+    wait(2);
+
+    // init ArtNet
+    art.BindIpAddress = *ip;
+    art.BCastAddress = IpAddr(2,255,255,255);
+
+    art.InitArtPollReplyDefaults();
+    // Device
+    art.ArtPollReply.PortType[0] = 128; // output
+    art.ArtPollReply.PortType[1] = 128; // output
+    art.ArtPollReply.PortType[2] = 64; // input
+    art.ArtPollReply.GoodInput[2] = 4;
+    art.ArtPollReply.PortType[3] = 64; // input
+    art.ArtPollReply.GoodInput[3] = 4;
+
+    art.Init();
+    art.SendArtPollReply(); // announce to art-net nodes
+
+    pc.printf("init ArtNet\r\n");
+    return 0;
+}
+
+int main () {
+    int i;
+    Ticker timer;
+    ifMessage ifmsg;
+    IpAddr ip;
+    UDPSocketErr udpErr;
+
+    set_new_handler(no_memory); // new handler function
+
+    pc.baud(112500);
+    
+    memset(dmx_art, 0, sizeof(dmx_art));
+    memset(dmx_udp, 0, sizeof(dmx_udp));
+    memset(dmx_rf, 0, sizeof(dmx_rf));
+
+    load_patch();
+    timer.attach(&isr_timer, 0.1);
+
+    // init ArtNet
+    if (init_artnet(&ip)) return -1;
+    pc.printf("Bind to interface: %d.%d.%d.%d\r\n", (unsigned char)ip[0], (unsigned char)ip[1], (unsigned char)ip[2], (unsigned char)ip[3]);
+
+    // init UDP2DMX
+    udpErr = udp.bind(Host(ip, UDP_PORT, NULL));
+    if (udpErr) {
+        pc.printf("Bind error (udp2dmx)\r\n");
+        return -1;
+    }
+    udp.setOnEvent(&isr_udp);
+    pc.printf("init UDP2DMX\r\n");
+
+    // init NEC950MHz
+    if (! init_rf(RF_CH)) {
+        pc.printf("init RF\r\n");
+    }
+
+    pc.printf("ArtNode begin\r\n");
+
+    for (;;) {
+        Net::poll();
+
+        if (! eth_link) {
+            LED_NET_G_ON;
+        } else {
+            LED_NET_GY_OFF;
+        }
+
+        if (dmx1.is_recived) {
+            // dmx in 1
+            LED_NET_ACT_ON;
+            led_yellow = 1;
+            led1 = 1;
+            patch_update = 1;
+            dmx1.is_recived = 1;
+            DBG("recv, dmx 1\r\n");
+        }
+
+        if (dmx2.is_recived) {
+            // dmx in 2
+            LED_NET_ACT_ON;
+            led_yellow = 1;
+            led1 = 1;
+            patch_update = 2;
+            dmx2.is_recived = 2;
+            DBG("recv, dmx 2\r\n");
+        }
+
+        if (art.Work()) {
+            // ArtNet
+            LED_NET_ACT_ON;
+            led_yellow = 1;
+            led2 = 1;
+            patch_update = art.LastRecievedUniverse + 3;
+            DBG("recv, node %d\r\n", art.LastRecievedUniverse + 1);
+        }
+
+        if (patch_update) {
+            // update DMX patch
+            led4 = 1;
+            patch();
+            DBG("update");
+        
+            for (i = 0; i < 2; i ++) {
+                // ArtNet good status
+                if (art_update[i]) {
+                    DBG("art good");
+                    Net::poll();
+                    art.ArtPollReply.GoodInput[i] = 128;
+                    art.Send_ArtDmx(i, 0, dmx_art[i], 512);
+                    art_update[i] = 0;
+                }
+            }
+
+            if (! rf_flg && rf_update) {
+                // RF send
+                send_rf(MSGID_SEND_NOACK, 0xffffffff, dmx_rf, 200);
+                rf_flg = 1;
+                rf_update = 0;
+            }
+
+            patch_update = 0;
+        }
+
+        if (rf_flg && read_rf(&ifmsg) > 0) {
+            // RF responce
+            DBG("recv %d\r\n", ifmsg.msgid);
+            if (ifmsg.msgid != MSGID_ACK) {
+                DBG("no ack\r\n");
+            }
+            rf_flg = 0;
+        }
+    }
+}
+