diff --git a/src/entrypoints/dsgamma-test.cpp b/src/entrypoints/dsgamma-test.cpp index f21f69617da7b453ec85c4837fdb3daad5152399..2bc1be55b006c8cd58a85a2e18d1d4a19e9ab60f 100644 --- a/src/entrypoints/dsgamma-test.cpp +++ b/src/entrypoints/dsgamma-test.cpp @@ -22,28 +22,36 @@ #include "miosix.h" #include <drivers/gamma868/Gamma868.h> +#include <stdio.h> +#include <string.h> using namespace std; using namespace miosix; +#define SENDER 1 +#define ECHO_RECEIVER 2 +#define NORMAL 0 + /* DISCOVERY F429I*/ typedef Gpio<GPIOG_BASE,13> greenLed; typedef Gpio<GPIOG_BASE,14> redLed; typedef Gpio<GPIOA_BASE,0> button; -Gamma868 gamma("/dev/auxtty"); //create object +Gamma868 gamma("/dev/auxtty"); //create gamma object +//RTT calculation long long sendTime = 0; int nTentativi = 0; int tot = 0; -int state = 0; //0 = normal, 1 = sender, 2 = echo receiver +int state = NORMAL; +int charSent = 0; void btnClick(void *arg); -void stdInput(void *arg); +void stdInput(); void handleCommand(char *cmd); void handleData(char *data); -void receiver(); +void receiver(void *arg); int main() { gamma.start(); //!!!!!IMPORTANT!!!!!!!! @@ -58,12 +66,15 @@ int main() { //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 + Thread::create(receiver, STACK_DEFAULT_FOR_PTHREAD); + stdInput(); //Runs in a loop return 0; } +/* + * Handles the button click (send an echo command). + */ void btnClick(void *arg){ char msg[CMD_LEN]; @@ -80,16 +91,18 @@ void btnClick(void *arg){ msg[0] = (char) 10; gamma.sendCmd(CMD_LEN, msg); //------------------------------------------ - state = 1; - printf("Ok \n" ); - Thread::sleep(200); + + Thread::sleep(200); } } -void stdInput(void *arg){ +/* + * Handles standard input (sends the string). + */ +void stdInput(){ - char msg[DATA_LEN + 1]; + char msg[100 + 1]; while(1){ @@ -97,31 +110,38 @@ void stdInput(void *arg){ scanf("%s", msg); //Save current time - if(state == 1){ - sendTime = miosix::getTick(); - nTentativi++; + if(state == SENDER && msg[0] == 'a'){ + for(int i = 0; i < 10; i++) + { + for(int j = 0; j < MIN_TO_SEND; j++) + { + msg[j] = (char) j; + + } + gamma.send(MIN_TO_SEND, msg); + sendTime = miosix::getTick(); + nTentativi++; + Thread::sleep(1000); + } } //----------------SEND DATA---------------- - gamma.send(strlen(msg), msg); + //gamma.send(strlen(msg), msg); //----------------------------------------- printf("Ok \n" ); - Thread::sleep(200); } } /* - * Continuosusly reads from the device. + * Continuously reads from the device. */ -void receiver(){ +void receiver(void *arg){ char inputBuf[DATA_LEN]; while(1){ - - //Read PKT_LEN bytes - printf("Reading: \n"); + printf("Reading: \n"); bool cmdReceived = gamma.receive(DATA_LEN, inputBuf); if(cmdReceived) @@ -131,27 +151,41 @@ void receiver(){ } } + +cd ~/skyward/Skyward-boardcore/bin/dsgamma-config +&& +openocd -f interface/stlink-v2.cfg -c "set WORKAREASIZE 0x2000" -f target/stm32f4x_stlink.cfg -c "program dsgamma-config.elf verify reset exit" + void handleCommand(char *cmd){ printf("Command received!\n"); + char c = (char)20; switch((int)cmd[0]){ - case 0: - state = 0; - break; - case 10: - state = 2; - break; - default: - printf("Unknown command\n"); - } + case 0: + state = NORMAL; + break; + case 10: + state = ECHO_RECEIVER; + gamma.sendCmd(1, &c); + break; + case 20: + printf("ACK\n"); + state = SENDER; + break; + default: + printf("Unknown command\n"); + } } void handleData(char *data){ long long arrivalTime = miosix::getTick(); - printf("Received: %s\n", data); - + printf("Received: "); + for(int i = 0; i < DATA_LEN; i++){ + printf("%c", data[i]); + } + printf("\n"); - if(state == 2){ + if(state == ECHO_RECEIVER){ gamma.send(DATA_LEN, data); } else if (state == 1) { int rtt = arrivalTime - sendTime; diff --git a/src/shared/drivers/gamma868/Gamma868.cpp b/src/shared/drivers/gamma868/Gamma868.cpp index 2a544f101798007021f4cb53696a5233d8ad9fdd..acdc7eb9f0d0b0d0ba85fe2d02d352002802386d 100644 --- a/src/shared/drivers/gamma868/Gamma868.cpp +++ b/src/shared/drivers/gamma868/Gamma868.cpp @@ -21,16 +21,16 @@ */ #include "Gamma868.h" - -using namespace std; +#include "miosix.h" /* * A serial port attached to the Gamma868 RX and TX pins is expected * to be passed to the object in order to communicate with the device. - * NOTE that the serial port has to be already open and at the baudrate + * + * NOTE: The serial port has to be already open and at the baudrate * at which the module has been configured (default is 9600 baud). * - * The object also uses 2 other pins, gammaSwitch and gammaLed, which are + * NOTE: The object also uses 2 other pins, gammaSwitch and gammaLed, which are * defined in the gamma_config.h file. */ Gamma868::Gamma868(const char *serialPath) @@ -38,44 +38,27 @@ Gamma868::Gamma868(const char *serialPath) fd=open(serialPath,O_RDWR); if(fd<0) printf("Cannot open %s\n", serialPath); gammaLed::mode(Mode::INPUT); + gammaSwitch::mode(Mode::OUTPUT); + gammaSwitch::high(); } /* - * Adds data to circular buffer (non blocking). - * Returns how many cahrs could be effectively stored in the buffer. + * Adds data to the output buffer (non blocking). + * Returns how many chars could be effectively stored in the buffer. */ -int Gamma868::send(int msg_len, const char *msg) +unsigned int Gamma868::send(unsigned int msg_len, const char *msg) { - int retVal = 0; - if(last == -1) return false; - else - { - int i = 0; - pthread_mutex_lock(&bufMutex); - for(i = 0; i < msg_len; i++){ - buffer[last] = msg[i]; - last++; - if(last == MAX_BUFFER) last = 0; - if(last == first){ - last =-1; - break; - } - } - pthread_mutex_unlock(&bufMutex); - - retVal = i; - } - return retVal; + return outBuffer.write(msg_len, msg); } /* * Immediately sends command (blocking). */ -bool Gamma868::sendCmd(int cmd_len, const char *cmd){ +bool Gamma868::sendCmd(int cmd_len, const char *cmd) +{ - //TODO implement command length char pkt[HEAD_LEN + cmd_len + END_LEN]; //Prepare packet @@ -84,7 +67,7 @@ bool Gamma868::sendCmd(int cmd_len, const char *cmd){ pkt[2] = cmd[0]; pkt[HEAD_LEN + CMD_LEN] = END; - //Send to gamma (synchronized) + //Send to gamma pthread_mutex_lock(&writingMutex); write(fd, pkt, HEAD_LEN + cmd_len + END_LEN); pthread_mutex_unlock(&writingMutex); @@ -93,7 +76,7 @@ bool Gamma868::sendCmd(int cmd_len, const char *cmd){ } /* - * Reads from the gamma868 serial. + * Reads from the gamma868 serial. (blocking) */ bool Gamma868::receive(int bufLen, char *buf) { @@ -102,23 +85,25 @@ bool Gamma868::receive(int bufLen, char *buf) char end = (char) 0; bool cmd = false; - //Read what you received (synchronized ?) - //First byte: start + //Read until you find the start byte. while(init != START){ read(fd, &init, 1); } - pthread_mutex_lock(&readingMutex); - //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_lock(&readingMutex); //TODO is sync needed? + + //Read second byte (type of data) + read(fd, &type, 1); + if(type == DATA){ + read(fd, buf, bufLen); //If it's data, read all the bufLen chars + }else if(type == CMD){ + read(fd, buf, CMD_LEN); //If it's a command, just read 1 char + cmd = true; + } + + //End byte + read(fd, &end, 1); + pthread_mutex_unlock(&readingMutex); if(end!= END) @@ -128,88 +113,66 @@ bool Gamma868::receive(int bufLen, char *buf) } /* - * 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. + * Continuously checks the buffer and, if there's something in it, sends + * it in packets of fixed dimension, waiting each time until the end of transmission. */ -void Gamma868::readFromBuffer(){ - while(1){ //Continuously check the buffer +void Gamma868::writerThreadTask() +{ + while(1) + { + if(outBuffer.size() >= MIN_TO_SEND) + { + //Prepare header + char pkt[HEAD_LEN + DATA_LEN + END_LEN]; + pkt[0] = START; + pkt[1] = DATA; + + //Send in packets of fixed size + while(outBuffer.size() >= MIN_TO_SEND) + { + //Read from the buffer + outBuffer.read(DATA_LEN, pkt, 2); + pkt[DATA_LEN + HEAD_LEN] = END; + + //Start thread that will notify when the device has finished transmission + Thread::create(&Gamma868::static_waitForLed, + STACK_DEFAULT_FOR_PTHREAD, + MAIN_PRIORITY, + reinterpret_cast<void*>(this)); + //Send + pthread_mutex_lock(&writingMutex); + write(fd, pkt, HEAD_LEN + DATA_LEN + END_LEN); + //TODO start timeout + { + Lock<FastMutex> l(ledMutex); + while(pktSent==0) ledCond.wait(l); //waitForLed will change the variable. + pktSent = 0; + } + pthread_mutex_unlock(&writingMutex); + } - if(bufSize() > MIN_TO_SEND){ //If there's something in it... - - while(bufSize() > 0){ //Read and send all the buffer - //Prepare header - char pkt[HEAD_LEN + DATA_LEN + END_LEN]; - pkt[0] = START; - pkt[1] = DATA; - - pthread_mutex_lock(&bufMutex); //Lock the buffer - int nChar = bufSize() > 64 ? 64 : bufSize(); - - //Copy from circular buffer - 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; - - //Start thread that will notify the end of the message sending - Thread::create(&Gamma868::static_waitForLed, - STACK_DEFAULT_FOR_PTHREAD, - MAIN_PRIORITY, - reinterpret_cast<void*>(this)); - //Send - pthread_mutex_lock(&writingMutex); - - write(fd, pkt, HEAD_LEN + DATA_LEN + END_LEN); - - { - Lock<FastMutex> l(ledMutex); - while(sent==0) ledCond.wait(l); - sent = 0; - } - pthread_mutex_unlock(&writingMutex); - } - Thread::sleep(200); //TODO needed? - } - + //Wait some time (set in gamma_config) before checking the buffer again + Thread::sleep(SEND_SLEEP_TIME); + } } } /* - * Static wrapper for running it in a thread. + * Changes the associated condition variable when the device's led goes off. + * TODO put it inside the function? */ - - void Gamma868::waitForLed(){ bool sending = false; while(1){ - if(gammaLed::value() == 1 && !sending){ + if(gammaLed::value() == 1 /*&& !sending*/){ sending = true; } - if(sending && gammaLed::value() == 0){ + if(/*sending &&*/ gammaLed::value() == 0){ Lock<FastMutex> l(ledMutex); - sent++; + pktSent++; 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 43cc71f12d6246697d6ed13a06e5f06571441889..32384032460cd79df831c02a260bd41126360770 100644 --- a/src/shared/drivers/gamma868/Gamma868.h +++ b/src/shared/drivers/gamma868/Gamma868.h @@ -29,15 +29,14 @@ #include <sys/stat.h> #include <fcntl.h> #include <string.h> -#ifdef _MIOSIX +#ifdef _MIOSIX #include <miosix.h> - using namespace miosix; - #endif //_MIOSIX -#include "gamma_config.h" +#include "CircularBuffer.h" +#include "gamma_config.h" //Defines are in here. class Gamma868 { public: @@ -47,7 +46,7 @@ class Gamma868 { * Starts a thread that reads from the buffer and sends to the gamma module. */ void start(){ - Thread::create(&Gamma868::static_readFromBuffer, + writerThread = Thread::create(&Gamma868::static_writerThreadTask, STACK_DEFAULT_FOR_PTHREAD, MAIN_PRIORITY, reinterpret_cast<void*>(this)); @@ -57,7 +56,7 @@ class Gamma868 { * Message goes in a queue (non blocking). * Returns number of bytes effectively stored in the buffer. */ - int send(int msg_len, const char *msg); + unsigned int send(unsigned int msg_len, const char *msg); /* * Message is sent as soon as possible (blocking). @@ -69,6 +68,7 @@ class Gamma868 { * Returns true if the received stream is a command. */ bool receive(int bufLen, char *buf); + //~Gamma868(); /* @@ -82,44 +82,35 @@ class Gamma868 { private: int fd; - pthread_t writeThread; + CircularBuffer outBuffer; + Thread *writerThread; + pthread_mutex_t readingMutex; pthread_mutex_t writingMutex; - pthread_mutex_t bufMutex; FastMutex ledMutex; ConditionVariable ledCond; - int sent=0; - - int first = 0; - int last = 0; - char buffer[MAX_BUFFER]; + int pktSent=0; - unsigned int bufSize(); - - void readFromBuffer(); + void writerThreadTask(); void waitForLed(); - - static void* static_readFromBuffer(void * object){ - reinterpret_cast<Gamma868*>(object)->readFromBuffer(); + /* + * Static wrapper for running it in a thread. + */ + static void* static_writerThreadTask(void * object){ + reinterpret_cast<Gamma868*>(object)->writerThreadTask(); + return 0; } + /* + * Static wrapper for running it in a thread. + */ static void* static_waitForLed(void * object){ reinterpret_cast<Gamma868*>(object)->waitForLed(); + return 0; } - - void printBufContent(){ - printf("Buffer: first %d last %d occupied %u total size %d\n", - first, last, bufSize(), MAX_BUFFER); - - int offset = first; - for (int i = 0; i < MAX_BUFFER; i++){ - if (offset + i == MAX_BUFFER) offset = -i; - printf("%c", buffer[i]); - } - printf("\n"); - } + }; #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 index 04d055c4767fa1733e3dd9ffe48258b229b3b2e4..fcc4c57782c15b9f51fcc3c3cfd93eee44043f87 100644 --- a/src/shared/drivers/gamma868/gamma_config.h +++ b/src/shared/drivers/gamma868/gamma_config.h @@ -2,12 +2,11 @@ #define CONFIG_H - -#endif /* CONFIG_H */ - +//DISCOVERY gpio configuration typedef Gpio<GPIOB_BASE,0> gammaLed; typedef Gpio<GPIOB_BASE,2> gammaSwitch; +//Module internal config struct Configuration{ int local_addr[3] = {126, 126, 126}; int dest_addr[3] = {126, 126, 126}; @@ -17,14 +16,21 @@ struct Configuration{ int baudrate = 0; //9600 baud }; -//Object config -#define MAX_BUFFER 128 -#define MIN_TO_SEND 1 +//Buffer config +#define OUT_BUFFER_SIZE 10 + +/* + * Change this if you want to send even if the buffer contains + * less chars than the packet (note that the packet has fixed size). + */ +#define MIN_TO_SEND 5 + +#define SEND_SLEEP_TIME 0 //Protocol config #define HEAD_LEN 2 #define CMD_LEN 1 -#define DATA_LEN 64 +#define DATA_LEN 5 #define END_LEN 1 #define START '#' @@ -32,3 +38,4 @@ struct Configuration{ #define DATA '?' #define END '%' +#endif \ No newline at end of file