Removed Ultimatic keyer mode. Added digital outputs for keyer and PTT (T/R switch) lines. Streamlined the code for the semaphores. Made it more configurable / less #defines.
This commit is contained in:
parent
9892ccb1a4
commit
1b4775f452
@ -1 +1 @@
|
|||||||
#Quisk version 4.1.52
|
#Quisk version 4.1.52-upr1
|
||||||
|
246
gpiokeyer.c
246
gpiokeyer.c
@ -68,7 +68,7 @@ Boston, MA 02110-1301, USA.
|
|||||||
Speed calculation - Using standard PARIS timing, dot_period(mS) = 1200/WPM
|
Speed calculation - Using standard PARIS timing, dot_period(mS) = 1200/WPM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define DEBUG
|
#define DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -90,16 +90,20 @@ static void* keyer_thread(void *arg);
|
|||||||
static pthread_t keyer_thread_id;
|
static pthread_t keyer_thread_id;
|
||||||
|
|
||||||
// GPIO pins
|
// GPIO pins
|
||||||
#define KEYER_OUT_GPIO 26
|
//#define LEFT_PADDLE_GPIO 22
|
||||||
#define LEFT_PADDLE_GPIO 22
|
//#define RIGHT_PADDLE_GPIO 27
|
||||||
#define RIGHT_PADDLE_GPIO 27
|
//#define KEY_OUT_GPIO 23
|
||||||
|
//#define PTT_OUT_GPIO 24
|
||||||
|
static int left_paddle_gpio = 22;
|
||||||
|
static int right_paddle_gpio = 27;
|
||||||
|
static int keyer_out_gpio = 23;
|
||||||
|
static int tr_switch_gpio = 24;
|
||||||
|
|
||||||
// Keyer modes
|
// Keyer modes
|
||||||
#define KEYER_STRAIGHT 0
|
#define KEYER_STRAIGHT 0
|
||||||
#define KEYER_MODE_A 1
|
#define KEYER_MODE_A 1
|
||||||
#define KEYER_MODE_B 2
|
#define KEYER_MODE_B 2
|
||||||
#define KEYER_ULTIMATIC 3
|
#define NUM_KEYER_MODES 3
|
||||||
#define NUM_KEYER_MODES 4
|
|
||||||
|
|
||||||
#define NSEC_PER_SEC (1000000000)
|
#define NSEC_PER_SEC (1000000000)
|
||||||
|
|
||||||
@ -114,42 +118,45 @@ enum {
|
|||||||
DOTHELD,
|
DOTHELD,
|
||||||
DASHHELD,
|
DASHHELD,
|
||||||
LETTERSPACE,
|
LETTERSPACE,
|
||||||
|
HANGTIME,
|
||||||
EXITLOOP
|
EXITLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
NONE = 0,
|
|
||||||
DOT = 1,
|
|
||||||
DASH = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static int dot_memory = 0;
|
static int dot_memory = 0;
|
||||||
static int dash_memory = 0;
|
static int dash_memory = 0;
|
||||||
static int key_state = 0;
|
static int key_state = 0;
|
||||||
static int kdelay = 0;
|
static int kdelay = 0;
|
||||||
static int dot_delay = 0;
|
static int dot_delay = 0;
|
||||||
static int dash_delay = 0;
|
static int dash_delay = 0;
|
||||||
static int kcwl = 0;
|
static volatile int kcwl = 0;
|
||||||
static int kcwr = 0;
|
static volatile int kcwr = 0;
|
||||||
static int *kdot;
|
static int *kdot;
|
||||||
static int *kdash;
|
static int *kdash;
|
||||||
static int cw_keyer_speed = 20;
|
static int cw_keyer_speed = 20;
|
||||||
static int cw_keyer_weight = 55;
|
static int cw_keyer_weight = 55;
|
||||||
static int cw_keys_reversed = 0;
|
static int cw_keys_reversed = 0;
|
||||||
static int cw_keyer_mode = KEYER_MODE_B;
|
static int cw_keyer_mode = KEYER_MODE_A;
|
||||||
static int cw_keyer_spacing = 0;
|
static int cw_keyer_spacing = 0;
|
||||||
static int cw_active_state = 0;
|
static int cw_active_state = 0;
|
||||||
static sem_t cw_event;
|
static sem_t cw_event;
|
||||||
|
#if defined(DEBUG)
|
||||||
static int last_pressed = NONE;
|
static int cw_event_value;
|
||||||
|
#endif
|
||||||
|
static int cw_hangtime_msec = 250;
|
||||||
|
|
||||||
static int running, keyer_out = 0;
|
static int running, keyer_out = 0;
|
||||||
|
|
||||||
static inline int kstate() {
|
// Function prototypes
|
||||||
return (*kdash<<1)&(*kdot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int prev_state = 0;
|
void keyer_update(void);
|
||||||
|
void keyer_event(int, int, uint32_t);
|
||||||
|
void keyer_event_left(void);
|
||||||
|
void keyer_event_right(void);
|
||||||
|
void clear_memory(void);
|
||||||
|
static void set_keyer_out(int);
|
||||||
|
static void* keyer_thread(void*);
|
||||||
|
|
||||||
|
/////
|
||||||
|
|
||||||
void keyer_update() {
|
void keyer_update() {
|
||||||
dot_delay = 1200 / cw_keyer_speed;
|
dot_delay = 1200 / cw_keyer_speed;
|
||||||
@ -163,49 +170,42 @@ void keyer_update() {
|
|||||||
kdot = &kcwl;
|
kdot = &kcwl;
|
||||||
kdash = &kcwr;
|
kdash = &kcwr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// need to actually dynamically set this at some point...
|
||||||
|
cw_hangtime_msec = (int)(0.25f * 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyer_event(int gpio, int level, uint32_t tick) {
|
void keyer_event(int gpio, int level, uint32_t tick) {
|
||||||
int state = (cw_active_state == 0) ? (level == 0) : (level != 0);
|
int state = (cw_active_state == 0) ? (level == 0) : (level != 0);
|
||||||
int okdash = *kdash;
|
|
||||||
int okdot = *kdot;
|
|
||||||
int new_state;
|
|
||||||
|
|
||||||
if (gpio == LEFT_PADDLE_GPIO)
|
if (gpio == left_paddle_gpio)
|
||||||
kcwl = state;
|
kcwl = state;
|
||||||
else // RIGHT_PADDLE_GPIO
|
else // RIGHT_PADDLE_GPIO
|
||||||
kcwr = state;
|
kcwr = state;
|
||||||
|
|
||||||
if (*kdash > okdash)
|
if (state) // || cw_keyer_mode == KEYER_STRAIGHT)
|
||||||
last_pressed = DASH;
|
|
||||||
else if (*kdot > okdot)
|
|
||||||
last_pressed = DOT;
|
|
||||||
else {
|
|
||||||
new_state = kstate();
|
|
||||||
last_pressed = new_state & prev_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state || cw_keyer_mode == KEYER_STRAIGHT)
|
|
||||||
sem_post(&cw_event);
|
sem_post(&cw_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Added to support WiringPi, which uses a different type of callback.
|
// Added to support WiringPi, which uses a different type of callback.
|
||||||
void keyer_event_left()
|
void keyer_event_left()
|
||||||
{
|
{
|
||||||
int level = digitalRead(LEFT_PADDLE_GPIO);
|
int level = digitalRead(left_paddle_gpio);
|
||||||
keyer_event(LEFT_PADDLE_GPIO, level, 0);
|
keyer_event(left_paddle_gpio, level, 0);
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("Left Paddle Pressed\n");
|
sem_getvalue(&cw_event, &cw_event_value);
|
||||||
|
fprintf(stdout, "left paddle pressed - %d\n", cw_event_value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Added to support WiringPi, which uses a different type of callback.
|
// Added to support WiringPi, which uses a different type of callback.
|
||||||
void keyer_event_right()
|
void keyer_event_right()
|
||||||
{
|
{
|
||||||
int level = digitalRead(RIGHT_PADDLE_GPIO);
|
int level = digitalRead(right_paddle_gpio);
|
||||||
keyer_event(RIGHT_PADDLE_GPIO, level, 0);
|
keyer_event(right_paddle_gpio, level, 0);
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("Right Paddle Pressed\n");
|
sem_getvalue(&cw_event, &cw_event_value);
|
||||||
|
fprintf(stdout, "right paddle pressed - %d\n", cw_event_value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,38 +215,62 @@ void clear_memory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void set_keyer_out(int state) {
|
static void set_keyer_out(int state) {
|
||||||
// if (keyer_out != state) {
|
if (state && tr_switch_gpio) {
|
||||||
keyer_out = state;
|
digitalWrite(tr_switch_gpio, 1);
|
||||||
// write(1, &buf[state], 1); // write output to stdout for Pi-HFIQ
|
}
|
||||||
|
keyer_out = state;
|
||||||
// if (state)
|
digitalWrite(keyer_out_gpio, keyer_out);
|
||||||
// beep_mute = 0;
|
|
||||||
// else
|
|
||||||
// beep_mute = 1;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* keyer_thread(void *arg) {
|
static void* keyer_thread(void *arg) {
|
||||||
struct timespec loop_delay;
|
struct timespec loop_delay;
|
||||||
int interval = 1000000; // 1 ms
|
int interval = 1000000; // 1 ms
|
||||||
|
int hangtime_elapsed = 0;
|
||||||
|
|
||||||
while(running) {
|
while (running) {
|
||||||
|
#if defined(DEBUG)
|
||||||
|
sem_getvalue(&cw_event, &cw_event_value);
|
||||||
|
fprintf(stdout, "waiting - %d\n", cw_event_value);
|
||||||
|
#endif
|
||||||
sem_wait(&cw_event);
|
sem_wait(&cw_event);
|
||||||
key_state = CHECK;
|
key_state = CHECK;
|
||||||
|
|
||||||
while (key_state != EXITLOOP) {
|
while (key_state != EXITLOOP) {
|
||||||
|
if (keyer_out)
|
||||||
|
hangtime_elapsed = 0;
|
||||||
|
|
||||||
switch(key_state) {
|
switch(key_state) {
|
||||||
|
|
||||||
|
case HANGTIME:
|
||||||
|
if (hangtime_elapsed >= cw_hangtime_msec) {
|
||||||
|
if (tr_switch_gpio) {
|
||||||
|
#if defined(DEBUG)
|
||||||
|
sem_getvalue(&cw_event, &cw_event_value);
|
||||||
|
fprintf(stdout, "hangtime complete, %d msec - %d\n", cw_hangtime_msec, cw_event_value);
|
||||||
|
#endif
|
||||||
|
digitalWrite(tr_switch_gpio, 0);
|
||||||
|
key_state = EXITLOOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// INTENTIONALLY FALLING THROUGH TO 'CHECK' STATE (no 'break')
|
||||||
|
|
||||||
case CHECK: // check for key press
|
case CHECK: // check for key press
|
||||||
if (cw_keyer_mode == KEYER_STRAIGHT) { // Straight/External key or bug
|
if (cw_keyer_mode == KEYER_STRAIGHT) { // Straight/External key or bug
|
||||||
if (*kdash) { // send manual dashes
|
if (*kdash) { // send manual dashes
|
||||||
set_keyer_out(1);
|
if (!keyer_out) {
|
||||||
key_state = EXITLOOP;
|
set_keyer_out(1);
|
||||||
|
key_state = HANGTIME; //EXITLOOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (*kdot) // and automatic dots
|
else if (*kdot) // and automatic dots
|
||||||
key_state = PREDOT;
|
key_state = PREDOT;
|
||||||
else {
|
else if (key_state == HANGTIME) {
|
||||||
set_keyer_out(0);
|
if (keyer_out)
|
||||||
|
set_keyer_out(0);
|
||||||
|
} else {
|
||||||
|
// NOTE: not working right
|
||||||
|
//set_keyer_out(0);
|
||||||
key_state = EXITLOOP;
|
key_state = EXITLOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,16 +279,19 @@ static void* keyer_thread(void *arg) {
|
|||||||
key_state = PREDOT;
|
key_state = PREDOT;
|
||||||
else if (*kdash)
|
else if (*kdash)
|
||||||
key_state = PREDASH;
|
key_state = PREDASH;
|
||||||
else {
|
else if (key_state != HANGTIME) {
|
||||||
set_keyer_out(0);
|
// Do we really need to do this? Aren't these covered in other states?
|
||||||
|
//set_keyer_out(0);
|
||||||
key_state = EXITLOOP;
|
key_state = EXITLOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREDOT: // need to clear any pending dots or dashes
|
case PREDOT: // need to clear any pending dots or dashes
|
||||||
clear_memory();
|
clear_memory();
|
||||||
key_state = SENDDOT;
|
key_state = SENDDOT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREDASH:
|
case PREDASH:
|
||||||
clear_memory();
|
clear_memory();
|
||||||
key_state = SENDDASH;
|
key_state = SENDDASH;
|
||||||
@ -288,11 +315,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*kdash) { // set dash memory
|
if (*kdash) { // set dash memory
|
||||||
if (cw_keyer_mode == KEYER_ULTIMATIC) {
|
dash_memory = 1;
|
||||||
if (last_pressed == DASH)
|
|
||||||
dash_memory = 1;
|
|
||||||
} else
|
|
||||||
dash_memory = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -314,11 +337,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*kdot) { // set dot memory
|
if (*kdot) { // set dot memory
|
||||||
if (cw_keyer_mode == KEYER_ULTIMATIC) {
|
dot_memory = 1;
|
||||||
if (last_pressed == DOT)
|
|
||||||
dot_memory = 1;
|
|
||||||
} else
|
|
||||||
dot_memory = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -327,7 +346,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
if (kdelay == dot_delay) {
|
if (kdelay == dot_delay) {
|
||||||
kdelay = 0;
|
kdelay = 0;
|
||||||
if(!*kdot && cw_keyer_mode == KEYER_STRAIGHT) // just return if in bug mode
|
if(!*kdot && cw_keyer_mode == KEYER_STRAIGHT) // just return if in bug mode
|
||||||
key_state = EXITLOOP;
|
key_state = HANGTIME;
|
||||||
else if (dash_memory) // dash has been set during the dot so service
|
else if (dash_memory) // dash has been set during the dot so service
|
||||||
key_state = PREDASH;
|
key_state = PREDASH;
|
||||||
else key_state = DOTHELD; // dot is still active so service
|
else key_state = DOTHELD; // dot is still active so service
|
||||||
@ -335,11 +354,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
else kdelay++;
|
else kdelay++;
|
||||||
|
|
||||||
if (*kdash) { // set dash memory
|
if (*kdash) { // set dash memory
|
||||||
if (cw_keyer_mode == KEYER_ULTIMATIC) {
|
dash_memory = 1;
|
||||||
if (last_pressed == DASH)
|
|
||||||
dash_memory = 1;
|
|
||||||
} else
|
|
||||||
dash_memory = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -355,19 +370,13 @@ static void* keyer_thread(void *arg) {
|
|||||||
else kdelay++;
|
else kdelay++;
|
||||||
|
|
||||||
if (*kdot) { // set dot memory
|
if (*kdot) { // set dot memory
|
||||||
if (cw_keyer_mode == KEYER_ULTIMATIC) {
|
dot_memory = 1;
|
||||||
if (last_pressed == DOT)
|
|
||||||
dot_memory = 1;
|
|
||||||
} else
|
|
||||||
dot_memory = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// check if dot paddle is still held, if so repeat the dot. Else check if Letter space is required
|
// check if dot paddle is still held, if so repeat the dot. Else check if Letter space is required
|
||||||
case DOTHELD:
|
case DOTHELD:
|
||||||
if ((cw_keyer_mode == KEYER_ULTIMATIC) && (last_pressed == DASH))
|
if (*kdot) // dot has been set during the dash so service
|
||||||
key_state = PREDASH;
|
|
||||||
else if (*kdot) // dot has been set during the dash so service
|
|
||||||
key_state = PREDOT;
|
key_state = PREDOT;
|
||||||
else if (*kdash) // has dash paddle been pressed
|
else if (*kdash) // has dash paddle been pressed
|
||||||
key_state = PREDASH;
|
key_state = PREDASH;
|
||||||
@ -375,14 +384,12 @@ static void* keyer_thread(void *arg) {
|
|||||||
clear_memory();
|
clear_memory();
|
||||||
key_state = LETTERSPACE;
|
key_state = LETTERSPACE;
|
||||||
}
|
}
|
||||||
else key_state = EXITLOOP;
|
else key_state = HANGTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// check if dash paddle is still held, if so repeat the dash. Else check if Letter space is required
|
// check if dash paddle is still held, if so repeat the dash. Else check if Letter space is required
|
||||||
case DASHHELD:
|
case DASHHELD:
|
||||||
if ((cw_keyer_mode == KEYER_ULTIMATIC) && (last_pressed == DOT))
|
if (*kdash) // dash has been set during the dot so service
|
||||||
key_state = PREDOT;
|
|
||||||
else if (*kdash) // dash has been set during the dot so service
|
|
||||||
key_state = PREDASH;
|
key_state = PREDASH;
|
||||||
else if (*kdot) // has dot paddle been pressed
|
else if (*kdot) // has dot paddle been pressed
|
||||||
key_state = PREDOT;
|
key_state = PREDOT;
|
||||||
@ -390,7 +397,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
clear_memory();
|
clear_memory();
|
||||||
key_state = LETTERSPACE;
|
key_state = LETTERSPACE;
|
||||||
}
|
}
|
||||||
else key_state = EXITLOOP;
|
else key_state = HANGTIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Add letter space (3 x dot delay) to end of character and check if a paddle is pressed during this time.
|
// Add letter space (3 x dot delay) to end of character and check if a paddle is pressed during this time.
|
||||||
@ -402,7 +409,7 @@ static void* keyer_thread(void *arg) {
|
|||||||
key_state = PREDOT;
|
key_state = PREDOT;
|
||||||
else if (dash_memory)
|
else if (dash_memory)
|
||||||
key_state = PREDASH;
|
key_state = PREDASH;
|
||||||
else key_state = EXITLOOP; // no memories set so restart
|
else key_state = HANGTIME; // no memories set so restart
|
||||||
}
|
}
|
||||||
else kdelay++;
|
else kdelay++;
|
||||||
|
|
||||||
@ -413,16 +420,20 @@ static void* keyer_thread(void *arg) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
key_state = EXITLOOP;
|
key_state = EXITLOOP;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &loop_delay);
|
if (!keyer_out)
|
||||||
loop_delay.tv_nsec += interval;
|
hangtime_elapsed++;
|
||||||
while (loop_delay.tv_nsec >= NSEC_PER_SEC) {
|
|
||||||
loop_delay.tv_nsec -= NSEC_PER_SEC;
|
if (key_state != EXITLOOP) {
|
||||||
loop_delay.tv_sec++;
|
clock_gettime(CLOCK_MONOTONIC, &loop_delay);
|
||||||
|
loop_delay.tv_nsec += interval;
|
||||||
|
while (loop_delay.tv_nsec >= NSEC_PER_SEC) {
|
||||||
|
loop_delay.tv_nsec -= NSEC_PER_SEC;
|
||||||
|
loop_delay.tv_sec++;
|
||||||
|
}
|
||||||
|
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &loop_delay, NULL);
|
||||||
}
|
}
|
||||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &loop_delay, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,23 +442,41 @@ int open_key_gpiokeyer(const char * name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (sscanf(name, "gpio:%d,%d,%d,%d", &left_paddle_gpio, &right_paddle_gpio, &keyer_out_gpio, &tr_switch_gpio) < 4) {
|
||||||
|
fprintf(stderr, "Insufficient parameters for GPIO Keyer: %s\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
fprintf(stdout, "GPIO Keyer selected:\n - left paddle GPIO: %d\n - right paddle GPIO: %d\n - keyer out GPIO: %d\n - T/R switch GPIO: %d\n",
|
||||||
|
left_paddle_gpio, right_paddle_gpio, keyer_out_gpio, tr_switch_gpio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (wiringPiSetupGpio () < 0) {
|
if (wiringPiSetupGpio () < 0) {
|
||||||
fprintf(stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
|
fprintf(stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinMode(RIGHT_PADDLE_GPIO, INPUT);
|
pinMode(right_paddle_gpio, INPUT);
|
||||||
pullUpDnControl(RIGHT_PADDLE_GPIO, PUD_UP);
|
pullUpDnControl(right_paddle_gpio, PUD_UP);
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
wiringPiISR(RIGHT_PADDLE_GPIO, INT_EDGE_BOTH, keyer_event_right);
|
wiringPiISR(right_paddle_gpio, INT_EDGE_BOTH, keyer_event_right);
|
||||||
|
|
||||||
pinMode(LEFT_PADDLE_GPIO, INPUT);
|
pinMode(left_paddle_gpio, INPUT);
|
||||||
pullUpDnControl(LEFT_PADDLE_GPIO, PUD_UP);
|
pullUpDnControl(left_paddle_gpio, PUD_UP);
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
wiringPiISR(LEFT_PADDLE_GPIO, INT_EDGE_BOTH, keyer_event_left);
|
wiringPiISR(left_paddle_gpio, INT_EDGE_BOTH, keyer_event_left);
|
||||||
|
|
||||||
pinMode(KEYER_OUT_GPIO, OUTPUT);
|
if (keyer_out_gpio) {
|
||||||
digitalWrite(KEYER_OUT_GPIO, 0);
|
pinMode(keyer_out_gpio, OUTPUT);
|
||||||
|
digitalWrite(keyer_out_gpio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tr_switch_gpio) {
|
||||||
|
pinMode(tr_switch_gpio, OUTPUT);
|
||||||
|
digitalWrite(tr_switch_gpio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
keyer_update();
|
keyer_update();
|
||||||
|
|
||||||
@ -473,23 +502,24 @@ void close_key_gpiokeyer(void)
|
|||||||
int is_key_down_gpiokeyer(void)
|
int is_key_down_gpiokeyer(void)
|
||||||
{
|
{
|
||||||
static int retval;
|
static int retval;
|
||||||
// sem_wait(&cw_event);
|
|
||||||
retval = keyer_out;
|
retval = keyer_out;
|
||||||
// sem_post(&cw_event);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quisk_set_gpio_keyer_mode(int mode)
|
void quisk_set_gpio_keyer_mode(int mode)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MODE CHANGE\n");
|
#if defined(DEBUG)
|
||||||
|
fprintf(stdout, "MODE CHANGE\n");
|
||||||
|
#endif
|
||||||
if ((mode > -1) && (mode < NUM_KEYER_MODES))
|
if ((mode > -1) && (mode < NUM_KEYER_MODES))
|
||||||
cw_keyer_mode = mode;
|
cw_keyer_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void quisk_set_gpio_keyer_speed(int wpm)
|
void quisk_set_gpio_keyer_speed(int wpm)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "SPEED CHANGE\n");
|
#if defined(DEBUG)
|
||||||
|
fprintf(stdout, "SPEED CHANGE\n");
|
||||||
|
#endif
|
||||||
cw_keyer_speed = wpm;
|
cw_keyer_speed = wpm;
|
||||||
keyer_update();
|
keyer_update();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ int quisk_open_key(const char * name)
|
|||||||
ret = open_key_enet(name);
|
ret = open_key_enet(name);
|
||||||
}
|
}
|
||||||
#if defined(ENABLE_GPIO_KEYER)
|
#if defined(ENABLE_GPIO_KEYER)
|
||||||
else if (!strncmp(name, "GPIO", 4)){ // Raspberry Pi GPIO keyer
|
else if (!strncmp(name, "gpio", 4)){ // Raspberry Pi GPIO keyer
|
||||||
key_method = GpioKeyer;
|
key_method = GpioKeyer;
|
||||||
ret = open_key_gpiokeyer(name);
|
ret = open_key_gpiokeyer(name);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user