#include #include #include "amswirelib.hpp" #include "amsgenlib.hpp" #include "amsswcomm.hpp" //initialize the sw communication channel // each swcomm channel has 3 pins, the clock pin (controlled by the master), // the input pin (receiving a signal from the other device) // and an output pin (sending a signal to the other device) //Inputs: // ms - master or slave // clkpin - the clock pin number // outpin - the output pin number // inpin - the input pin number // divisor - how many updates to skip between clock changes void amsswcomm::init(uint8_t _ms, uint8_t _clkpin, uint8_t _sendpin, uint8_t _recvpin, int _divisor) { ms = _ms; clkpin = _clkpin; sendpin = _sendpin; recvpin = _recvpin; divisor = _divisor; clockticks = 0; clockstate = 0; lastclockstate = 0; if(ms==1) { //master set_pinmode(clkpin,1); set_pinmode(recvpin,0); set_pinmode(sendpin,1); } else if(ms==0) { //slave set_pinmode(clkpin,0); set_pinmode(recvpin,0); set_pinmode(sendpin,1); } clearrecvqueue(); clearsendqueue(); // recvmessage_size = -1; // sendmessage_size = -1; //no message // recvmessage_bit = 0; // sendmessage_bit = 0; // sendstate = 0; // recvstate = 0; // sendbytepointer = 0; // recvbytepointer = 0; // sendbitpointer = 0; // recvbitpointer = 0; int8_t I; for(I=0;I> (9-sendbitpointer); write_pin(sendpin,bit); sendbitpointer++; //advance pointer if(sendbitpointer>=10) { //if finished, advance state sendbitpointer=0; sendbytepointer=0; sendstate=2; } } else if(sendstate==2) { if(sendmessage_size>=0 && sendbytepointer> (9-sendbitpointer); write_pin(sendpin,bit); sendbitpointer++; //advance pointer if(sendbitpointer>=10) { //if finished, advance bytepointer sendbitpointer=0; sendbytepointer++; } if(sendbytepointer>sendmessage_size) { //if finished with message, advance state to send ending byte sendbitpointer=0; sendbytepointer=0; sendstate=3; } } else { //size 0 message sendbitpointer=0; sendbytepointer=0; sendstate=3; } } else if(sendstate==3) { //send ending byte sendmessage_byte = 0; //if zero is received for more than 10 bits, end message bit = (sendmessage_byte & 1<<(9-sendbitpointer)) >> (9-sendbitpointer); write_pin(sendpin,bit); sendbitpointer++; //advance pointer if(sendbitpointer>=10) { //if finished, advance state sendbitpointer=0; sendbytepointer=0; sendstate=4; } } else if(sendstate==4) { clearsendqueue(); } else { //this shouldn't happen, but if it does, reset things clearsendqueue(); } return; } void amsswcomm::update_recv() { uint8_t bit; if(recvstate==0) { bit = read_pin(recvpin); if(bit==1) { recvstate=1; //advance to receive state recvbitpointer=1; recvmessage_byte = 0b0000001000000000; //set first leading bit recvbytepointer = 0; } } else if(recvstate==1) { bit = read_pin(recvpin); recvmessage_byte = recvmessage_byte + (bit<<(9-recvbitpointer)); recvbitpointer++; if(recvbitpointer>=10) { recvbitpointer = 0; if(recvmessage_byte = 0b0000001111111111) { recvstate = 2; recvmessage_byte = 0; recvbytepointer = 0; recvmessage_size = 0; } else { //byte received not part of message or garbled message, ignore recvstate = 0; recvbytepointer = 0; clearrecvqueue(); } } } else if(recvstate==2) { bit = read_pin(recvpin); recvmessage_byte = recvmessage_byte + (bit<<(9-recvbitpointer)); recvbitpointer++; if(recvbitpointer>=10) { if(recvmessage_byte==0) { //end of message byte has been received recvbitpointer = 0; recvbytepointer = 0; recvstate = 3; //has message recvmessage_byte = 0; } else { recvbitpointer = 0; recvmessage[recvbytepointer] = (uint8_t)(recvmessage_byte & 0b0000000011111111); recvbytepointer++; recvmessage_size++; recvmessage_byte = 0; } } } else if(recvstate==3) { //has message, do nothing and wait until message has been processed } else { clearrecvqueue(); } return; } bool amsswcomm::has_message() { if(recvstate==3) { return 1; } return 0; } //receives the message and resets the receive queue //return value is message size, or -1 for no message int amsswcomm::recv_message(char *outputbuff, int outputbuffsize) { int ret = -1; int I; if(has_message()) { ret = recvmessage_size; for(I=0;I