forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
5.2 KiB
260 lines
5.2 KiB
#include <stdint.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <chopstx.h> |
|
#include <contrib/usart.h> |
|
|
|
#include <usb_lld.h> |
|
#include "cdc.h" |
|
|
|
/* For set_led */ |
|
#include "board.h" |
|
#include "sys.h" |
|
|
|
static void * |
|
blk (void *arg) |
|
{ |
|
(void)arg; |
|
|
|
while (1) |
|
{ |
|
set_led (0); |
|
chopstx_usec_wait (200*1000); |
|
set_led (1); |
|
chopstx_usec_wait (200*1000); |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
#define PRIO_USART 4 |
|
#define PRIO_CDC2USART 3 |
|
#define PRIO_USART2CDC 3 |
|
#define PRIO_CDC 2 |
|
|
|
#define STACK_MAIN |
|
#define STACK_PROCESS_1 |
|
#define STACK_PROCESS_2 |
|
#define STACK_PROCESS_3 |
|
#define STACK_PROCESS_4 |
|
#define STACK_PROCESS_5 |
|
#define STACK_PROCESS_6 |
|
#include "stack-def.h" |
|
#define STACK_ADDR_CDC ((uintptr_t)process1_base) |
|
#define STACK_SIZE_CDC (sizeof process1_base) |
|
|
|
#define STACK_ADDR_USART ((uint32_t)process2_base) |
|
#define STACK_SIZE_USART (sizeof process2_base) |
|
|
|
#define STACK_ADDR_CDC2USART0 ((uint32_t)process3_base) |
|
#define STACK_SIZE_CDC2USART0 (sizeof process3_base) |
|
|
|
#define STACK_ADDR_USART2CDC0 ((uint32_t)process4_base) |
|
#define STACK_SIZE_USART2CDC0 (sizeof process4_base) |
|
|
|
#define STACK_ADDR_CDC2USART1 ((uint32_t)process5_base) |
|
#define STACK_SIZE_CDC2USART1 (sizeof process5_base) |
|
|
|
#define STACK_ADDR_USART2CDC1 ((uint32_t)process6_base) |
|
#define STACK_SIZE_USART2CDC1 (sizeof process6_base) |
|
|
|
|
|
struct cdc_usart { |
|
uint8_t dev_no; |
|
struct cdc *cdc; |
|
}; |
|
|
|
static void * |
|
usart_to_cdc_loop (void *arg) |
|
{ |
|
struct cdc_usart *cdc_usart = arg; |
|
|
|
while (1) |
|
{ |
|
char s[BUFSIZE]; |
|
|
|
cdc_wait_connection (cdc_usart->cdc); |
|
|
|
/* Flush USART buffers */ |
|
usart_read (cdc_usart->dev_no, NULL, 0); |
|
usart_write (cdc_usart->dev_no, NULL, 0); |
|
|
|
chopstx_usec_wait (100*1000); |
|
|
|
while (1) |
|
{ |
|
int size = usart_read (cdc_usart->dev_no, s, BUFSIZE); |
|
|
|
if (size > 0) |
|
{ |
|
if (cdc_send (cdc_usart->cdc, s, size) < 0) |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
static void * |
|
cdc_to_usart_loop (void *arg) |
|
{ |
|
struct cdc_usart *cdc_usart = arg; |
|
|
|
while (1) |
|
{ |
|
char s[BUFSIZE]; |
|
|
|
cdc_wait_connection (cdc_usart->cdc); |
|
|
|
/* Flush USART buffers */ |
|
usart_read (cdc_usart->dev_no, NULL, 0); |
|
usart_write (cdc_usart->dev_no, NULL, 0); |
|
|
|
chopstx_usec_wait (50*1000); |
|
|
|
/* Send ZLP at the beginning. */ |
|
cdc_send (cdc_usart->cdc, s, 0); |
|
|
|
while (1) |
|
{ |
|
int size; |
|
uint32_t usec = 3000000; /* 3.0 seconds */ |
|
|
|
size = cdc_recv (cdc_usart->cdc, s, &usec); |
|
if (size < 0) |
|
break; |
|
|
|
if (size) |
|
usart_write (cdc_usart->dev_no, s, size); |
|
} |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
static struct cdc_usart cdc_usart0; |
|
static struct cdc_usart cdc_usart1; |
|
|
|
static int |
|
ss_notify (uint8_t dev_no, uint16_t state_bits) |
|
{ |
|
struct cdc *s; |
|
|
|
if (dev_no == cdc_usart0.dev_no) |
|
s = cdc_usart0.cdc; |
|
else if (dev_no == cdc_usart1.dev_no) |
|
s = cdc_usart1.cdc; |
|
else |
|
return -1; |
|
|
|
return cdc_ss_notify (s, state_bits); |
|
} |
|
|
|
static void |
|
send_break (uint8_t dev_no, uint16_t duration) |
|
{ |
|
(void)duration; /* Not supported by USART. */ |
|
usart_send_break (dev_no); |
|
} |
|
|
|
static void |
|
setup_usart_config (uint8_t dev_no, uint32_t bitrate, uint8_t format, |
|
uint8_t paritytype, uint8_t databits) |
|
{ |
|
/* Check supported config(s) */ |
|
uint32_t config_bits; |
|
|
|
if (bitrate == 9600) |
|
config_bits = B9600; |
|
else if (bitrate == 19200) |
|
config_bits = B19200; |
|
else if (bitrate == 57600) |
|
config_bits = B57600; |
|
else if (bitrate == 115200) |
|
config_bits = B115200; |
|
else |
|
{ |
|
bitrate = 115200; |
|
config_bits = B115200; |
|
} |
|
|
|
if (format == 0) |
|
config_bits |= STOP1B; |
|
else if (format == 1) |
|
config_bits |= STOP1B5; |
|
else if (format == 2) |
|
config_bits |= STOP2B; |
|
else |
|
{ |
|
format = 0; |
|
config_bits |= STOP1B; |
|
} |
|
|
|
if (paritytype == 0) |
|
config_bits |= 0; |
|
else if (paritytype == 1) |
|
config_bits |= (PARENB | PARODD); |
|
else if (paritytype == 2) |
|
config_bits |= PARENB; |
|
else |
|
{ |
|
paritytype = 0; |
|
config_bits |= 0; |
|
} |
|
|
|
if (databits == 7) |
|
config_bits |= CS7; |
|
else if (databits == 7) |
|
config_bits |= CS8; |
|
else |
|
{ |
|
databits = 8; |
|
config_bits |= CS8; |
|
} |
|
|
|
if (databits == 7 && paritytype == 0) |
|
{ |
|
databits = 8; |
|
config_bits &= ~MASK_CS; |
|
config_bits |= CS8; |
|
} |
|
|
|
usart_config (dev_no, config_bits); |
|
} |
|
|
|
|
|
int |
|
main (int argc, const char *argv[]) |
|
{ |
|
(void)argc; |
|
(void)argv; |
|
|
|
chopstx_usec_wait (200*1000); |
|
|
|
cdc_init (PRIO_CDC, STACK_ADDR_CDC, STACK_SIZE_CDC, |
|
send_break, setup_usart_config); |
|
cdc_wait_configured (); |
|
|
|
usart_init (PRIO_USART, STACK_ADDR_USART, STACK_SIZE_USART, ss_notify); |
|
|
|
usart_config (2, B115200 | CS8 | STOP1B); |
|
usart_config (3, B115200 | CS8 | STOP1B); |
|
|
|
cdc_usart0.cdc = cdc_open (0); |
|
cdc_usart0.dev_no = 2; |
|
cdc_usart1.cdc = cdc_open (1); |
|
cdc_usart1.dev_no = 3; |
|
|
|
chopstx_create (PRIO_USART2CDC, STACK_ADDR_USART2CDC0, |
|
STACK_SIZE_USART2CDC0, usart_to_cdc_loop, &cdc_usart0); |
|
chopstx_create (PRIO_USART2CDC, STACK_ADDR_USART2CDC1, |
|
STACK_SIZE_USART2CDC1, usart_to_cdc_loop, &cdc_usart1); |
|
chopstx_create (PRIO_CDC2USART, STACK_ADDR_CDC2USART0, |
|
STACK_SIZE_CDC2USART0, cdc_to_usart_loop, &cdc_usart0); |
|
chopstx_create (PRIO_CDC2USART, STACK_ADDR_CDC2USART1, |
|
STACK_SIZE_CDC2USART1, cdc_to_usart_loop, &cdc_usart1); |
|
|
|
blk (NULL); |
|
return 0; |
|
}
|
|
|