implementation of parts of the unilynx protocol, for communicating with danfos photovoltaic inverters. Still BETA ! needs byte stuff/unstuff fixed, and some CRC are left out for niw...

Dependencies:   mbed

Revision:
0:66a099b01e08
Child:
1:df4e9da66448
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unilynx.cpp	Mon Aug 27 18:30:37 2012 +0000
@@ -0,0 +1,253 @@
+/**
+* <describing text>
+*
+* @file     commlynx_protocol.c.c
+* @ingroup <>
+*
+* @author     MortenOJ
+* @date     Aug 24, 2012
+*
+*/
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include "mbed.h"
+#include "unilynx.h"
+#include "crc.h"
+
+#define DEBUG
+
+Serial rs485(p26, p25);
+Serial pc(USBTX, USBRX);
+
+
+// Telegram format
+//----------------------------------------------------------------------------------------------------
+//      Start of frame         /              Header                   /   Data     / End of frame
+//  Start  / Address / Control / Source  / Destination / Size  / Type  /   Data     /  FCS   / Stop
+//  1byte  / 1byte   / 1byte   / 2bytes  /   2bytes   /  1byte / 1byte / 0-255bytes / 2bytes / 1byte
+//----------------------------------------------------------------------------------------------------
+//unsigned char txStr[255];
+
+#define MY_ADDR0        0x28
+#define MY_ADDR1        0xD7
+
+#define FRAME_START        0x7E
+#define FRAME_STOP        0x7E
+#define FRAME_ADDRESS    0xFF
+#define FRAME_CONTROL    0x03
+
+#define PPPINITFCS16 0xFFFF /* Initial FCS value */
+#define PPPGOODFCS16 0xf0b8 /* Good final FCS value */
+
+const unsigned char pingAllStr[12] =
+{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0xFF, 0xFF, 0x00, 0x15, 0xB1, 0x8B, 0x7E };
+
+
+
+/*const char getNodeReqStr[41] =
+{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0x12, 0x03, 0x1D, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xC9, 0x35, 0x7E };
+*/
+/*
+const char getNodeReqStr[41] =
+{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0x12, 0x03, 0x1D, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xC9, 0x35, 0x7E };
+*/
+
+char pingAllStrWoCrc[12] =
+{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0xFF, 0xFF, 0x00, 0x15, 0, 0, 0x7E };
+//{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0x12, 0x03, 0x00, 0x15, 0, 0, 0x7E };
+/* func code 0x13*/
+
+char getNodeReqStrWoCrc[41] = {
+    0x7E, 0xFF, 0x03, 0x00, 0x02, 0x28, 0xD7, 0x1D, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0x00, 0x00, 0x7E
+};
+
+char getNodeParamStrWoCrc[41] =
+{ 0x7E, 0xFF, 0x03, 0x00, 0x02, 0x28, 0xD7, 0x0A, 0x01, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E };
+
+
+char tx[40];
+
+void rs485init(void)
+{
+    rs485.baud(19200);
+    pc.baud(115200);
+
+    LPC_PINCON->PINSEL4 &= 0x0ffff;
+    LPC_PINCON->PINSEL4 |= 0x0AAAA;
+
+    LPC_UART1->RS485DLY = 128;
+
+    LPC_UART1->RS485CTRL   &=~(1<<1);       //Receiver enabled
+    LPC_UART1->RS485CTRL   &=~(1<<2);       //AAD disabled
+    LPC_UART1->RS485CTRL   |= (1<<3);       //DTR used for direction control
+    LPC_UART1->RS485CTRL   |= (1<<4);       //direction control enabled
+    LPC_UART1->RS485CTRL   |= (1<<5);       //DTR=1 when transmitting
+}
+
+void rs485write(char* str, int len)
+{
+    int i;
+    i=0;
+    while(i < len)
+    {
+        rs485.putc(*(str +i));
+        i++;
+    }
+#ifdef DEBUG2
+    i=0;   
+    pc.printf("TX:");
+    while(i < len)
+    {
+        pc.putc(*(str +i));
+        i++;
+    }
+#endif
+}
+
+static void rs485read(char* str, int len)
+{
+    int i;
+    i=0;
+    while(i < len) {
+        (*(str +i)) = rs485.getc();
+        i++;
+        //TODO add timeout
+    }
+#ifdef DEBUG
+    i=0;
+    pc.printf("RX:");
+    while(i < len)
+    {
+        pc.putc(*(str +i));
+        i++;
+    }
+#endif
+
+}
+
+void getNodeInfo(void)
+{
+    /* data of interest TODO MAKE GLOBAL AVAILIBLE */
+    char network, subnet, address;
+
+    /*local variables*/
+    char rx[42];
+    short fcs;
+    /* fill in address */
+    getNodeReqStrWoCrc[5] = MY_ADDR0;
+    getNodeReqStrWoCrc[6] = MY_ADDR1;
+    /* calculate CRC and fill in string */
+    fcs = pppfcs16( PPPINITFCS16, &getNodeReqStrWoCrc[1], 37 );
+    fcs ^= 0xFFFF;
+    getNodeReqStrWoCrc[38] = (unsigned char)(fcs & 0xFF);
+    getNodeReqStrWoCrc[39] = (unsigned char)((fcs>>8) & 0xFF);
+    /* send request */
+    rs485write(getNodeReqStrWoCrc,41);
+    /* retrieve response */
+    rs485read(rx,41);
+    /* extract data*/
+    network = rx[33];
+    subnet  = rx[34];
+    address = rx[35];
+    
+    //pc.printf("Network: %X Subnet: %X Address: %X",network,subnet, address);
+}
+
+void readParameter(int param_idx, int param_sub_idx)
+{
+	short fcs;
+	char rx[24];
+	char flags;
+
+	/* fill in address */
+	getNodeParamStrWoCrc[5] = MY_ADDR0;
+	getNodeParamStrWoCrc[6] = MY_ADDR1;
+
+	getNodeParamStrWoCrc[10] = 0x04;//0D;//dest;
+	getNodeParamStrWoCrc[11] = 0xD0;//((source<<4) | page);
+	getNodeParamStrWoCrc[12] = (param_idx);
+	getNodeParamStrWoCrc[13] = (param_sub_idx);
+	getNodeParamStrWoCrc[14] = 0x80;//	we want reply (DO_REPLY | IM_REQUEST | TYPE_U16);
+	getNodeParamStrWoCrc[15] = 0;
+	getNodeParamStrWoCrc[16] = 0;
+	getNodeParamStrWoCrc[17] = 0;
+	getNodeParamStrWoCrc[18] = 0;
+
+	/* calculate VRC and fill in string */
+	fcs = pppfcs16( PPPINITFCS16, &getNodeParamStrWoCrc[1], 18 );
+	fcs ^= 0xFFFF;
+	getNodeParamStrWoCrc[19] = (unsigned char)(fcs & 0xFF);
+	getNodeParamStrWoCrc[20] = (unsigned char)((fcs>>8) & 0xFF);
+
+	/* send request */
+	rs485write(getNodeParamStrWoCrc,22);
+	/* retrieve response */
+	rs485read(rx,22);
+	/* extract data*/
+	flags = rx[14];
+	
+	switch (flags & 0x0F)
+	{
+		case 0x07:	//U32
+			pc.printf("VAl: %d %d %d %d",rx[15],rx[16],rx[17],rx[18]);
+		break;
+		default:
+			pc.printf("Flags: %X" ,rx[14]);
+		break;
+	}
+}
+
+
+void test(void)
+{
+    //pc.baud(19200);
+
+    while(1) {
+        if(pc.readable())
+            rs485.putc(pc.getc());
+
+        if(rs485.readable())
+            pc.putc(rs485.getc());
+    }
+}
+
+void ping(void)
+{
+    int rxcnt = 0;
+    char rx[14];
+    short fcs;
+
+    for(int i=0; i < 12; i++) {
+        rs485.putc(pingAllStr[i]);
+//        pc.putc(pingAllStr[i]);
+    }
+    while(1) {
+        if(rs485.readable()) {
+            rx[rxcnt++] = rs485.getc();
+//            pc.putc(rx[rxcnt]);
+        }
+        /* reached stop 0x7E ? todo, timeout & CRC*/
+        if( rxcnt > 10)
+            if(rx[rxcnt] == 0x7E)
+                break;
+
+        if( rxcnt == 11)
+            break;
+    }
+
+    for(int i=0; i < 12; i++) {
+        pc.putc(pingAllStr[i]);
+    }
+    for(int i=0; i < 12; i++) {
+        pc.putc(rx[i]);
+    }
+
+    pc.printf("Done");
+}
\ No newline at end of file