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, committed 2012-03-01
- Comitter:
- okini3939
- Date:
- Thu Mar 01 01:40:07 2012 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 41b699bbda83 ChaNFS.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ChaNFS.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/NeoBelerophon/code/ChaNFS/#8ea634413549
diff -r 000000000000 -r 41b699bbda83 ChaNFSSD.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ChaNFSSD.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/NeoBelerophon/code/ChaNFSSD/#7532f4c4163c
diff -r 000000000000 -r 41b699bbda83 ConfigFile.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ConfigFile.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
diff -r 000000000000 -r 41b699bbda83 DMX.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DMX.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/okini3939/code/DMX/#7826eb77d9ea
diff -r 000000000000 -r 41b699bbda83 DmxArtNet.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DmxArtNet.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/okini3939/code/DmxArtNet/#c59dc374fc64
diff -r 000000000000 -r 41b699bbda83 EthernetNetIf.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetNetIf.lib Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
diff -r 000000000000 -r 41b699bbda83 NEC950MHz.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NEC950MHz.cpp Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,114 @@ +/* + * NEC 950MHz RF module + * H001-000003-001 + */ + +#include "mbed.h" +#include "NEC950MHz.h" +#include "dbg.h" +#include <string.h> + +#define RXD p10 +#define TXD p9 +#define RST p12 + + +// host to network short +#define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) ) +#define ntohs( x ) htons(x) +// host to network long +#define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \ + | (( (x) << 8 ) & 0x00FF0000) \ + | (( (x) >> 8 ) & 0x0000FF00) \ + | (( (x) >> 24 ) & 0x000000FF) ) +#define ntohl( x ) htonl(x) + + +static Serial rf(TXD, RXD); +static DigitalOut rst(RST); + +int send_rf (int msgid, unsigned long dest, char *param, int len) { + int i; + static int msgno = 0; + struct ifMessage ifmsg; + unsigned char *buf = (unsigned char *)&ifmsg; + + if (len > 240) len = 240; + msgno ++; + ifmsg.start = htons(0x0f5a); + ifmsg.length = 13 + len; + ifmsg.msgid = msgid; + ifmsg.msgno = msgno; + ifmsg.dstid = htonl(dest); + ifmsg.srcid = htonl(0xffffffff); + memcpy(ifmsg.parameter, param, len); + DBG("send_rf %d / %d\r\n", ifmsg.length, len); + + for (i = 0; i < ifmsg.length; i ++) { + rf.putc(buf[i]); + } + + return ifmsg.msgno; +} + +int read_rf (struct ifMessage *ifmsg) { + Timer timeout; + int i = 0, len = 0; + unsigned char buf[sizeof(struct ifMessage)]; + + timeout.start(); + while (timeout.read_ms() < TIMEOUT) { + if (rf.readable()) { + buf[i] = rf.getc(); + if (i == 0 && buf[i] == 0x0f) { + i ++; + } else + if (i == 1 && buf[i] == 0x5a) { + i ++; + } else + if (i == 2) { + len = buf[i]; + i ++; + } else + if (i >= 3) { + i ++; + if (i >= len || i >= sizeof(buf)) break; + } + timeout.reset(); + } + } + timeout.stop(); + + if (len) { + DBG("read_rf %d / %d\r\n", i, len); + memcpy(ifmsg, buf, len); + } + return len; +} + +int init_rf (int ch) { + int no; + struct ifMessage ifmsg; + // high power, 100kbps, retry 0 + char rfconf[] = {POWER_HIGH, ch, BAUD_100k, 1, 0, UART_115200, 1, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x83, 0x41}; + + rf.baud(38400); + + rst = 0; // reset + wait_ms(50); + rst = 1; + wait_ms(100); + + no = send_rf(MSGID_WRITE_CONFIG, 0xffffffff, rfconf, sizeof(rfconf)); + DBG("rfconf %d\r\n", no); + // responce + if (! read_rf(&ifmsg) || ifmsg.msgid != MSGID_ACK || ifmsg.msgno != no) { + return -1; + } + + rf.baud(115200); + + return 0; +}
diff -r 000000000000 -r 41b699bbda83 NEC950MHz.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NEC950MHz.h Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,55 @@ +/* + * NEC 950MHz RF module + * H001-000003-001 + */ + +#include <inttypes.h> + +//#define CH 17 // 17-31 +#define TIMEOUT 10 // ms + +#define MSGID_ACK 0x00 +#define MSGID_NOACK 0x01 +#define MSGID_SEARCH 0x10 +#define MSGID_SEND_DAT 0x11 +#define MSGID_RESEND 0x12 +#define MSGID_SEND_NOACK 0x13 +#define MSGID_ENERGY_DETECT 0x16 +#define MSGID_SEND_CMD 0x17 +#define MSGID_WRITE_RFCONF 0x21 +#define MSGID_READ_RSSI 0x24 +#define MSGID_READ_CONFIG 0x29 +#define MSGID_WRITE_CONFIG 0x2A +#define MSGID_READ_DEFAULT 0x7D +#define MSGID_WRITE_DEFAULT 0x7E +#define MSGID_RESET 0x77 + +#define POWER_LOW 0x00 +#define POWER_MID 0x01 +#define POWER_HIGH 0x02 + +#define BAUD_9600 0x02 +#define BAUD_50k 0x06 +#define BAUD_100k 0x07 + +#define UART_4800 0x01 +#define UART_9600 0x02 +#define UART_19200 0x04 +#define UART_38400 0x05 +#define UART_56700 0x06 +#define UART_115200 0x08 + +struct ifMessage { + uint16_t start; + uint8_t length; + uint8_t msgid; + uint8_t msgno; + uint32_t dstid; + uint32_t srcid; + uint8_t parameter[242]; +} __attribute__((packed)); + + +int send_rf (int msgid, unsigned long dest, char *param, int len); +int read_rf (struct ifMessage *ifmsg); +int init_rf (int ch);
diff -r 000000000000 -r 41b699bbda83 dbg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbg.h Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,7 @@ +//#define DEBUG + +#ifdef DEBUG +#define DBG(...) printf("" __VA_ARGS__) +#else +#define DBG(...) +#endif
diff -r 000000000000 -r 41b699bbda83 dmx_patch.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmx_patch.cpp Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,132 @@ +/* + * DMX Station - mbed DMX Platform + * Copyright (c) 2012 Hiroshi Suga + * Released under the MIT License: http://mbed.org/license/mit + */ + +/* + * "patch#.csv" (#=dest port) + * |dest ch,src port,src ch| + * + * dest port: 1=dmx out 1 / 2=dmx out 2 / 3=ArtNet 1 / 4=ArtNet 2 / 5=RF(NEC950MHz) + * src port: 1=dmx in 1 / 2=dmx in 2 / 3=ArtNet 1 / 4=ArtNet 2 / 5=UDP2DMX + */ +#include "dbg.h" +#include "mbed.h" +#include "SDFileSystem.h" +#include "DmxArtNet.h" +#include "DMX.h" +#include "dmx_patch.h" + + +SDFileSystem sd(p5, p6, p7, p8, "sd"); + +struct TPatch dmx_patch[DEST_NUM][512] __attribute__((section("AHBSRAM0"))); + +extern DmxArtNet art; +extern DMX dmx1; +extern DMX dmx2; + +extern volatile int patch_update; +extern volatile int art_update[2]; +extern volatile int rf_update; +extern char dmx_art[2][512]; +extern char dmx_udp[512]; +extern char dmx_rf[512]; + + +int load_patch () { + int i, j, dest, src, port; + FILE *fp; + char file[32]; + + for (i = 0; i < DEST_NUM; i ++) { + for (j = 0; j < 512; j ++) { + dmx_patch[i][j].port = i < 2 ? i + 2 : i - 2; + dmx_patch[i][j].addr = j; + } + } + + if (sd.disk_initialize()) { + DBG("no SD\r\n"); + return -1; + } + + for (i = 0; i < DEST_NUM; i ++) { + sprintf(file, "/sd/patch%d.csv", i + 1); + fp = fopen(file, "r"); + if (! fp) continue; + + while (1) { + // load csv + if (feof(fp)) break; + if (fscanf(fp, "%d,%d,%d", &dest, &port, &src) == 3) { + if (dest < 1 && dest > 512) continue; + if (src < 1 && src > 512) continue; + if (port < 1 && port > 5) continue; + dmx_patch[i][dest - 1].port = port - 1; + dmx_patch[i][dest - 1].addr = src - 1; + DBG("%d %d <- %d %d\r\n", i + 1, dest, port, src); + } + } + fclose(fp); + } + return 0; +} + +void patch () { + int i, j, dmx; + + for (i = 0; i < DEST_NUM; i ++) { + for (j = 0; j < 512; j ++) { + // src + switch (dmx_patch[i][j].port) { + case 0: // dmx in 1 + dmx = dmx1.get(dmx_patch[i][j].addr); + break; + case 1: // dmx in 2 + dmx = dmx2.get(dmx_patch[i][j].addr); + break; + case 2: // ArtNet 1 + dmx = art.DmxIn[0][dmx_patch[i][j].addr]; + break; + case 3: // ArtNet 2 + dmx = art.DmxIn[1][dmx_patch[i][j].addr]; + break; + case 4: // UDP2DMX + dmx = dmx_udp[dmx_patch[i][j].addr]; + break; + default: + continue; + } + + // dest + switch (i) { + case 0: // dmx out 1 + dmx1.put(j, dmx); + break; + case 1: // dmx out 2 + dmx2.put(j, dmx); + break; + case 2: // ArtNet 1 + if (dmx_art[0][j] != dmx) { + dmx_art[0][j] = dmx; + art_update[0] = 1; + } + break; + case 3: // ArtNet 2 + if (dmx_art[1][j] != dmx) { + dmx_art[1][j] = dmx; + art_update[1] = 1; + } + break; + case 4: // RF(NEC950MHz) + if (dmx_rf[j] != dmx) { + dmx_rf[j] = dmx; + rf_update = 1; + } + break; + } + } + } +}
diff -r 000000000000 -r 41b699bbda83 dmx_patch.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmx_patch.h Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,25 @@ +/* + * DMX Station - mbed DMX Platform + * Copyright (c) 2012 Hiroshi Suga + * Released under the MIT License: http://mbed.org/license/mit + */ + +#define DEST_NUM 5 +#define SRC_NUM 5 +/* +#define DMX0 1 +#define DMX1 2 +#define ARTNET0 3 +#define ARTNET1 4 +#define RF 5 +#define CV2DMX 5 +*/ +struct TPatch { + short port; + short addr; +}; + + +int load_patch (); +void patch (); +
diff -r 000000000000 -r 41b699bbda83 main.cpp --- /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; + } + } +} +
diff -r 000000000000 -r 41b699bbda83 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 01 01:40:07 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4c0c40fd0593