-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmorse.c
207 lines (193 loc) · 4.14 KB
/
morse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
/**
* Data
*/
/* Port that the blinky boi is on */
static const int blinky = 440;
/*
* IO Functions
*/
static FILE* fp = NULL;
void io_init(const int pin)
{
char path[64];
/* Open GPIO direction for writing */
sprintf(path,"/sys/class/gpio/gpio%d/direction",pin);
printf("Opening Direction file %s\n",path);
fp = fopen(path,"w");
if(!fp)
{
/* Must not be exported yet */
printf("GPIO not exported yet... doing that\n");
fp = fopen("/sys/class/gpio/export", "w");
if(!fp)
{
printf("ERROR: Failed to export IO\n");
exit(-1);
}
fprintf(fp, "%d", pin);
fclose(fp);
/* Now reopen the gpio file */
printf("Opening Direction file %s\n",path);
fp = fopen(path,"w");
if(!fp)
{
printf("ERROR: Failed to open GPIO direction\n");
exit(-1);
}
}
/* Write direction */
fprintf(fp,"out");
fclose(fp);
/* Open 'value' file */
sprintf(path,"/sys/class/gpio/gpio%d/value",pin);
printf("Opening Value file %s\n",path);
fp = fopen(path,"w");
if(!fp)
{
printf("ERROR: Failed to open GPIO value\n");
exit(-1);
}
/* Initialize LED to off */
fprintf(fp,"0");
fflush(fp);
}
void io_write(bool status)
{
fprintf(fp,(status) ? "1" : "0");
fflush(fp);
}
/* Float sleep function */
void fsleep(double dur)
{
struct timespec tim;
tim.tv_sec = 0;
tim.tv_nsec = dur * 1000000000.0;
nanosleep(&tim , NULL);
}
/*
* Morse Functions
*/
/* Base duration that the rest of the constants come from */
#define TIME_BASE 0.33
/* Duration of a dit and dah, dah should be 3x dit */
static const double time_dit = 1*(TIME_BASE);
static const double time_dah = 3*(TIME_BASE);
/* Space between symbols */
static const double time_space = 1*(TIME_BASE);
/* Space between letters minus space between symbols already slept */
static const double time_letter = (3-1)*(TIME_BASE);
/* Space between words, minus space between letters already slept*/
static const double time_word = (7-3)*(TIME_BASE);
/* Morse Code table in terms of dots+dashes
* The table itself is Huffman-coded, but before Huffman coding was a thing
* It's kinda neat
* But it means each letter is variable length
* So string-encode them
*/
static const char *morse_tbl[] = {
".-", //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
"-----", //0
".----", //1
"..---", //2
"...--", //3
"....-", //4
".....", //5
"-....", //6
"--...", //7
"---..", //8
"----.", //9
};
/* Function is only correct for letters and numbers, nothing else */
void morse_letter(const char let)
{
/* If it's a space, wait the space time and exit */
if(let == ' ')
{
printf("Space\n");
fsleep(time_word);
return;
}
/* Find the string from the table */
const char * pattern = ".";//Initialize to ensure it's always valid
if(let >= '0' && let <= '9')
{
pattern = morse_tbl[let - '0' + 26]; //For numbers
}
else if((let & 0x1F) >= 'A' || (let & 0x1F) <= 'Z')
{
pattern = morse_tbl[(let & 0x1F) - 1]; //For letters
}
else
{
printf("Invalid Letter %c\n",let);
return;
}
printf("Letter %c to morse %s\n",let,pattern);
/* Loop through remaining symbols and output them */
while(pattern[0])
{
/* Turn on output */
io_write(1);
/* Output on-time */
if(pattern[0] == '.')
{
fsleep(time_dit);
}
else
{
fsleep(time_dah);
}
/* Turn off output and wait off-time */
io_write(0);
fsleep(time_space);
/* Increment pointer */
pattern++;
};
/* Wait additional character delay */
fsleep(time_letter);
}
/* Output a string in morse code */
void morse(const char * string)
{
/* Output all letters in the string */
while(string[0])
{
morse_letter(string[0]);
string++;
}
}
int main (int argc, char** argv) {
printf("Hello from RISC-V!\n");
io_init(blinky);
morse("Hello World from RISC V");
return 0;
}