Modbus with stm 32

Dependencies:   mbed

modbus.cpp

Committer:
lhakpa
Date:
2018-03-14
Revision:
0:40b96f9186c3

File content as of revision 0:40b96f9186c3:

#include "mbed.h"
#include "modbus.h"

uint8_t nodeId = 0;
uint16_t regValue[ADDR_RANGE];

enum state {IDLE, RECEPTION, END} protState = IDLE;

int process_buffer(char *buf, uint8_t *frame)
{
    int status = 0;
    uint8_t sum = 0;
    uint8_t lrc, i;
    char tmpbuf[] = {0, 0, 0};
    
    if (strlen(buf) == 14) {
        for (i = 0; i < 6; i++) {
            tmpbuf[0] = buf[i*2];
            tmpbuf[1] = buf[i*2 + 1]; 
            frame[i] = strtoul(tmpbuf, NULL, 16);
        }
        tmpbuf[0] = buf[12]; tmpbuf[1] = buf[13]; 
        lrc = strtoul(tmpbuf, NULL, 16);
        for (i = 0; i < 6; i++) {
            sum += frame[i];
        }
        if ((sum + lrc) == 0) {
            status = 1;
        }
    }
    
    return status;    
}

void modbus_init(uint8_t id)
{
    nodeId = id;
}

uint16_t modbus_read(uint16_t offset)
{
    if (offset < ADDR_RANGE) {
        return regValue[offset];
    } 
    return 0xFFFF;
}

uint16_t modbus_update(uint8_t offset, uint16_t val)
{
    uint16_t tmp;
    
    if (offset < ADDR_RANGE) {
        tmp = regValue[offset];
        regValue[offset] = val;
        return tmp;
    } 
    return 0xFFFF;
}

int modbus_parser(char ch, uint8_t *frame)
{
    static char buf[514];
    static int idx = 0;
    static int status = 0;
    
    switch(protState) {
        case IDLE:
            if (ch == ':') {
                protState = RECEPTION;
                idx = 0;
                status = 0;
            }
            break;
        case RECEPTION:
            if ((ch >= '0') && (ch <= '9')) {
                buf[idx++] = ch;
            } else if ((ch >= 'a') && (ch <= 'f')) {
                buf[idx++] = ch;
            } else if ((ch >= 'A') && (ch <= 'F')) {
                buf[idx++] = ch;
            } else if (ch == '\r') {
                buf[idx] = 0;
                protState = END;
            } else {
                protState = IDLE;
            }
            break;
        case END:
            if (ch == '\n') {
                if (process_buffer(buf, frame)) {
                    if ((frame[0] == nodeId) && (frame[1] == FUNC_CODE)) {
                        status = 1;
                    }
                }
            } 
            protState = IDLE;
            break;
        default:
            protState = IDLE;
    }
    
    return status;
}