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
Diff: main.cpp
- 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; + } + } +} +