Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ICE-Application/src/Drivers/mod.cpp
- Committer:
- jmarkel44
- Date:
- 2017-01-24
- Revision:
- 0:61364762ee0e
File content as of revision 0:61364762ee0e:
// modbus // --------------------------------------------------------------------------------------------------------------------- // includes #include "mbed.h" #include "global.h" #include "mod.h" // --------------------------------------------------------------------------------------------------------------------- // globals unsigned short int mod_data[MOD_DATA]; unsigned short int mod_ireg[MOD_IREG]; int mod_verbose = 0; // ------------------------------------------------------------------------------------------------- // modbus buffers #define MOD_RXNUM 200 #define MOD_TXNUM 200 int mod_rxnum = 0; int mod_txnum = 0; unsigned char mod_rxbuf[MOD_RXNUM]; unsigned char mod_txbuf[MOD_TXNUM]; // ------------------------------------------------------------------------------------------------- // print functions void print_uc(char hex, char bin, char dec, char* pre, unsigned char input, char* post) { if(pre[0] != 0) printf("%s", pre); if(hex) { printf("0x%02X", input); } if(bin) { if(hex) printf(" "); for(int i=7; i>=0; i--) { if(i<7 && (i%4)==3) printf(" "); if(input & (1<<i)) printf("1"); else printf("0"); } } if(dec) { if(hex || bin) printf(" "); printf("%u", input); } if(post[0] != 0) printf("%s", post); } void print_us(char hex, char bin, char dec, char* pre, unsigned short int input, char* post) { if(pre[0] != 0) printf("%s", pre); if(hex) { printf("0x%04X", input); } if(bin) { if(hex) printf(" "); for(int i=15; i>=0; i--) { if(i<15 && (i%4)==3) printf(" "); if(input & (1<<i)) printf("1"); else printf("0"); } } if(dec) { if(hex || bin) printf(" "); printf("%u", input); } if(post[0] != 0) printf("%s", post); } // ------------------------------------------------------------------------------------------------- // initialization RawSerial mod(PC_6, PC_7); DigitalOut mod_de(PC_8); DigitalOut mod_re(PC_9); void mod_init(void) { mod_de = 0; mod_re = 0; mod.baud(MOD_BAUD); mod.attach(&mod_process, RawSerial::RxIrq); for(int i=0; i<MOD_IREG; i++) mod_ireg[i] = 0; } // ------------------------------------------------------------------------------------------------- // utilities void mod_clear(void) { mod_rxnum = 0; for(int i=0; i<MOD_RXNUM; i++) mod_rxbuf[i] = 0; mod_txnum = 0; for(int i=0; i<MOD_TXNUM; i++) mod_txbuf[i] = 0; } unsigned short int mod_calc_crc(unsigned char *buffer, int length) { unsigned short int temp=0xFFFF, flag; for(int i=0; i<length; i++) { temp = temp ^ buffer[i]; for(int j=1; j<=8; j++) { flag = temp & 0x0001; temp = temp >> 1; if(flag) temp = temp ^ 0xA001; } } return(temp); } void mod_ireg_dump(void) { for(int i=0; i<MOD_IREG; i++) { printf(" I%02d = ", i); print_us(1,0,1, "", mod_ireg[i], "\r\n"); } } // --------------------------------------------------------------------------------------------------------------------- // process received data void mod_process(void) { if(mod.readable()) { if(mod_rxnum < MOD_RXNUM) { mod_rxbuf[mod_rxnum++] = mod.getc(); } else { if(mod_verbose) printf(" [mod_process] buffer full\r\n"); mod_clear(); } } } // --------------------------------------------------------------------------------------------------------------------- // MOD_FUNC_GET_IREG (NBYT = total bytes of data transmitted) // MOD_FUNC_GET_HREG // // byte: 0 1 2 3 4 5 6 7 // received: ADDR FUNC SREG-H SREG-L NREG-H NREG-L RCRC-L RCRC-H // transmit: ADDR FUNC NBYT DATA-H DATA-L TCRC-L TCRC-H NULL int mod_read(int inp_addr, int inp_func, int inp_sreg, int inp_nreg, unsigned char *rd_buf) { int mod_error = 0; unsigned char tx_addr = inp_addr; unsigned char tx_func = inp_func; WORD2BYTE tx_sreg; tx_sreg.value = inp_sreg; if(inp_nreg < 1) inp_nreg = 1; WORD2BYTE tx_nreg; tx_nreg.value = inp_nreg; // fill transmit buffer mod_clear(); mod_txbuf[mod_txnum++] = tx_addr; mod_txbuf[mod_txnum++] = tx_func; mod_txbuf[mod_txnum++] = tx_sreg.byte1; mod_txbuf[mod_txnum++] = tx_sreg.byte0; mod_txbuf[mod_txnum++] = tx_nreg.byte1; mod_txbuf[mod_txnum++] = tx_nreg.byte0; WORD2BYTE tx_crc; tx_crc.value = mod_calc_crc(mod_txbuf, mod_txnum); mod_txbuf[mod_txnum++] = tx_crc.byte0; mod_txbuf[mod_txnum++] = tx_crc.byte1; // transmit mod_de = 1; mod_re = 1; wait_ms(1); for(int i=0; i<mod_txnum; i++) mod.putc(mod_txbuf[i]); wait_ms(2); mod_de = 0; mod_re = 0; wait_ms(30); // output transmit buffer if(mod_verbose) { printf(" mod_txbuf: %d\r\n\r\n", mod_txnum); for(int i=0; i<mod_txnum; i++) { printf(" %02d", i); print_uc(1,0,1, " = ", mod_txbuf[i], "\r\n"); } if(mod_txnum) { printf("\r\n"); print_uc(1,0,1, " addr = ", tx_addr, "\r\n"); print_uc(1,0,1, " func = ", tx_func, "\r\n"); print_us(1,0,1, " sreg = ", tx_sreg.value, "\r\n"); print_us(1,0,1, " nreg = ", tx_nreg.value, "\r\n"); print_us(1,0,1, " tcrc = ", tx_crc.value, "\r\n"); } } // process received buffer if(mod_verbose) { printf("\r\n mod_rxbuf: %d\r\n\r\n", mod_rxnum); for(int i=0; i<mod_rxnum; i++) { printf(" %02d", i); print_uc(1,0,1, " = ", mod_rxbuf[i], "\r\n"); } } if(mod_rxnum) { int rxnum = 0; unsigned char rx_addr = mod_rxbuf[rxnum++]; unsigned char rx_func = mod_rxbuf[rxnum++]; if(mod_verbose) { print_uc(1,0,1, "\r\n addr = ", rx_addr, "\r\n"); print_uc(1,0,1, " func = ", rx_func, ""); } if(rx_func == tx_func) { int rd_buf_index = 0; unsigned char rx_nbyt = mod_rxbuf[rxnum++]; if(mod_verbose) print_uc(1,0,1, "\r\n nbyt = ", rx_nbyt, "\r\n\r\n"); for(int i=0; i<rx_nbyt/2; i++) { WORD2BYTE rx_data; rd_buf[rd_buf_index++] = rx_data.byte1 = mod_rxbuf[rxnum++]; rd_buf[rd_buf_index++] = rx_data.byte0 = mod_rxbuf[rxnum++]; int ireg = tx_sreg.value + i; if(ireg < MOD_IREG) mod_ireg[ireg] = rx_data.value; if(mod_verbose) { printf(" data(%03d)", ireg); print_us(1,0,1, " = ", rx_data.value, "\r\n"); } } WORD2BYTE rx_crc; rx_crc.byte0 = mod_rxbuf[rxnum++]; rx_crc.byte1 = mod_rxbuf[rxnum++]; if(mod_verbose) print_us(1,0,1, "\r\n rcrc = ", rx_crc.value, "\r\n"); } else { unsigned char rx_nerr = mod_rxbuf[rxnum++]; mod_error = rx_nerr; if(mod_verbose) { if(rx_func == tx_func+0x80) printf(" (func %d error)\r\n", tx_func); else printf(" (unknown func error)\r\n"); print_uc(1,0,1, " nerr = ", rx_nerr, " ("); switch(rx_nerr) { case MOD_ERROR_ILL_FUNC: ; printf("slave received illegal function code") ; break; case MOD_ERROR_ILL_ADDR: ; printf("slave received illegal register address") ; break; case MOD_ERROR_ILL_DATA: ; printf("slave received illegal register value") ; break; case MOD_ERROR_SLAVE_FAIL: ; printf("slave device-specific failure") ; break; case MOD_ERROR_SLAVE_ACK: ; printf("slave ACK") ; break; case MOD_ERROR_SLAVE_BUSY: ; printf("slave is busy") ; break; case MOD_ERROR_SLAVE_NACK: ; printf("slave NACK") ; break; case MOD_ERROR_SLAVE_PARITY: ; printf("slave memory parity error") ; break; case MOD_ERROR_RX_TIMEOUT: ; printf("master receive timeout") ; break; case MOD_ERROR_TX_TIMEOUT: ; printf("master transmit timeout") ; break; case MOD_ERROR_CRC: ; printf("master CRC error") ; break; default: ; printf("unknown error") ; break; } printf(")\r\n"); } WORD2BYTE rx_crc; rx_crc.byte0 = mod_rxbuf[rxnum++]; rx_crc.byte1 = mod_rxbuf[rxnum++]; if(mod_verbose) print_us(1,0,1, " rcrc = ", rx_crc.value, "\r\n"); } } else { mod_error = MOD_ERROR_RX_TIMEOUT; // no received data } if(mod_verbose) printf("\r\n mod_error: %d\r\n", mod_error); return(mod_error); } // --------------------------------------------------------------------------------------------------------------------- // MOD_FUNC_SET_HREG // // byte: 0 1 2 3 4 5 6 7 8 // received: ADDR FUNC SREG-H SREG-L DATA-H DATA-L RCRC-L RCRC-H // transmit: ADDR FUNC SREG-H SREG-L DATA-H DATA-L TCRC-L TCRC-H NULL // // MOD_FUNC_SET_HREGS // // byte: 0 1 2 3 4 5 6 7 8 9 10 // received: ADDR FUNC SREG-H SREG-L NREG-H NREG-L NBYT DATA-H DATA-L RCRC-L RCRC-H // transmit: ADDR FUNC SREG-H SREG-L NREG-H NREG-L TCRC-L TCRC-H NULL // int mod_write(int inp_addr, int inp_func, int inp_sreg, int inp_nreg, unsigned char *xmt_data) { int mod_error = 0; unsigned char tx_addr = inp_addr; unsigned char tx_func = inp_func; WORD2BYTE tx_sreg; tx_sreg.value = inp_sreg; WORD2BYTE tx_nreg; tx_nreg.value = inp_nreg; WORD2BYTE data; unsigned char nbyt = 2*inp_nreg; // fill transmit buffer mod_clear(); mod_txbuf[mod_txnum++] = tx_addr; mod_txbuf[mod_txnum++] = tx_func; mod_txbuf[mod_txnum++] = tx_sreg.byte1; mod_txbuf[mod_txnum++] = tx_sreg.byte0; if(tx_func == MOD_FUNC_SET_HREG) { // data.value = xmt_data[0]; // mod_txbuf[mod_txnum++] = data.byte1; // mod_txbuf[mod_txnum++] = data.byte0; mod_txbuf[mod_txnum++] = xmt_data[0]; mod_txbuf[mod_txnum++] = xmt_data[1]; } else { mod_txbuf[mod_txnum++] = tx_nreg.byte1; mod_txbuf[mod_txnum++] = tx_nreg.byte0; mod_txbuf[mod_txnum++] = nbyt; for(int i=0,i2=0; i<inp_nreg; i++) { // data.value = xmt_data[i]; // mod_txbuf[mod_txnum++] = data.byte1; // mod_txbuf[mod_txnum++] = data.byte0; mod_txbuf[mod_txnum++] = xmt_data[i2]; mod_txbuf[mod_txnum++] = xmt_data[(i2+1)]; i2=i2+2; } } WORD2BYTE tx_crc; tx_crc.value = mod_calc_crc(mod_txbuf, mod_txnum); mod_txbuf[mod_txnum++] = tx_crc.byte0; mod_txbuf[mod_txnum++] = tx_crc.byte1; // transmit mod_de = 1; mod_re = 1; wait_ms(1); for(int i=0; i<mod_txnum; i++) mod.putc(mod_txbuf[i]); wait_ms(2); mod_de = 0; mod_re = 0; wait_ms(30); // output transmit buffer if(mod_verbose) { printf(" mod_txbuf: %d\r\n\r\n", mod_txnum); for(int i=0; i<mod_txnum; i++) { printf(" %02d", i); print_uc(1,0,1, " = ", mod_txbuf[i], "\r\n"); } if(mod_txnum) { print_uc(1,0,1, "\r\n addr = ", tx_addr, "\r\n"); print_uc(1,0,1, " func = ", tx_func, "\r\n"); print_us(1,0,1, " sreg = ", tx_sreg.value, "\r\n"); if(tx_func == MOD_FUNC_SET_HREG) { data.value = xmt_data[0]; print_us(1,0,1, " data = ", data.value, "\r\n"); } else { print_us(1,0,1, " nreg = ", tx_nreg.value, "\r\n"); print_uc(1,0,1, " nbyt = ", nbyt, "\r\n\r\n"); for(int i=0; i<inp_nreg; i++) { printf(" data(%03d)", tx_sreg.value+i); data.value = xmt_data[i]; print_us(1,0,1, " = ", data.value, "\r\n"); } } print_us(1,0,1, " tcrc = ", tx_crc.value, "\r\n"); } } // process received buffer if(mod_verbose) { printf("\r\n mod_rxbuf: %d\r\n\r\n", mod_rxnum); for(int i=0; i<mod_rxnum; i++) { printf(" %02d", i); print_uc(1,0,1, " = ", mod_rxbuf[i], "\r\n"); } } if(mod_rxnum) { int rxnum = 0; unsigned char rx_addr = mod_rxbuf[rxnum++]; unsigned char rx_func = mod_rxbuf[rxnum++]; if(mod_verbose) { print_uc(1,0,1, "\r\n addr = ", rx_addr, "\r\n"); print_uc(1,0,1, " func = ", rx_func, ""); } if(rx_func == tx_func) { WORD2BYTE rx_sreg; rx_sreg.byte1 = mod_rxbuf[rxnum++]; rx_sreg.byte0 = mod_rxbuf[rxnum++]; WORD2BYTE rx_nreg; rx_nreg.byte1 = mod_rxbuf[rxnum++]; rx_nreg.byte0 = mod_rxbuf[rxnum++]; WORD2BYTE rx_crc; rx_crc.byte0 = mod_rxbuf[rxnum++]; rx_crc.byte1 = mod_rxbuf[rxnum++]; if(mod_verbose) { print_us(1,0,1, "\r\n sreg = ", rx_sreg.value, "\r\n"); print_us(1,0,1, " nreg = ", rx_nreg.value, "\r\n"); print_us(1,0,1, " rcrc = ", rx_crc.value, "\r\n"); } } else { unsigned char rx_nerr = mod_rxbuf[rxnum++]; mod_error = rx_nerr; if(mod_verbose) { if(rx_func == tx_func+0x80) printf(" (func %d error)\r\n", tx_func); else printf(" (unknown func error)\r\n"); print_uc(1,0,1, " nerr = ", rx_nerr, " ("); switch(rx_nerr) { case MOD_ERROR_ILL_FUNC: ; printf("slave received illegal function code") ; break; case MOD_ERROR_ILL_ADDR: ; printf("slave received illegal register address") ; break; case MOD_ERROR_ILL_DATA: ; printf("slave received illegal register value") ; break; case MOD_ERROR_SLAVE_FAIL: ; printf("slave device-specific failure") ; break; case MOD_ERROR_SLAVE_ACK: ; printf("slave ACK") ; break; case MOD_ERROR_SLAVE_BUSY: ; printf("slave is busy") ; break; case MOD_ERROR_SLAVE_NACK: ; printf("slave NACK") ; break; case MOD_ERROR_SLAVE_PARITY: ; printf("slave memory parity error") ; break; case MOD_ERROR_RX_TIMEOUT: ; printf("master receive timeout") ; break; case MOD_ERROR_TX_TIMEOUT: ; printf("master transmit timeout") ; break; case MOD_ERROR_CRC: ; printf("master CRC error") ; break; default: ; printf("unknown error") ; break; } printf(")\r\n"); } WORD2BYTE rx_crc; rx_crc.byte0 = mod_rxbuf[rxnum++]; rx_crc.byte1 = mod_rxbuf[rxnum++]; if(mod_verbose) print_us(1,0,1, " rcrc = ", rx_crc.value, "\r\n"); } } else { mod_error = MOD_ERROR_RX_TIMEOUT; // no received data } if(mod_verbose) printf("\r\n mod_error: %d\r\n", mod_error); return(mod_error); } // ---------------------------------------------------------------------------------------------------------------------