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...
Diff: unilynx.cpp
- 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