kopia lustrzana https://github.com/amedes/pico_tnc
add calibrate command
rodzic
10b393484e
commit
0b7d6ae75a
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -99,6 +99,9 @@ static const uint8_t *gps_str[] = {
|
||||||
|
|
||||||
// indicate converse mode
|
// indicate converse mode
|
||||||
bool converse_mode = false;
|
bool converse_mode = false;
|
||||||
|
// indicate calibrate mode
|
||||||
|
bool calibrate_mode = false;
|
||||||
|
uint8_t calibrate_idx = 0;
|
||||||
|
|
||||||
static uint8_t *read_call(uint8_t *buf, callsign_t *c)
|
static uint8_t *read_call(uint8_t *buf, callsign_t *c)
|
||||||
{
|
{
|
||||||
|
@ -547,7 +550,33 @@ static bool cmd_txdelay(tty_t *ttyp, uint8_t *buf, int len)
|
||||||
|
|
||||||
static bool cmd_calibrate(tty_t *ttyp, uint8_t *buf, int len)
|
static bool cmd_calibrate(tty_t *ttyp, uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
tty_write_str(ttyp, "CALIBRATE\r\n");
|
//tty_write_str(ttyp, "CALIBRATE\r\n");
|
||||||
|
tnc_t *tp = &tnc[0];
|
||||||
|
if (tp->send_state != SP_IDLE) {
|
||||||
|
tty_write_str(ttyp, "Transmitter busy\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp->send_state = SP_CALIBRATE;
|
||||||
|
tp->do_nrzi = false;
|
||||||
|
calibrate_mode = true;
|
||||||
|
calibrate_idx = 0;
|
||||||
|
tp->cal_data = 0x00;
|
||||||
|
tp->ttyp = ttyp;
|
||||||
|
tp->cal_time = tnc_time();
|
||||||
|
tty_write_str(ttyp, "Calibrate Mode. SP to toggle; ctl C to Exit\r\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calibrate(void)
|
||||||
|
{
|
||||||
|
tnc_t *tp = &tnc[0];
|
||||||
|
if (tp->send_state != SP_CALIBRATE_OFF) return;
|
||||||
|
|
||||||
|
tp->send_state = SP_IDLE;
|
||||||
|
tp->do_nrzi = true;
|
||||||
|
calibrate_mode = false;
|
||||||
|
tty_write_str(tp->ttyp, "Exit Calibrate Mode\r\ncmd: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cmd_converse(tty_t *ttyp, uint8_t *buf, int len)
|
static bool cmd_converse(tty_t *ttyp, uint8_t *buf, int len)
|
||||||
|
@ -719,7 +748,7 @@ void cmd(tty_t *ttyp, uint8_t *buf, int len)
|
||||||
if (matched == 1) {
|
if (matched == 1) {
|
||||||
|
|
||||||
if (mp->func(ttyp, param, param_len)) {
|
if (mp->func(ttyp, param, param_len)) {
|
||||||
if (!converse_mode) tty_write_str(ttyp, "\r\nOK\r\n");
|
if (!(converse_mode | calibrate_mode)) tty_write_str(ttyp, "\r\nOK\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,5 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
extern bool converse_mode;
|
extern bool converse_mode;
|
||||||
|
extern bool calibrate_mode;
|
||||||
|
extern uint8_t calibrate_idx;
|
||||||
|
|
||||||
void cmd(tty_t *ttyp, uint8_t *buf, int len);
|
void cmd(tty_t *ttyp, uint8_t *buf, int len);
|
||||||
|
void calibrate(void);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -148,6 +148,9 @@ int main()
|
||||||
// send beacon
|
// send beacon
|
||||||
beacon();
|
beacon();
|
||||||
|
|
||||||
|
// calibrate off
|
||||||
|
calibrate();
|
||||||
|
|
||||||
#ifdef BUSY_PIN
|
#ifdef BUSY_PIN
|
||||||
// gpio_put(BUSY_PIN, 0);
|
// gpio_put(BUSY_PIN, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,6 +63,8 @@ static const int ptt_pins[] = {
|
||||||
|
|
||||||
#define ISR_PIN 15
|
#define ISR_PIN 15
|
||||||
|
|
||||||
|
#define CAL_TIMEOUT (60 * 100) // 60 sec
|
||||||
|
|
||||||
static void __isr dma_handler(void)
|
static void __isr dma_handler(void)
|
||||||
{
|
{
|
||||||
int int_status = dma_hw->ints0;
|
int int_status = dma_hw->ints0;
|
||||||
|
@ -152,7 +154,11 @@ int send_byte(tnc_t *tp, uint8_t data, bool bit_stuff)
|
||||||
int bit = byte & 1;
|
int bit = byte & 1;
|
||||||
while (byte > 1) { // check sentinel
|
while (byte > 1) { // check sentinel
|
||||||
|
|
||||||
if (!bit) tp->level ^= 1; // NRZI, invert if original bit == 0
|
if (tp->do_nrzi) {
|
||||||
|
if (!bit) tp->level ^= 1; // NRZI, invert if original bit == 0
|
||||||
|
} else {
|
||||||
|
tp->level = bit;
|
||||||
|
}
|
||||||
|
|
||||||
// make Bell202 CPAFSK audio samples
|
// make Bell202 CPAFSK audio samples
|
||||||
tp->dma_blocks[tp->next][idx++] = phase_tab[tp->level][tp->phase]; // 1: mark, 0: space
|
tp->dma_blocks[tp->next][idx++] = phase_tab[tp->level][tp->phase]; // 1: mark, 0: space
|
||||||
|
@ -309,17 +315,6 @@ void send_init(void)
|
||||||
gpio_put(SMPS_PIN, 1);
|
gpio_put(SMPS_PIN, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SEND_STATE {
|
|
||||||
SP_IDLE = 0,
|
|
||||||
SP_WAIT_CLR_CH,
|
|
||||||
SP_P_PERSISTENCE,
|
|
||||||
SP_WAIT_SLOTTIME,
|
|
||||||
SP_PTT_ON,
|
|
||||||
SP_SEND_FLAGS,
|
|
||||||
SP_DATA_START,
|
|
||||||
SP_DATA,
|
|
||||||
SP_ERROR,
|
|
||||||
};
|
|
||||||
|
|
||||||
int send_queue_free(tnc_t *tp)
|
int send_queue_free(tnc_t *tp)
|
||||||
{
|
{
|
||||||
|
@ -434,6 +429,15 @@ void send(void)
|
||||||
while (queue_try_remove(&tp->send_queue, &data)) {
|
while (queue_try_remove(&tp->send_queue, &data)) {
|
||||||
}
|
}
|
||||||
tp->send_state = SP_IDLE;
|
tp->send_state = SP_IDLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SP_CALIBRATE:
|
||||||
|
if (tnc_time() - tp->cal_time >= CAL_TIMEOUT) {
|
||||||
|
tp->send_state = SP_CALIBRATE_OFF;
|
||||||
|
} else {
|
||||||
|
send_byte(tp, tp->cal_data, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp++;
|
tp++;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -95,12 +95,16 @@ void tnc_init(void)
|
||||||
|
|
||||||
// send queue
|
// send queue
|
||||||
queue_init(&tp->send_queue, sizeof(uint8_t), SEND_QUEUE_LEN);
|
queue_init(&tp->send_queue, sizeof(uint8_t), SEND_QUEUE_LEN);
|
||||||
|
tp->send_state = SP_IDLE;
|
||||||
|
|
||||||
tp->cdt = 0;
|
tp->cdt = 0;
|
||||||
tp->kiss_txdelay = 50;
|
tp->kiss_txdelay = 50;
|
||||||
tp->kiss_p = 63;
|
tp->kiss_p = 63;
|
||||||
tp->kiss_slottime = 10;
|
tp->kiss_slottime = 10;
|
||||||
tp->kiss_fullduplex = 0;
|
tp->kiss_fullduplex = 0;
|
||||||
|
|
||||||
|
// calibrate
|
||||||
|
tp->do_nrzi = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%d ports support\n", PORT_N);
|
//printf("%d ports support\n", PORT_N);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -85,6 +85,8 @@ typedef struct {
|
||||||
int high_q;
|
int high_q;
|
||||||
} values_t;
|
} values_t;
|
||||||
|
|
||||||
|
typedef struct TTY tty_t;
|
||||||
|
|
||||||
typedef struct TNC {
|
typedef struct TNC {
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
|
|
||||||
|
@ -177,6 +179,12 @@ typedef struct TNC {
|
||||||
uint16_t packet_len;
|
uint16_t packet_len;
|
||||||
int wait_time;
|
int wait_time;
|
||||||
|
|
||||||
|
// calibrate
|
||||||
|
uint8_t cal_data;
|
||||||
|
bool do_nrzi;
|
||||||
|
uint32_t cal_time;
|
||||||
|
tty_t *ttyp;
|
||||||
|
|
||||||
} tnc_t;
|
} tnc_t;
|
||||||
|
|
||||||
extern tnc_t tnc[];
|
extern tnc_t tnc[];
|
||||||
|
@ -256,3 +264,18 @@ typedef struct TTY {
|
||||||
} tty_t;
|
} tty_t;
|
||||||
|
|
||||||
extern tty_t tty[];
|
extern tty_t tty[];
|
||||||
|
|
||||||
|
// send process state
|
||||||
|
enum SEND_STATE {
|
||||||
|
SP_IDLE = 0,
|
||||||
|
SP_WAIT_CLR_CH,
|
||||||
|
SP_P_PERSISTENCE,
|
||||||
|
SP_WAIT_SLOTTIME,
|
||||||
|
SP_PTT_ON,
|
||||||
|
SP_SEND_FLAGS,
|
||||||
|
SP_DATA_START,
|
||||||
|
SP_DATA,
|
||||||
|
SP_ERROR,
|
||||||
|
SP_CALIBRATE,
|
||||||
|
SP_CALIBRATE_OFF,
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, Kazuhisa Yokota, JN1DFF
|
Copyright (c) 2021, JN1DFF
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -112,8 +112,21 @@ void tty_write_str(tty_t *ttyp, uint8_t const *str)
|
||||||
#define BELL '\a'
|
#define BELL '\a'
|
||||||
#define CTRL_C '\x03'
|
#define CTRL_C '\x03'
|
||||||
#define FEND 0xc0
|
#define FEND 0xc0
|
||||||
|
#define SP ' '
|
||||||
|
|
||||||
#define KISS_TIMEOUT (1 * 100) // 1 sec
|
#define KISS_TIMEOUT (1 * 100) // 1 sec
|
||||||
|
|
||||||
|
#define CAL_DATA_MAX 3
|
||||||
|
|
||||||
|
static const uint8_t calibrate_data[CAL_DATA_MAX] = {
|
||||||
|
0x00, 0xff, 0x55,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *calibrate_str[CAL_DATA_MAX] = {
|
||||||
|
"send space (2200Hz)\r\n",
|
||||||
|
"send mark (1200Hz)\r\n",
|
||||||
|
"send 0x55 (1200/2200Hz)\r\n",
|
||||||
|
};
|
||||||
|
|
||||||
void tty_input(tty_t *ttyp, int ch)
|
void tty_input(tty_t *ttyp, int ch)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +141,28 @@ void tty_input(tty_t *ttyp, int ch)
|
||||||
ttyp->kiss_state = KISS_OUTSIDE;
|
ttyp->kiss_state = KISS_OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calibrate mode
|
||||||
|
if (calibrate_mode) {
|
||||||
|
tnc_t *tp = &tnc[0];
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case SP: // toggle mark/space
|
||||||
|
if (++calibrate_idx >= CAL_DATA_MAX) calibrate_idx = 0;
|
||||||
|
tp->cal_data = calibrate_data[calibrate_idx];
|
||||||
|
tty_write_str(ttyp, calibrate_str[calibrate_idx]);
|
||||||
|
tp->cal_time = tnc_time();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CTRL_C:
|
||||||
|
tp->send_state = SP_CALIBRATE_OFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
tty_write_char(ttyp, BELL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case FEND: // KISS frame end
|
case FEND: // KISS frame end
|
||||||
kiss_input(ttyp, ch);
|
kiss_input(ttyp, ch);
|
||||||
|
@ -153,7 +188,7 @@ void tty_input(tty_t *ttyp, int ch)
|
||||||
cmd(ttyp, ttyp->cmd_buf, ttyp->cmd_idx);
|
cmd(ttyp, ttyp->cmd_buf, ttyp->cmd_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!converse_mode) tty_write_str(ttyp, "cmd: ");
|
if (!(converse_mode | calibrate_mode)) tty_write_str(ttyp, "cmd: ");
|
||||||
ttyp->cmd_idx = 0;
|
ttyp->cmd_idx = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue