https://www.st.com/en/ecosystems/x-nucleo-plm01a1.html MBED driver for the ST7580 IC.

ST7580.cpp

Committer:
Arthrik
Date:
2019-04-20
Revision:
1:edbcde816013
Parent:
0:e88514a784bb

File content as of revision 1:edbcde816013:

#include "ST7580.h"

ST7580::ST7580(PinName tx, PinName rx, PinName t_req, PinName reset, void (*usr_callback)(unsigned char *, int))
{
    this->_rcv_data_idx = 0;
    this->_rcv_data_offset = 0;
    this->_rcv_payload_len = 255;
    
    _plm_t_req = new DigitalOut(t_req);
    _plm_reset = new DigitalOut(reset);
    
    _plm_uart = new RawSerial(tx, rx);
    _plm_uart->baud(57600);
    _plm_uart->format();                  //8N1
    _plm_uart->attach(callback(this, &ST7580::rx_callback));

    _usr_callback = usr_callback;
}

void ST7580::init()
{
    //printf("PLM INIT START\n");
    
    _plm_t_req->write(1);
    
    _plm_reset->write(0);
    wait_ms(1500);
    _plm_reset->write(1);
    
    this->wait_reset();
    
    //printf("PLM INIT DONE\n");
}

void ST7580::send_frame(unsigned char *msg, int msg_length)
{
    unsigned char   data[255];
    unsigned char   full_data[255 + 5];
    unsigned int    checksum;
    unsigned int    data_length = msg_length + 1;
    unsigned int    frame_length = data_length + 1;

    data[0] = 0x44;     //Default modulation
    for(int i = 0; i < msg_length; i++)
    {
        data[i + 1] = msg[i];
    }

    //checksum calculation
    checksum = 0;
    checksum += data_length;
    checksum += CMD_DL_DATA_REQ;           //command, data request
    for(int i = 0; i < data_length; ++i){
        checksum += data[i];
    }
    full_data[0] = ST7580_STX_02;        //start of frame
    full_data[1] = data_length;
    full_data[2] = CMD_DL_DATA_REQ;

    for(unsigned char i = 0;i < data_length; ++i)
    {
        full_data[i + 3] = data[i];
    }

    full_data[data_length + 3] = (unsigned char)( checksum );
    full_data[data_length + 4] = (unsigned char)( checksum >> 8 );

    _plm_t_req->write(0);
    
    //this->wait_status();

    wait_ms(ST7580_TSR);   //p.18 de la doc ST7580
    
    _plm_uart->printf((const char*)full_data);
    //for (int i = 0; i < frame_length; i++)
    //{
    //    _plm_uart->putc(full_data[i]);
    //}
    _plm_t_req->write(1);
    //printf("SENT DATA\n");
}

void ST7580::wait_status()
{
    while (_rx_char != ST7580_STX_STATUS);
}

void ST7580::wait_reset()
{
    while (_rx_char != CMD_RESET_IND);
}

void ST7580::reset_reception_buffer()
{
    _rcv_payload_len = 255;
    _rcv_data_idx = 0;
    memset((char *)_rcv_data, 0, sizeof(_rcv_data)); //Reset reception buffer
}

void ST7580::rx_complete()
{
    //printf("%s\n", (unsigned char *)this->_rcv_data);
    this->_usr_callback((unsigned char *)_rcv_data + 7, _rcv_payload_len); //callback into the user app, trims the PLC data;
    this->reset_reception_buffer();
}

void ST7580::rx_callback()
{
    _rx_char = _plm_uart->getc();
    _rcv_data[_rcv_data_idx] = _rx_char;
    _rcv_data_idx++;
    if (_rcv_data[0] == ST7580_STX_02)         //If this is a start condition
    {
        if (_rcv_data_idx > 1)
        {
            _rcv_payload_len = _rcv_data[1];
            if (_rcv_payload_len < 5)
            {
                this->reset_reception_buffer();
            }
            if (_rcv_data_idx >= _rcv_payload_len)
            {
                this->rx_complete();
            }
        }
    }
    else
    {
        this->reset_reception_buffer();
    }
}