Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

Committer:
davidjhoward
Date:
Wed Sep 14 16:10:36 2016 +0000
Revision:
57:5f18ae91c7c7
Parent:
54:ec1b03064bbd
Child:
67:49f266601d83
Bump up priority of ModbusMaster thread

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmarkel44 0:65cfa4873284 1 /******************************************************************************
davidjhoward 4:c35db3946fd8 2 *
jmarkel44 0:65cfa4873284 3 * File: ModbusMaster.cpp
jmarkel44 0:65cfa4873284 4 * Desciption: source for the ICE Modbus Master
jmarkel44 0:65cfa4873284 5 *
jmarkel44 0:65cfa4873284 6 *****************************************************************************/
jmarkel44 0:65cfa4873284 7 #include "global.h"
jmarkel44 0:65cfa4873284 8 #include <stdio.h>
davidjhoward 31:4b1587034318 9 #include "MTSLog.h"
jmarkel44 0:65cfa4873284 10 #include "BLEDataHandler.h"
davidjhoward 4:c35db3946fd8 11 #include "ModbusMaster.h"
davidjhoward 8:abe51ae5ef8b 12 #include "MbedJSONValue.h"
jmarkel44 0:65cfa4873284 13
jmarkel44 0:65cfa4873284 14 /*****************************************************************************
jmarkel44 0:65cfa4873284 15 * Function: ModbusMaster
jmarkel44 0:65cfa4873284 16 * Description: entry point for the Modbus Master
jmarkel44 0:65cfa4873284 17 *
jmarkel44 0:65cfa4873284 18 * @param (IN) args (user-defined arguments)
jmarkel44 0:65cfa4873284 19 * @return none
jmarkel44 0:65cfa4873284 20 *****************************************************************************/
davidjhoward 42:c703a60993b1 21 char ModbusMasterScratchBuf[1024];
jmarkel44 0:65cfa4873284 22 void ModbusMaster(void const *args)
jmarkel44 0:65cfa4873284 23 {
davidjhoward 31:4b1587034318 24 logInfo("%s ModbusMaster has started...", __func__);
davidjhoward 15:a6ee32969e8e 25 bool status;
davidjhoward 8:abe51ae5ef8b 26 MbedJSONValue json_value;
davidjhoward 54:ec1b03064bbd 27
davidjhoward 54:ec1b03064bbd 28 modbus_init(MB_BAUD_RATE);
davidjhoward 54:ec1b03064bbd 29 DigitalOut flu_power(PA_11);
davidjhoward 54:ec1b03064bbd 30 flu_power = 0; // provide power to the modbus
davidjhoward 54:ec1b03064bbd 31 printf("MODBUS INITIALIZED\r\n");
davidjhoward 54:ec1b03064bbd 32
jmarkel44 0:65cfa4873284 33
davidjhoward 39:9287c7d59016 34 while( true ) {
davidjhoward 8:abe51ae5ef8b 35
davidjhoward 42:c703a60993b1 36 logInfo("Top Of Modbus Master Loop");
davidjhoward 42:c703a60993b1 37
davidjhoward 39:9287c7d59016 38 // configure modbus registers based in all files that start with "input"
davidjhoward 39:9287c7d59016 39 std::vector<mDot::mdot_file> file_list = GLOBAL_mdot->listUserFiles();
davidjhoward 39:9287c7d59016 40 for (std::vector<mDot::mdot_file>::iterator i = file_list.begin(); i != file_list.end(); ++i) {
davidjhoward 8:abe51ae5ef8b 41
davidjhoward 42:c703a60993b1 42 if( strncmp( i->name, "input", (strlen("input")-1)) == 0 ) {
davidjhoward 8:abe51ae5ef8b 43
davidjhoward 45:3b9e1923cb15 44 logInfo("(%d)FOUND INPUT FILE: %s", __LINE__, i->name);
davidjhoward 42:c703a60993b1 45
davidjhoward 49:0456ee2271be 46 status = GLOBAL_mdot->readUserFile(i->name, ModbusMasterScratchBuf, 1024);
davidjhoward 39:9287c7d59016 47 if( status != true ) {
davidjhoward 45:3b9e1923cb15 48 logInfo("(%d)read file failed, status=%d", __LINE__, status);
davidjhoward 39:9287c7d59016 49 } else {
davidjhoward 45:3b9e1923cb15 50 logInfo("(%d)Read File SUCCESS: %s", __LINE__, ModbusMasterScratchBuf );
davidjhoward 39:9287c7d59016 51 }
davidjhoward 49:0456ee2271be 52
davidjhoward 42:c703a60993b1 53 parse( json_value, ModbusMasterScratchBuf );
davidjhoward 9:ef0ca2f8a8a6 54
davidjhoward 39:9287c7d59016 55 std::string id = json_value["id"].get<std::string>().c_str();
davidjhoward 39:9287c7d59016 56 ModbusRegisterMap[id].name = json_value["name"].get<std::string>().c_str();
davidjhoward 39:9287c7d59016 57 ModbusRegisterMap[id].units = json_value["units"].get<std::string>().c_str();
davidjhoward 39:9287c7d59016 58 ModbusRegisterMap[id].min = atof(json_value["min"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 59 ModbusRegisterMap[id].max = atof(json_value["max"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 60 ModbusRegisterMap[id].node = atoi(json_value["node"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 61 ModbusRegisterMap[id].reg = atoi(json_value["reg"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 62 ModbusRegisterMap[id].rtype = atoi(json_value["rtype"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 63 ModbusRegisterMap[id].type = atoi(json_value["type"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 64 ModbusRegisterMap[id].size = atoi(json_value["size"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 65 ModbusRegisterMap[id].order = atoi(json_value["order"].get<std::string>().c_str());
davidjhoward 39:9287c7d59016 66 ModbusRegisterMap[id].fmt = json_value["fmt"].get<std::string>().c_str();
davidjhoward 49:0456ee2271be 67 ModbusRegisterMap[id].rfreq = atoi(json_value["rfreq"].get<std::string>().c_str());
davidjhoward 15:a6ee32969e8e 68 }
davidjhoward 4:c35db3946fd8 69 }
davidjhoward 31:4b1587034318 70
davidjhoward 39:9287c7d59016 71 // read modbus registers that have been configured.
davidjhoward 39:9287c7d59016 72 while ( true ) {
davidjhoward 39:9287c7d59016 73
davidjhoward 39:9287c7d59016 74 std::map<std::string, ModbusRegister>::iterator iter;
davidjhoward 39:9287c7d59016 75 for (iter = ModbusRegisterMap.begin(); iter != ModbusRegisterMap.end(); ++iter) {
davidjhoward 42:c703a60993b1 76 logInfo("Reading node=%d, reg=%d, size=%d, order=%d", iter->second.node, iter->second.reg, iter->second.size, iter->second.order );
davidjhoward 39:9287c7d59016 77 SendModbusCommand(iter->second.node, iter->second.reg, iter->second.size);
davidjhoward 57:5f18ae91c7c7 78 Thread::wait(30);
davidjhoward 39:9287c7d59016 79
davidjhoward 39:9287c7d59016 80 switch( iter->second.type ) {
davidjhoward 39:9287c7d59016 81 case TYPE_32BIT_FLOAT:
davidjhoward 39:9287c7d59016 82 float float_value;
davidjhoward 39:9287c7d59016 83 status = ReadModbus_32bit_float( &float_value, iter->second.order );
davidjhoward 39:9287c7d59016 84 if( status == true ) {
davidjhoward 39:9287c7d59016 85 ModbusRegisterMap[iter->first].float_value = float_value;
davidjhoward 54:ec1b03064bbd 86 logInfo("Modbus Tag:%s value=%2.2f", iter->first.c_str(), float_value );
davidjhoward 54:ec1b03064bbd 87 }
davidjhoward 54:ec1b03064bbd 88 else
davidjhoward 54:ec1b03064bbd 89 {
davidjhoward 54:ec1b03064bbd 90 logInfo("Modbus Read Failed, tag=%s", iter->first.c_str() );
davidjhoward 39:9287c7d59016 91 }
davidjhoward 39:9287c7d59016 92 break;
davidjhoward 39:9287c7d59016 93 case TYPE_32BIT_INT:
davidjhoward 39:9287c7d59016 94 break;
davidjhoward 39:9287c7d59016 95 case TYPE_32BIT_UINT:
davidjhoward 39:9287c7d59016 96 break;
davidjhoward 39:9287c7d59016 97 case TYPE_16BIT_INT:
davidjhoward 39:9287c7d59016 98 break;
davidjhoward 39:9287c7d59016 99 case TYPE_16BIT_UINT:
davidjhoward 39:9287c7d59016 100 break;
davidjhoward 39:9287c7d59016 101 default:
davidjhoward 39:9287c7d59016 102 break;
davidjhoward 39:9287c7d59016 103 }
davidjhoward 39:9287c7d59016 104 }
davidjhoward 39:9287c7d59016 105
davidjhoward 39:9287c7d59016 106 logInfo("Checking for MAIL");
davidjhoward 39:9287c7d59016 107 osEvent evt = ModbusMasterMailBox.get(50);
davidjhoward 39:9287c7d59016 108 if (evt.status == osEventMail) {
davidjhoward 39:9287c7d59016 109 Message_t *mail = (Message_t*)evt.value.p;
davidjhoward 39:9287c7d59016 110 logInfo("Mail Received: Action: %d, New Input File: %s", mail->action, mail->controlFile);
davidjhoward 39:9287c7d59016 111 ModbusMasterMailBox.free(mail);
davidjhoward 39:9287c7d59016 112 ModbusRegisterMap.clear();
davidjhoward 39:9287c7d59016 113 break;
davidjhoward 39:9287c7d59016 114 } else {
davidjhoward 39:9287c7d59016 115 logInfo("No Mail");
davidjhoward 39:9287c7d59016 116 }
davidjhoward 57:5f18ae91c7c7 117 Thread::wait(5000);
davidjhoward 31:4b1587034318 118 }
jmarkel44 0:65cfa4873284 119 }
davidjhoward 4:c35db3946fd8 120 }
davidjhoward 4:c35db3946fd8 121
davidjhoward 4:c35db3946fd8 122
davidjhoward 4:c35db3946fd8 123 volatile char modbus_buffer_char;
davidjhoward 4:c35db3946fd8 124 volatile bool modbus_interrupt_complete = false;
davidjhoward 4:c35db3946fd8 125
davidjhoward 4:c35db3946fd8 126 uint8_t modbus_input_buffer[SIZE_MB_BUFFER];// 1byte address + 1 byte function +1 byte number of regs + 12 bytes of data + 2 bytes for crc response frame from slave
davidjhoward 4:c35db3946fd8 127 volatile uint8_t modbus_input_buffer_counter = 0;
davidjhoward 4:c35db3946fd8 128
davidjhoward 4:c35db3946fd8 129 //Frame crc calucation
davidjhoward 4:c35db3946fd8 130 uint16_t modbus_crc(uint8_t* buf, int len)
davidjhoward 4:c35db3946fd8 131 {
davidjhoward 4:c35db3946fd8 132 uint16_t crc = 0xFFFF;
davidjhoward 4:c35db3946fd8 133
davidjhoward 4:c35db3946fd8 134 for (int pos = 0; pos < len; pos++) {
davidjhoward 4:c35db3946fd8 135 crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc
davidjhoward 4:c35db3946fd8 136
davidjhoward 4:c35db3946fd8 137 for (int i = 8; i != 0; i--) {
davidjhoward 4:c35db3946fd8 138 // Loop over each bit
davidjhoward 4:c35db3946fd8 139 if ((crc & 0x0001) != 0) {
davidjhoward 4:c35db3946fd8 140 // If the LSB is set
davidjhoward 4:c35db3946fd8 141 crc >>= 1; // Shift right and XOR 0xA001
davidjhoward 4:c35db3946fd8 142 crc ^= 0xA001;
davidjhoward 4:c35db3946fd8 143 } else // Else LSB is not set
davidjhoward 4:c35db3946fd8 144 crc >>= 1; // Just shift right
davidjhoward 4:c35db3946fd8 145 }
davidjhoward 4:c35db3946fd8 146 }
davidjhoward 4:c35db3946fd8 147 // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
davidjhoward 4:c35db3946fd8 148 return crc;
davidjhoward 4:c35db3946fd8 149 }
davidjhoward 4:c35db3946fd8 150
davidjhoward 4:c35db3946fd8 151 RawSerial modbus(PA_2, PA_3);
davidjhoward 57:5f18ae91c7c7 152 DigitalOut mod_de(PB_0);
davidjhoward 57:5f18ae91c7c7 153 DigitalOut mod_re(PB_1);
davidjhoward 4:c35db3946fd8 154
davidjhoward 4:c35db3946fd8 155 void modbus_init( uint16_t baudRate )
davidjhoward 4:c35db3946fd8 156 {
davidjhoward 4:c35db3946fd8 157 modbus.baud(baudRate);
davidjhoward 4:c35db3946fd8 158 modbus.attach(&modbus_recv, RawSerial::RxIrq);
davidjhoward 4:c35db3946fd8 159 }
davidjhoward 4:c35db3946fd8 160
davidjhoward 4:c35db3946fd8 161 //call back when character goes into RX buffer for RS485 modbus
davidjhoward 4:c35db3946fd8 162 void modbus_recv()
davidjhoward 4:c35db3946fd8 163 {
davidjhoward 4:c35db3946fd8 164
davidjhoward 4:c35db3946fd8 165 if (modbus.readable()) {
davidjhoward 4:c35db3946fd8 166 modbus_buffer_char = modbus.getc();
davidjhoward 4:c35db3946fd8 167 if (modbus_input_buffer_counter == 0 && modbus_buffer_char == 0x00) {
davidjhoward 4:c35db3946fd8 168 modbus_input_buffer_counter = 0;
davidjhoward 4:c35db3946fd8 169 } else {
davidjhoward 4:c35db3946fd8 170 modbus_input_buffer[modbus_input_buffer_counter] = modbus_buffer_char;
davidjhoward 4:c35db3946fd8 171 modbus_input_buffer_counter++;
davidjhoward 4:c35db3946fd8 172 }
davidjhoward 4:c35db3946fd8 173 }
davidjhoward 4:c35db3946fd8 174
davidjhoward 4:c35db3946fd8 175 if (modbus_input_buffer_counter > modbus_input_buffer[2] + 4) {
davidjhoward 4:c35db3946fd8 176 modbus_interrupt_complete = true;
davidjhoward 4:c35db3946fd8 177 modbus_input_buffer_counter = 0;
davidjhoward 4:c35db3946fd8 178 }
davidjhoward 4:c35db3946fd8 179 }
davidjhoward 4:c35db3946fd8 180
davidjhoward 4:c35db3946fd8 181 // Read modbus master frame
davidjhoward 9:ef0ca2f8a8a6 182 void SendModbusCommand(uint8_t slave_address, uint16_t firstReg, uint16_t noRegs)
davidjhoward 4:c35db3946fd8 183 {
davidjhoward 4:c35db3946fd8 184 uint8_t L1V[8] = {slave_address, 0x04, 0x00, 0x02, 0x00, 0x02, 0xD1, 0x16};
davidjhoward 4:c35db3946fd8 185
davidjhoward 4:c35db3946fd8 186 L1V[2] = (firstReg >> 8) & 0xFF;
davidjhoward 4:c35db3946fd8 187 L1V[3] = firstReg & 0xFF;
davidjhoward 4:c35db3946fd8 188 L1V[4] = (noRegs >> 8) & 0xFF;
davidjhoward 4:c35db3946fd8 189 L1V[5] = noRegs & 0xFF;
davidjhoward 4:c35db3946fd8 190 L1V[6] = modbus_crc(L1V,6) & 0xFF;
davidjhoward 4:c35db3946fd8 191 L1V[7] = (modbus_crc(L1V,6)>>8) & 0xFF;
davidjhoward 4:c35db3946fd8 192
davidjhoward 57:5f18ae91c7c7 193 mod_de = 1;
davidjhoward 57:5f18ae91c7c7 194 mod_re = 1;
davidjhoward 57:5f18ae91c7c7 195 Thread::wait(1);
davidjhoward 4:c35db3946fd8 196 for (uint8_t i = 0; i < 8; i++)
davidjhoward 4:c35db3946fd8 197 modbus.putc(L1V[i]);
davidjhoward 4:c35db3946fd8 198
davidjhoward 57:5f18ae91c7c7 199 Thread::wait(2);
davidjhoward 57:5f18ae91c7c7 200 mod_de = 0;
davidjhoward 57:5f18ae91c7c7 201 mod_re = 0;
davidjhoward 4:c35db3946fd8 202
davidjhoward 4:c35db3946fd8 203 }
davidjhoward 4:c35db3946fd8 204
davidjhoward 4:c35db3946fd8 205 bool mbInterruptComplete()
davidjhoward 4:c35db3946fd8 206 {
davidjhoward 4:c35db3946fd8 207 if (modbus_interrupt_complete) {
davidjhoward 4:c35db3946fd8 208 modbus_interrupt_complete = false;
davidjhoward 4:c35db3946fd8 209 return true;
davidjhoward 4:c35db3946fd8 210 } else {
davidjhoward 4:c35db3946fd8 211 return false;
davidjhoward 4:c35db3946fd8 212 }
davidjhoward 4:c35db3946fd8 213 }
davidjhoward 4:c35db3946fd8 214
davidjhoward 15:a6ee32969e8e 215 bool ReadModbus_32bit_float( float *float_value, int order )
davidjhoward 4:c35db3946fd8 216 {
davidjhoward 15:a6ee32969e8e 217 MR_REGISTER_32_BIT_FLOAT value;
davidjhoward 31:4b1587034318 218
davidjhoward 4:c35db3946fd8 219 if (mbInterruptComplete() != true ) {
davidjhoward 4:c35db3946fd8 220 return false;
davidjhoward 4:c35db3946fd8 221 }
davidjhoward 4:c35db3946fd8 222
davidjhoward 15:a6ee32969e8e 223 switch( order ) {
davidjhoward 31:4b1587034318 224 case BigEndian:
davidjhoward 15:a6ee32969e8e 225 value.b.lo_lo = modbus_input_buffer[6];
davidjhoward 15:a6ee32969e8e 226 value.b.lo_hi = modbus_input_buffer[5];
davidjhoward 15:a6ee32969e8e 227 value.b.hi_lo = modbus_input_buffer[4];
davidjhoward 15:a6ee32969e8e 228 value.b.hi_hi = modbus_input_buffer[3];
davidjhoward 15:a6ee32969e8e 229 break;
davidjhoward 15:a6ee32969e8e 230 case BigEndianReverseWord:
davidjhoward 15:a6ee32969e8e 231 value.b.lo_lo = modbus_input_buffer[4];
davidjhoward 15:a6ee32969e8e 232 value.b.lo_hi = modbus_input_buffer[3];
davidjhoward 15:a6ee32969e8e 233 value.b.hi_lo = modbus_input_buffer[6];
davidjhoward 15:a6ee32969e8e 234 value.b.hi_hi = modbus_input_buffer[5];
davidjhoward 15:a6ee32969e8e 235 break;
davidjhoward 15:a6ee32969e8e 236 default:
davidjhoward 15:a6ee32969e8e 237 return false;
davidjhoward 15:a6ee32969e8e 238 }
davidjhoward 15:a6ee32969e8e 239 *float_value = value.f;
davidjhoward 4:c35db3946fd8 240 return true;
davidjhoward 4:c35db3946fd8 241 }