diff --git a/src/entrypoints/dsgamma-test.cpp b/src/entrypoints/dsgamma-test.cpp index 3d1f05a3d4d5f53ba5861e047429e700642f3ab4..36d11cbc4d406b28962db5e2a6c3c5b44dc36a56 100644 --- a/src/entrypoints/dsgamma-test.cpp +++ b/src/entrypoints/dsgamma-test.cpp @@ -26,12 +26,8 @@ using namespace std; using namespace miosix; - -/* - * STRANGE THING #1 (AKA BUG): - * Stack overflow if PKT_LEN in greater than 24 !!!!! - */ -#define PKT_LEN 14 +#define CMD_LEN 1 +#define DATA_LEN 64 typedef Gpio<GPIOG_BASE,13> greenLed; typedef Gpio<GPIOG_BASE,14> redLed; @@ -42,10 +38,14 @@ Gamma868 gamma("/dev/auxtty"); long long sendTime = 0; int nTentativi = 0; int tot = 0; +int state = 0; //0 = normal, 1 = sender, 2 = echo receiver -void sender(void *arg); +void btnClick(void *arg); +void stdInput(void *arg); void receiver(); + int main() { + gamma.start(); //!!!!!IMPORTANT!!!!!!!! //Discovery gpio setup { @@ -55,17 +55,17 @@ int main() { button::mode(Mode::INPUT); } - Thread::create(sender, STACK_MIN); - + //STACK_DEFAULT_FOR_PTHREAD is needed for printf()) + Thread::create(btnClick, STACK_DEFAULT_FOR_PTHREAD); + Thread::create(stdInput, STACK_DEFAULT_FOR_PTHREAD); receiver(); //Runs in a loop - return 0; } -void sender(void *arg){ +void btnClick(void *arg){ - char msg[PKT_LEN]; + char msg[CMD_LEN]; while(1){ @@ -74,55 +74,94 @@ void sender(void *arg){ if(button::value()==1) break; } - //Prepare a packet of PKT_LEN chars with all # - printf("Writing... \n"); - for(int i = 0; i < PKT_LEN; i++){ - msg[i] = '#'; - } + //---------------Send COMMAND---------------- + printf("Writing CMD... \n"); + msg[0] = (char) 10; + gamma.sendCmd(CMD_LEN, msg); + //------------------------------------------ + state = 1; + + printf("Ok \n" ); + Thread::sleep(200); + } +} + +void stdInput(void *arg){ + + char msg[DATA_LEN + 1]; + + while(1){ + + //Wait for button + scanf("%s", msg); //Save current time - sendTime = miosix::getTick(); - nTentativi++; + if(state == 1){ + sendTime = miosix::getTick(); + nTentativi++; + } - //Send - gamma.send(msg); + //----------------SEND DATA---------------- + gamma.send(DATA_LEN, msg); + //----------------------------------------- printf("Ok \n" ); Thread::sleep(200); } } +/* + * Continuosusly reads from the device. + */ void receiver(){ - int len = PKT_LEN; - char inputBuf[len]; - long long arrivalTime; + char inputBuf[DATA_LEN]; while(1){ //Read PKT_LEN bytes printf("Reading: \n"); - gamma.receive(len, inputBuf); + bool cmdReceived = gamma.receive(DATA_LEN, inputBuf); - //Print received chars - for(int i = 0; i < len ; i++){ - printf("Received: %c\n", inputBuf[i]); - } - - //Calculate Round Trip Time - arrivalTime = miosix::getTick(); + if(cmdReceived) + handleCommand(inputBuf); + else + handleData(inputBuf); + } +} + +void handleCommand(char *cmd){ + printf("Command received!\n"); + switch((int)cmd[0]){ + case 0: + state = 0; + break; + case 10: + state = 2; + break; + default: + printf("Unknown command\n"); + } +} + +void handleData(char *data){ + + long long arrivalTime = miosix::getTick(); + printf("Received: %s\n", data); + + + if(state == 2){ + gamma.send(DATA_LEN, data); + } else if (state == 1) { int rtt = arrivalTime - sendTime; printf("RTT: %d\n", rtt); - + printf("--------------RESULT------------"); tot += rtt; - + //Print Delay calculation if(nTentativi > 0) printf("Tentativi: %d Media: %d \n", nTentativi, tot/(2*nTentativi)); - - //------------------ RECEIVER ONLY ----------------- - gamma.send(inputBuf); - //-------------------------------------------------- + } } \ No newline at end of file diff --git a/src/shared/drivers/gamma868/Gamma868.cpp b/src/shared/drivers/gamma868/Gamma868.cpp index 08760408c8dd221c80fc724281f2cf43ab1ebfdb..5af89b281869ee07756bca3b4f764df189203a12 100644 --- a/src/shared/drivers/gamma868/Gamma868.cpp +++ b/src/shared/drivers/gamma868/Gamma868.cpp @@ -24,37 +24,179 @@ using namespace std; -#ifdef _MIOSIX - -#include <miosix.h> - -using namespace miosix; - -#endif //_MIOSIX - Gamma868::Gamma868(const char *serialPath) { fd=open(serialPath,O_RDWR); if(fd<0) printf("Cannot open %s\n", serialPath); + led::mode(Mode::INPUT); } -bool Gamma868::send(const char *msg) -{ - //TODO output buffer and synchronize - int length = strlen(msg); - write(fd, msg, length); + +/* + * Adds data to circular buffer (non blocking). + * Returns how many cahrs could be effectively stored in the buffer. + */ +int Gamma868::send(int msg_len, const char *msg) +{ + int retVal = 0; + if(last == -1) return false; + else + { + int i = 0; + pthread_mutex_lock(&bufMutex); + printf("Locked buffer mutex (send)\n"); + for(i = 0; i < msg_len; i++){ + buffer[last] = msg[last]; + last++; + if(last == MAX_BUFFER) last = 0; + if(last == first){ + last =-1; + break; + } + } + pthread_mutex_unlock(&bufMutex); + printf("Unocked buffer mutex (send)\n"); + retVal = i; + } + return retVal; +} + +/* + * Immediately sends command (blocking). + */ +bool Gamma868::sendCmd(int cmd_len, const char *cmd){ + + //TODO implement command length + char pkt[HEAD_LEN + cmd_len + END_LEN]; + + //Prepare packet + pkt[0] = START; + pkt[1] = CMD; + pkt[2] = cmd[0]; + pkt[HEAD_LEN + CMD_LEN] = END; + + //Send to gamma (synchronized) + pthread_mutex_lock(&writingMutex); + printf("Locked writing mutex (sendcmd)\n"); + write(fd, pkt, HEAD_LEN + cmd_len + END_LEN); + pthread_mutex_unlock(&writingMutex); + printf("Unocked writing mutex (sendcmd)\n"); + return true; } +/* + * Reads from the gamma868 serial. + */ bool Gamma868::receive(int bufLen, char *buf) { + char init = (char) 0; + char type = (char) 0; + char end = (char) 0; + bool cmd = false; + + //Read what you received (synchronized ?) pthread_mutex_lock(&readingMutex); - char received[bufLen+1]; - read(fd, &received, bufLen+1); + //First byte: start + while(init != START){ + read(fd, &init, 1); + } + //Second byte: type of data + read(fd, &type, 1); + if(type == DATA){ + read(fd, buf, bufLen); + }else if(type == CMD){ + read(fd, buf, CMD_LEN); + cmd = true; + } + //End byte + read(fd, &end, 1); + pthread_mutex_unlock(&readingMutex); - for(int i = 0; i < bufLen; i++){ - buf[i] = received[i]; + if(end!= END) + printf("Did not find end char! stream may be inconsistent\n"); + + return cmd; +} + +/* + * Reads from the circular buffer and, if there's something in the buffer, + * sends it in packets of fixed dimension, then until the end of transmission. + */ +void Gamma868::readFromBuffer(){ + while(1){ + if(bufSize() > 0){ + int nChar = bufSize() > 64 ? 64 : bufSize(); + + //Prepare header + char pkt[HEAD_LEN + DATA_LEN + END_LEN]; + pkt[0] = START; + pkt[1] = DATA; + //Copy from circular buffer (Synchronized) + pthread_mutex_lock(&bufMutex); + for(int i = 0; i < nChar; i++){ + pkt[i+HEAD_LEN] = buffer[first]; + first++; + if(first == MAX_BUFFER) + first = 0; + if(first == last){ + break; + } + } + pthread_mutex_unlock(&bufMutex); + pkt[DATA_LEN + HEAD_LEN] = END; + + //Send + pthread_mutex_lock(&writingMutex); + printf("Locked writing mutex (cycle)\n"); + Thread::create(&Gamma868::static_waitForLed, + STACK_DEFAULT_FOR_PTHREAD, + MAIN_PRIORITY, + reinterpret_cast<void*>(this)); + + write(fd, pkt, HEAD_LEN + DATA_LEN + END_LEN); + { + Lock<FastMutex> l(ledMutex); + while(sent==0) ledCond.wait(l); + sent = 0; + } + printf("Unocked writing mutex (cycle)\n"); + pthread_mutex_unlock(&writingMutex); + } - pthread_mutex_unlock(&readingMutex); - return true; + Thread::sleep(200); + } + +} + +/* + * Static wrapper for running it in a thread. + */ + + +void Gamma868::waitForLed(){ + bool sending = false; + while(1){ + if(led::value() == 1 && !sending){ + sending = true; + } + if(sending && led::value() == 0){ + Lock<FastMutex> l(ledMutex); + sent++; + ledCond.signal(); + break; + } + } +} + +/* + * Calculates the occupied portion of the circular buffer. + */ +unsigned int Gamma868::bufSize(){ + if(last == -1) + return MAX_BUFFER; + else if(last < first) + return MAX_BUFFER - (first - last); + else + return last - first; } \ No newline at end of file diff --git a/src/shared/drivers/gamma868/Gamma868.h b/src/shared/drivers/gamma868/Gamma868.h index 36169b74d0066bdebbce765768256208af8aace8..2512a557a197ea9f3618e0e289c5f4429b9d9410 100644 --- a/src/shared/drivers/gamma868/Gamma868.h +++ b/src/shared/drivers/gamma868/Gamma868.h @@ -29,20 +29,45 @@ #include <sys/stat.h> #include <fcntl.h> #include <string.h> +#ifdef _MIOSIX -struct Configuration{ - int local_addr[3] = {127, 127, 127}; - int dest_addr[3] = {127, 127, 127}; - int lora_mode = 6; - int lora_pow = 15; - int handshake = 0; - int baudrate = 4; -}; +#include <miosix.h> + +using namespace miosix; + +#endif //_MIOSIX + +#include "gamma_config.h" class Gamma868 { public: Gamma868(const char *serialPath); - bool send(const char *msg); + + /* + * Starts a thread that reads from the buffer and sends to the gamma module. + */ + void start(){ + Thread::create(&Gamma868::static_readFromBuffer, + STACK_DEFAULT_FOR_PTHREAD, + MAIN_PRIORITY, + reinterpret_cast<void*>(this)); + } + + /* + * Message goes in a queue (non blocking). + * Returns number of bytes effectively stored in the buffer. + */ + int send(int msg_len, const char *msg); + + /* + * Message is sent as soon as possible (blocking). + */ + bool sendCmd(int cmd_len, const char *cmd); + + /* + * Read from the Blocking. + * Returns true if the received stream is a command. + */ bool receive(int bufLen, char *buf); //~Gamma868(); @@ -54,14 +79,35 @@ class Gamma868 { * bool configure(Configuration newConf); * void exitLearnMode(); */ - - private: + private: int fd; pthread_t writeThread; pthread_mutex_t readingMutex; pthread_mutex_t writingMutex; - pthread_cond_t writingCond; + pthread_mutex_t bufMutex; + + FastMutex ledMutex; + ConditionVariable ledCond; + int sent=0; + + int first = 0; + int last = 0; + char buffer[MAX_BUFFER]; + + unsigned int bufSize(); + + void readFromBuffer(); + void waitForLed(); + + + static void* static_readFromBuffer(void * object){ + reinterpret_cast<Gamma868*>(object)->readFromBuffer(); + } + + static void* static_waitForLed(void * object){ + reinterpret_cast<Gamma868*>(object)->waitForLed(); + } }; #endif /* GAMMA868_H */ \ No newline at end of file diff --git a/src/shared/drivers/gamma868/gamma_config.h b/src/shared/drivers/gamma868/gamma_config.h new file mode 100644 index 0000000000000000000000000000000000000000..a7fdef4b72eff79e77a0bcf251dccb5f9797b19a --- /dev/null +++ b/src/shared/drivers/gamma868/gamma_config.h @@ -0,0 +1,32 @@ +#ifndef CONFIG_H +#define CONFIG_H + + + +#endif /* CONFIG_H */ + +//Object config +#define MAX_BUFFER 128 + +typedef Gpio<GPIOB_BASE,0> led; + +struct Configuration{ + int local_addr[3] = {127, 127, 127}; + int dest_addr[3] = {127, 127, 127}; + int lora_mode = 6; + int lora_pow = 15; + int handshake = 0; + int baudrate = 4; +}; + +//Protocol config +#define HEAD_LEN 2 +#define CMD_LEN 1 +#define DATA_LEN 64 +#define END_LEN 1 + +#define START '#' +#define CMD '!' +#define DATA '?' +#define END '%' +