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...
unilynx.cpp
- Committer:
- morten_opprud
- Date:
- 2012-08-27
- Revision:
- 0:66a099b01e08
- Child:
- 1:df4e9da66448
File content as of revision 0:66a099b01e08:
/** * <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"); }