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.
Dependencies: ELEC350-Practicals-FZ429
Fork of Task622Solution-mbedos54 by
Diff: main.cpp
- Revision:
- 2:70084af839d3
- Parent:
- 1:4fb27aea76b2
- Child:
- 3:423191a375dc
--- a/main.cpp Tue Mar 08 12:26:28 2016 +0000
+++ b/main.cpp Tue Mar 08 20:51:13 2016 +0000
@@ -1,13 +1,77 @@
#include "mbed.h"
#include "rtos.h"
+#include "string.h"
+#include <stdio.h>
+#include <ctype.h>
#define RED_DONE 1
#define YELLOW_DONE 2
+//Delays in ms
+#define TUNIT 250
+#define TDOT TUNIT
+#define TDASH (3*TUNIT)
+#define TGAP TUNIT
+#define TLETTER (3*TUNIT)
+#define TWORD (7*TUNIT)
-//Function declarations
-void countUP(void const *args);
-void countDOWN(void const *args);
+//Size of the morse character buffer
+#define BUFFERSIZE 240
+
+
+/*
+**** Morse Code ***
+
+. 1 unit
+- 3 units
+inter-space 1 unit
+
+between letters 3 units
+between words 7 units
+*/
+
+//Morse code
+const char* const morseAlpha[] = {
+ ".-", //A
+ "-...", //B
+ "-.-.", //C
+ "-..", //D
+ ".", //E
+ "..-.", //F
+ "--.", //G
+ "....", //H
+ "..", //I
+ ".---", //J
+ "-.-", //K
+ ".-..", //L
+ "--", //M
+ "-.", //N
+ "---", //O
+ ".--.", //P
+ "--.-", //Q
+ ".-.", //R
+ "...", //S
+ "-", //T
+ "..-", //U
+ "...-", //V
+ ".--", //W
+ "-..-", //X
+ "-.--", //Y
+ "--.." //Z
+};
+
+const char* const morseNumeric[] = {
+ "-----", //0
+ ".----", //1
+ "..---", //2
+ "...--", //3
+ "....-", //4
+ ".....", //5
+ "-....", //6
+ "--...", //7
+ "---..", //8
+ "----." //9
+};
//Digital outputs
DigitalOut onBoardLED(LED1);
@@ -15,112 +79,168 @@
DigitalOut yellowLED(D6);
DigitalOut greenLED(D5);
+//Serial Interface
+Serial pc(USBTX, USBRX);
+
//Digital inputs
DigitalIn onBoardSwitch(USER_BUTTON);
DigitalIn SW1(D4);
DigitalIn SW2(D3);
-//MUTEX Lock
-Mutex *countLock;
-
//Thread ID for the Main function (CMSIS API)
osThreadId tidMain;
-//Stared mutable state
-volatile long long count = 0;
+//Thread sychronisation primatives
+Semaphore *spaceAvailable;
+Semaphore *samplesInBuffer;
+Mutex *bufferLock;
+
+//Output buffer
+char buffer[BUFFERSIZE];
+unsigned int newestIndex = BUFFERSIZE-1; //First time it is incremented, it will be 0
+unsigned int oldestIndex = BUFFERSIZE-1;
-//Threads
-void countUP(void const *args)
-{
- redLED = 1;
-
- for (unsigned int n=0; n<10000; n++) {
- //Take lock
- countLock->lock();
+
+//Producer
+void addCharacterToQueue(const char c)
+{
+ //Is there space?
+ spaceAvailable->wait();
+
+ //Ok, there is space - take the lock
+ bufferLock->lock();
+ redLED = 1;
- //Critical section(s)
- count++;
- count++;
- count++;
- count++;
- count++;
- count++;
- count++;
- count++;
- count++;
- count++;
+ //Update buffer
+ newestIndex = (newestIndex+1) % BUFFERSIZE;
+ buffer[newestIndex] = c;
+
+ //Release lock
+ bufferLock->unlock();
+ redLED = 0;
+
+ //Signal that a sample has been added
+ samplesInBuffer->release();
+}
+
+//Consumer
+char takeCharacterFromQueue()
+{
+ //Are thre any samples in the buffer
+ samplesInBuffer->wait();
- //Release lock
- countLock->unlock();
- }
+ //Ok, there are samples - take the lock
+ bufferLock->lock();
+ yellowLED = 1;
+
+ //Update buffer - remove oldest
+ oldestIndex = (oldestIndex+1) % BUFFERSIZE;
+ char cc = buffer[oldestIndex];
- redLED = 0;
- osSignalSet(tidMain, RED_DONE); //Signal main thread we are done
+ //Release lock
+ bufferLock->unlock();
+ yellowLED = 0;
+
+ //Signal there is space in the buffer
+ spaceAvailable->release();
+
+ //return a copy of the result
+ return cc;
}
-void countDOWN(void const *args)
+void morseGenerator( const void* arg )
{
- yellowLED = 1;
-
- for (unsigned int n=0; n<10000; n++) {
- //Take lock
- countLock->lock();
+ while (true) {
+
+ //Are there samples available?
+ char nextChar = takeCharacterFromQueue();
+ nextChar = tolower(nextChar);
+
+ //Look up morse code
+
+ //Space between words - assumes only one
+ if (nextChar == ' ') {
+ Thread::wait(TWORD-TLETTER);
+ continue;
+ }
+
+ //Number?
+ const char *nextString;
+ if ((nextChar >= '0') && (nextChar <= '9')) {
+ nextString = morseNumeric[nextChar - '0'];
+ }
+ //Character?
+ else if ((nextChar >='a') && (nextChar <= 'z')) {
+ nextString = morseAlpha[nextChar - 'a'];
+ } else {
+ //Invalid
+ continue;
+ }
- //Critical section(s)
- count--;
- count--;
- count--;
- count--;
- count--;
- count--;
- count--;
- count--;
- count--;
- count--;
+ //Flash morse for this letter
+ for (unsigned int n=0; n<strlen(nextString); n++) {
+ char symb = nextString[n];
+ greenLED = 1;
+ switch (symb) {
+ case '.':
+ Thread::wait(TDOT);
+ break;
+ case '-':
+ Thread::wait(TDASH);
+ break;
+ default:
+ break;
+ }
+ greenLED = 0;
+
+ //A gap between symbols
+ Thread::wait(TGAP);
+ }
- //Release lock
- countLock->unlock();
- }
-
- osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done
- yellowLED = 0;
+ //Gap between letters
+ Thread::wait(TLETTER-TGAP);
+
+ }
}
+void convertToMorseAsync(const char* pString)
+{
+ //Copy each character into the buffer
+ int L = strlen(pString);
+ for (int n=0; n<L; n++) {
+ char c = pString[n];
+ addCharacterToQueue(c);
+ }
+}
+
//Main thread
int main() {
redLED = 0;
yellowLED = 0;
- greenLED = 1;
+ greenLED = 0;
+
+ //Semaphores
+ bufferLock = new Mutex();
+ spaceAvailable = new Semaphore(BUFFERSIZE);
+ samplesInBuffer = new Semaphore(0);
+
//Main thread ID
tidMain = Thread::gettid();
- //Create lock
- countLock = new Mutex();
+
+ //Thread for outputting mors
+ Thread writer(morseGenerator);
- //Press the switch to run concurrently
- if (onBoardSwitch == 1) {
- printf("Running sequntially\n");
- countUP(NULL);
- countDOWN(NULL);
- } else {
- printf("Running concurrently\n");
- Thread t1(countUP);
- Thread t2(countDOWN);
-
- //Wait for the ALL_ON signal
- Thread::signal_wait(RED_DONE,osWaitForever);
- Thread::signal_wait(YELLOW_DONE,osWaitForever);
+ pc.printf("Type characters to send\n");
+ while (true) {
+ //Read keyboard (serial port)
+ char c = pc.getc();
+ pc.printf("\n");
+ addCharacterToQueue(c);
}
- printf("Final result = %lld\n", count);
- if (count == 0) {
- greenLED = 0;
- }
-
- //Tidy
- delete countLock;
-
- while(true);
}
+
+
