Program the control the fischertechnik robo interface or intelligent interface via tcp socket or via a java gui.
Diff: rs485.cpp
- Revision:
- 1:2c9d412ad471
- Parent:
- 0:7f26f0680202
--- a/rs485.cpp Fri Dec 31 14:01:14 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -#include "mbed.h" -#include "data.h" - -#define TXMODE true /* level of eg. MAX485 input to switch to transmit mode */ -#define RXMODE (!TXMODE) - -class rs485: public Serial, DigitalOut { //since communication is half duplex we use only one buffer for both reading and writing - char *buffer; - int index, length; //index is the buffer pointer, length is the length of the buffer - //bool receiving; - bool _done; - virtual void rx() { //ISR that stashes bytes until the buffer is full and then disables itself - //if (!receiving)return; - if (index<length) - buffer[index++] = getc(); - else { - //receiving = false; - attach(0); - _done = true; - } - } - virtual void tx() { //ISR that sends out the entire buffer and then switches to receive mode - if (index<length) - putc(buffer[index++]); - else { - DigitalOut::write(RXMODE); - attach(this,&rs485::rx, RxIrq); - _done = true; - } - } -public: - enum mode_t { rec, trans}; - rs485(PinName out, PinName in, PinName dir): Serial(out, in), DigitalOut(dir) { - //attach(this, rx, RxIrq); - attach(this, &rs485::tx, TxIrq); - DigitalOut::write(RXMODE); - buffer = 0; - length = 0; - //receiving = false; - } - //void init(int br) {} - void send(char *buf, int len) { - DigitalOut::write(TXMODE); - buffer = buf; - length = len; - putc(*buffer); - index = 1; - } - void receive(char *buf, int len) { - buffer = buf; - length = len; - //receiving = true; - attach(this,&rs485::rx, RxIrq); - } - bool done() { - bool tmp = _done; - _done=false; - return tmp; - } - void setmode(enum mode_t m) { - if (m==rec) - DigitalOut::write(RXMODE); - else - DigitalOut::write(TXMODE); - } -}; - - -//class specialized for use with the fischertechnik TXC -class TXC_rs485: public rs485 { - message *msg; //pointer to a TXC message buffer - char *wp; //pointer where the receiver will write the data - int rpos; //index where the transmitter will read the data - virtual void rx(); //ISR - virtual void tx(); //ISR - char state; //receiver state - int rs485_timeout; // a timeout period, intended to reset the receiver when interrupts stop before the end of a message - int tx_message; //the destination of a received message, i.e. the slave address -public: - TXC_rs485(PinName out, PinName in, PinName dir): rs485(out, in, dir) { - baud(921600); - } - void receive(message *m) { - state = 0; - msg = m; - wp = (char*)&msg->hdr.snd; - } - void send(message *m) { -#if 1 - rs485::send((char*)m, BYTES(msg)+7);//use base class for transmission -#else - rpos = 0; - msg = m; -//set RS485 tranceiver in send mode - setmode(trans); -//disable rx interrupt - attach(0); -//enable tx interrupt, will immediately generate int - attach(this, &TXC_rs485::tx, TxIrq); -//kick off transmission -// putc((char*)msg)[rpos++];//not necessary, will start by itself - rs485_timeout = sizeof(message)/8; //just a precaution, transmit should not timeout, timeout is approx. 110% of expected time -#endif - } - - int Slave(bool clear=false) {//return the destination of the received packet, functions also as reception complete flag, is <0 when not yet available - int tmp = tx_message; - if (clear) - tx_message = -3; - return tmp; - } - void timeout(); -}; - -void TXC_rs485::rx() { -// SETPIN12; - char data; - do { - data = getc(); - rs485_timeout = 2;//set a timeout of 100-200us equiv. to 10-20 bytes - switch (state) { - case 0: //idle - if (data == 0x02)//stx - state = 1; - break; - case 1: //stx - if (data == 0x55) - state = 2; - else - state = 0; - break; - case 2://length H, high byte comes first - msg->hdr.bytesL = data; - //length = (unsigned)data<<8; - state = 3; - break; - case 3://length L, low byte - msg->hdr.bytesH = data; - //length += data; - if (msg->hdr.bytes > sizeof(msg)-7) - state = 0; //message structure cannot accomodate message this size - else - state = 4; - break; - case 4://store - *wp++ = data; - if (wp >= ((char*)&msg->hdr.snd + sizeof(trailer)) + msg->hdr.bytes - && wp <= (char*)msg + sizeof(message) + 1 - ) { //message complete - wp = (char*)&msg->hdr.snd;//ready for next message to receive - rs485_timeout = 0; - tx_message = msg->hdr.rec - 3;//slave address tx_message==0 means Ext.1 etc - if (tx_message >= 0) { - attach(0); //disable rec to avoid corruption by new messages - } - state = 0; - } - break; - default: - break; - } - } while (readable()); //see if another char is available, now it is fast enough so this is normally not the case -// CLRPIN12; -} - -void TXC_rs485::tx() {// SETPIN12; - if (rpos > BYTES(msg)+7) { //last byte was sent - attach(0, TxIrq); //disable tx int - attach(this,&TXC_rs485::rx, RxIrq); //re-enable rx int - rs485_timeout = 0; - } else//send 1 byte too many in order to detect that the etx char was sent - putc(((char*)msg)[rpos++]); -// CLRPIN12; -} - -void TXC_rs485::timeout() { - //SETPIN12; - //reset receiver - wp = (char*)&msg->hdr.snd; - state = 0; - //reset transmitter - rpos = 0; - setmode(rec); - attach(0, TxIrq); //disable tx int - attach(this,&TXC_rs485::rx, RxIrq); //re-enable rx int - //CLRPIN12; -}