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

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");
}