DALI send/recv library.

Dependents:   dali_sample

DALI send/recv library

lighting control protocol.

設備照明の調光プロトコル DALI を送受信するライブラリです。

DALI インターフェースの回路図などは次を参照。

Revision:
1:319d52b5116b
Parent:
0:6cb7026982fc
--- a/DALI.cpp	Wed Jul 22 03:04:04 2020 +0000
+++ b/DALI.cpp	Mon Jul 27 05:53:55 2020 +0000
@@ -13,11 +13,11 @@
 
 #define BUFFER_SIZE 20
 
-#define TIME_BITTIME 833 // us, 1200bps
-#define TIME_BITTIME1p2 417 // us, 1200bps 3/4
+#define TIME_BITTIME    833 // us, 1200bps
+#define TIME_BITTIME1p2 417 // us, 1200bps 1/2
 #define TIME_BITTIME3p4 625 // us, 1200bps 3/4
+#define TIME_BETWEEN    10000 // us >22Te
 
-extern Serial pc;
 
 DALI::DALI (PinName tx, PinName rx) : _tx(tx), _rx(rx) {
     _rx.mode(PullUp);
@@ -39,22 +39,22 @@
 
     if (recv_buf->dequeue(&dat)) {
         if (dat & (1<<16)) {
-            *frame = DALI_BACKWARD;
+            *frame = BACKWARD;
             *value = dat & 0xff;
         } else {
             if (dat & (1<<15)) {
                 // group
                 if (dat & (1<<8)) {
-                    *frame = DALI_FORWARD_GROUP_IAP;
+                    *frame = FORWARD_GROUP_IAP;
                 } else {
-                    *frame = DALI_FORWARD_GROUP_DAP;
+                    *frame = FORWARD_GROUP_DAP;
                 }
             } else {
                 // short
                 if (dat & (1<<8)) {
-                    *frame = DALI_FORWARD_SHORT_IAP;
+                    *frame = FORWARD_SHORT_IAP;
                 } else {
-                    *frame = DALI_FORWARD_SHORT_DAP;
+                    *frame = FORWARD_SHORT_DAP;
                 }
             }
             *addr = (dat >> 9) & 0x3f;
@@ -71,6 +71,21 @@
 
 void DALI::isr_send () {
 
+    if (! busy) {
+        if (mode) return; // recv working
+
+        _ticker.detach();
+        // next data
+        int dat, bit;
+        busy = 1;
+        send_buf->dequeue(&dat);
+        bit = (dat >> 20) & 0x0fff;
+        send_bit = (1 << bit) << 2;
+        send_data = dat & 0x0fffff;
+        halfbit = 0;
+        _ticker.attach_us(this, &DALI::isr_send, TIME_BITTIME1p2);
+    }
+
     if (send_bit & 3) {
         // stop bit
         _tx = 0;
@@ -88,18 +103,12 @@
         send_bit >>= 1;
 
         if (send_bit == 0) {
-            if (send_buf->isEmpty()) {
-                // end
-                _ticker.detach();
-                busy = 0;
-            } else {
-                // next
-                int dat, bit;
-                send_buf->dequeue(&dat);
-                bit = (dat >> 20) & 0x0fff;
-                send_bit = (1 << bit) << 2;
-                send_data = dat & 0x0fffff;
-                halfbit = 0;
+            // end of data
+            _ticker.detach();
+            busy = 0;
+            if (! send_buf->isEmpty()) {
+                // next data
+                _ticker.attach_us(this, &DALI::isr_send, TIME_BETWEEN);
             }
         }
     } else {
@@ -107,33 +116,35 @@
     }
 }
 
+int DALI::writable () {
+    return ! send_buf->isFull();
+}
+
 int DALI::write (enum DALI_FRAME frame, int addr, int value) {
     int dat, bit;
 
-    while ((volatile int)send_bit);
-
     switch (frame) {
-    case DALI_FORWARD_SHORT_DAP:
+    case FORWARD_SHORT_DAP:
         dat = (0<<15) | ((addr & 0x3f) << 9) | (0<<8) | (value & 0xff);
         bit = 16;
         break;
 
-    case DALI_FORWARD_SHORT_IAP:
+    case FORWARD_SHORT_IAP:
         dat = (0<<15) | ((addr & 0x3f) << 9) | (1<<8) | (value & 0xff);
         bit = 16;
         break;
 
-    case DALI_FORWARD_GROUP_DAP:
+    case FORWARD_GROUP_DAP:
         dat = (1<<15) | ((addr & 0x3f) << 9) | (0<<8) | (value & 0xff);
         bit = 16;
         break;
 
-    case DALI_FORWARD_GROUP_IAP:
+    case FORWARD_GROUP_IAP:
         dat = (1<<15) | ((addr & 0x3f) << 9) | (1<<8) | (value & 0xff);
         bit = 16;
         break;
 
-    case DALI_BACKWARD:
+    case BACKWARD:
         dat = (value & 0xff);
         bit = 8;
         break;
@@ -147,6 +158,8 @@
     send_buf->queue(dat);
 
     if (! busy) {
+        while (mode); // wait recv
+        // begin data
         busy = 1;
         send_buf->dequeue(&dat);
         bit = (dat >> 20) & 0x0fff;