Naming tx programs based on pinout rather than transfer speed

This commit is contained in:
sekigon-gonnoc 2023-10-04 21:00:08 +09:00
parent 98275fe1dd
commit 52ebecb8b4
6 changed files with 146 additions and 61 deletions

View file

@ -40,7 +40,7 @@ static void __no_inline_not_in_flash_func(send_pre)(const pio_port_t *pp) {
// send PRE token in full-speed
pio_sm_set_enabled(pp->pio_usb_tx, pp->sm_tx, false);
for (uint i = 0; i < USB_TX_EOP_DISABLER_LEN; ++i) {
uint16_t instr = usb_tx_fs_pre_program.instructions[i + USB_TX_EOP_OFFSET];
uint16_t instr = pp->fs_tx_pre_program->instructions[i + USB_TX_EOP_OFFSET];
pp->pio_usb_tx->instr_mem[pp->offset_tx + i + USB_TX_EOP_OFFSET] = instr;
}
@ -59,7 +59,7 @@ static void __no_inline_not_in_flash_func(send_pre)(const pio_port_t *pp) {
// change bus speed to low-speed
pio_sm_set_enabled(pp->pio_usb_tx, pp->sm_tx, false);
for (uint i = 0; i < USB_TX_EOP_DISABLER_LEN; ++i) {
uint16_t instr = usb_tx_fs_program.instructions[i + USB_TX_EOP_OFFSET];
uint16_t instr = pp->fs_tx_program->instructions[i + USB_TX_EOP_OFFSET];
pp->pio_usb_tx->instr_mem[pp->offset_tx + i + USB_TX_EOP_OFFSET] = instr;
}
SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_ls_tx);
@ -215,9 +215,9 @@ static __always_inline void add_pio_host_rx_program(PIO pio,
static void __no_inline_not_in_flash_func(initialize_host_programs)(
pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port) {
pp->offset_tx = pio_add_program(pp->pio_usb_tx, &usb_tx_fs_program);
pp->offset_tx = pio_add_program(pp->pio_usb_tx, pp->fs_tx_program);
usb_tx_fs_program_init(pp->pio_usb_tx, pp->sm_tx, pp->offset_tx,
port->pin_dp);
port->pin_dp, port->pin_dm);
add_pio_host_rx_program(pp->pio_usb_rx, &usb_nrzi_decoder_program,
&usb_nrzi_decoder_debug_program, &pp->offset_rx,
@ -234,7 +234,7 @@ static void __no_inline_not_in_flash_func(initialize_host_programs)(
port->pin_dp, port->pin_dm, true,
c->debug_pin_eop);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp, port->pin_dm);
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, port->pin_dp);
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_eop, port->pin_dm);
@ -262,7 +262,18 @@ static void apply_config(pio_port_t *pp, const pio_usb_configuration_t *c,
pp->sm_rx = c->sm_rx;
pp->sm_eop = c->sm_eop;
port->pin_dp = c->pin_dp;
port->pin_dm = c->pin_dp + 1;
if (c->pinout == PIO_USB_PINOUT_DPDM) {
port->pin_dm = c->pin_dp + 1;
pp->fs_tx_program = &usb_tx_dpdm_program;
pp->fs_tx_pre_program = &usb_tx_pre_dpdm_program;
pp->ls_tx_program = &usb_tx_dmdp_program;
} else {
port->pin_dm = c->pin_dp - 1;
pp->fs_tx_program = &usb_tx_dmdp_program;
pp->fs_tx_pre_program = &usb_tx_pre_dmdp_program;
pp->ls_tx_program = &usb_tx_dpdm_program;
}
pp->debug_pin_rx = c->debug_pin_rx;
pp->debug_pin_eop = c->debug_pin_eop;
@ -431,24 +442,26 @@ void __no_inline_not_in_flash_func(pio_usb_ll_transfer_complete)(
ep->has_transfer = false;
}
int pio_usb_host_add_port(uint8_t pin_dp) {
int pio_usb_host_add_port(uint8_t pin_dp, PIO_USB_PINOUT pinout) {
for (int idx = 0; idx < PIO_USB_ROOT_PORT_CNT; idx++) {
root_port_t *root = PIO_USB_ROOT_PORT(idx);
if (!root->initialized) {
root->pin_dp = pin_dp;
root->pin_dm = pin_dp + 1;
PIO_USB_ROOT_PORT(idx)->pin_dp = pin_dp;
PIO_USB_ROOT_PORT(idx)->pin_dm = pin_dp + 1;
if (pinout == PIO_USB_PINOUT_DPDM) {
root->pin_dm = pin_dp + 1;
} else {
root->pin_dm = pin_dp - 1;
}
gpio_pull_down(pin_dp);
gpio_pull_down(pin_dp + 1);
gpio_pull_down(root->pin_dm);
pio_gpio_init(pio_port[0].pio_usb_tx, pin_dp);
pio_gpio_init(pio_port[0].pio_usb_tx, pin_dp + 1);
pio_gpio_init(pio_port[0].pio_usb_tx, root->pin_dm);
gpio_set_inover(pin_dp, GPIO_OVERRIDE_INVERT);
gpio_set_inover(pin_dp + 1, GPIO_OVERRIDE_INVERT);
gpio_set_inover(root->pin_dm, GPIO_OVERRIDE_INVERT);
pio_sm_set_pindirs_with_mask(pio_port[0].pio_usb_tx, pio_port[0].sm_tx, 0,
(0b11 << pin_dp));
(1 << pin_dp) | (1 << root->pin_dm));
port_pin_drive_setting(root);
root->initialized = true;

View file

@ -10,7 +10,7 @@
// Host functions
usb_device_t *pio_usb_host_init(const pio_usb_configuration_t *c);
int pio_usb_host_add_port(uint8_t pin_dp);
int pio_usb_host_add_port(uint8_t pin_dp, PIO_USB_PINOUT pinout);
void pio_usb_host_task(void);
void pio_usb_host_stop(void);
void pio_usb_host_restart(void);

View file

@ -1,6 +1,11 @@
#pragma once
typedef enum {
PIO_USB_PINOUT_DPDM = 0, // DM = DP+1
PIO_USB_PINOUT_DMDP, // DM = DP-1
} PIO_USB_PINOUT;
typedef struct {
uint8_t pin_dp;
uint8_t pio_tx_num;
@ -13,6 +18,7 @@ typedef struct {
int8_t debug_pin_rx;
int8_t debug_pin_eop;
bool skip_alarm_pool;
PIO_USB_PINOUT pinout;
} pio_usb_configuration_t;
#ifndef PIO_USB_DP_PIN_DEFAULT

View file

@ -126,7 +126,7 @@ static __always_inline void override_pio_rx_program(PIO pio,
static void __no_inline_not_in_flash_func(configure_fullspeed_host)(
pio_port_t const *pp, root_port_t *port) {
override_pio_program(pp->pio_usb_tx, &usb_tx_fs_program, pp->offset_tx);
override_pio_program(pp->pio_usb_tx, pp->fs_tx_program, pp->offset_tx);
SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_fs_tx);
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, port->pin_dp);
@ -136,12 +136,12 @@ static void __no_inline_not_in_flash_func(configure_fullspeed_host)(
pio_sm_set_in_pins(pp->pio_usb_rx, pp->sm_eop, port->pin_dp);
SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_fs_rx);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp, port->pin_dm);
}
static void __no_inline_not_in_flash_func(configure_lowspeed_host)(
pio_port_t const *pp, root_port_t *port) {
override_pio_program(pp->pio_usb_tx, &usb_tx_ls_program, pp->offset_tx);
override_pio_program(pp->pio_usb_tx, pp->ls_tx_program, pp->offset_tx);
SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_ls_tx);
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, port->pin_dm);
@ -151,7 +151,7 @@ static void __no_inline_not_in_flash_func(configure_lowspeed_host)(
pio_sm_set_in_pins(pp->pio_usb_rx, pp->sm_eop, port->pin_dm);
SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_ls_rx);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp);
usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp, port->pin_dm);
}
static void __no_inline_not_in_flash_func(configure_root_port)(

View file

@ -64,6 +64,10 @@ typedef struct {
int8_t debug_pin_rx;
int8_t debug_pin_eop;
const pio_program_t *fs_tx_program;
const pio_program_t *fs_tx_pre_program;
const pio_program_t *ls_tx_program;
pio_clk_div_t clk_div_fs_tx;
pio_clk_div_t clk_div_fs_rx;
pio_clk_div_t clk_div_ls_tx;
@ -99,8 +103,8 @@ extern pio_port_t pio_port[1];
// Bus functions
//--------------------------------------------------------------------+
#define IRQ_TX_EOP_MASK (1 << usb_tx_fs_IRQ_EOP)
#define IRQ_TX_COMP_MASK (1 << usb_tx_fs_IRQ_COMP)
#define IRQ_TX_EOP_MASK (1 << usb_tx_dpdm_IRQ_EOP)
#define IRQ_TX_COMP_MASK (1 << usb_tx_dpdm_IRQ_COMP)
#define IRQ_TX_ALL_MASK (IRQ_TX_EOP_MASK | IRQ_TX_COMP_MASK)
#define IRQ_RX_COMP_MASK (1 << IRQ_RX_EOP)
#define IRQ_RX_ALL_MASK \

View file

@ -1,22 +1,26 @@
; Copyright (c) 2021 sekigon-gonnoc
; Copyright (c) 2021-2023 sekigon-gonnoc
.define public USB_TX_EOP_OFFSET 4
.define public USB_TX_EOP_DISABLER_LEN 4
; USB FS NRZI transmitter
; Run 48 MHz, autopull
.program usb_tx_fs
; USB NRZI transmitter
; Run at 48 MHz for full-spped
; Run at 6 MHz for low-spped
; autopull enabled
.program usb_tx_dpdm
.side_set 2 opt
.define J 0b01
.define K 0b10
; J for fs, K for ls
.define FJ_LK 0b01
; K for fs, J for ls
.define FK_LJ 0b10
.define SE0 0b00
.define BR 5 ; bit repeat limit
.define public IRQ_COMP 0 ; complete flag bit
.define public IRQ_EOP 1 ; EOP start flag bit
start:
set y, BR side J
set y, BR side FJ_LK
set pindirs, 0b11
.wrap_target
@ -26,7 +30,7 @@ check_eop1:
send_eop:
irq IRQ_EOP side SE0 [3] ; To catch quik ACK, mark as complete here
nop [3]
nop side J
nop side FJ_LK
set pindirs, 0b00 [3]
irq wait IRQ_COMP
jmp start
@ -34,10 +38,10 @@ load_bit1:
out x, 1
jmp !x low1
high1:
jmp y-- check_eop1 side J
jmp y-- check_eop1 side FJ_LK
nop [2] ; bit stuffing
low1:
set y BR side K
set y BR side FK_LJ
check_eop2:
jmp !osre load_bit2
@ -46,15 +50,16 @@ load_bit2:
out x, 1
jmp !x low2
high2:
jmp y-- check_eop2 side K
jmp y-- check_eop2 side FK_LJ
nop [2] ; bit stuffing
low2:
set y BR side J
set y BR side FJ_LK
.wrap
; USB FS transmitter for PRE packet (No EOP)
; Run 48 MHz, autopull
.program usb_tx_fs_pre
; USB transmitter for PRE packet (No EOP)
; Run at 48 MHz for full-spped
; autopull enabled
.program usb_tx_pre_dpdm
.side_set 2 opt
.define J 0b01
@ -102,9 +107,61 @@ low2:
.wrap
; USB LS Transmitter
; Run 6MHz, autopull
.program usb_tx_ls
; USB NRZI transmitter
; Run at 48 MHz for full-spped
; Run at 6 MHz for low-spped
; autopull enabled
.program usb_tx_dmdp
.side_set 2 opt
.define FK_LJ 0b10
.define FJ_LK 0b01
.define SE0 0b00
.define BR 5 ; bit repeat limit
.define public IRQ_COMP 0 ; complete flag bit
.define public IRQ_EOP 1 ; EOP start flag bit
start:
set y, BR side FK_LJ
set pindirs, 0b11
.wrap_target
check_eop1:
jmp !osre load_bit1
nop [1]
send_eop:
irq IRQ_EOP side SE0 [3]
nop [3]
nop side FK_LJ
set pindirs, 0b00 [3]
irq wait IRQ_COMP
jmp start
load_bit1:
out x, 1
jmp !x low1
high1:
jmp y-- check_eop1 side FK_LJ
nop [2] ; bit stuffing
low1:
set y BR side FJ_LK
check_eop2:
jmp !osre load_bit2
jmp send_eop [1]
load_bit2:
out x, 1
jmp !x low2
high2:
jmp y-- check_eop2 side FJ_LK
nop [2] ; bit stuffing
low2:
set y BR side FK_LJ
.wrap
; USB transmitter for PRE packet (No EOP)
; Run at 48 MHz for full-spped
; autopull enabled
.program usb_tx_pre_dmdp
.side_set 2 opt
.define J 0b10
@ -123,10 +180,10 @@ check_eop1:
jmp !osre load_bit1
nop [1]
send_eop:
irq IRQ_EOP side SE0 [3]
nop [3]
nop side J
set pindirs, 0b00 [3]
irq IRQ_EOP side J [3]
set pindirs, 0b00
nop ; to align program size
nop ; to align program size
irq wait IRQ_COMP
jmp start
load_bit1:
@ -152,26 +209,31 @@ low2:
.wrap
% c-sdk {
#include "hardware/clocks.h"
static void __no_inline_not_in_flash_func(usb_tx_configure_pins)(PIO pio, uint sm, uint pin_dp) {
pio_sm_set_out_pins(pio, sm, pin_dp, 2);
pio_sm_set_set_pins(pio, sm, pin_dp, 2);
pio_sm_set_sideset_pins(pio, sm, pin_dp);
static void __no_inline_not_in_flash_func(usb_tx_configure_pins)(PIO pio, uint sm, uint pin_dp, uint pin_dm) {
if (pin_dp < pin_dm) {
pio_sm_set_out_pins(pio, sm, pin_dp, 2);
pio_sm_set_set_pins(pio, sm, pin_dp, 2);
pio_sm_set_sideset_pins(pio, sm, pin_dp);
} else {
pio_sm_set_out_pins(pio, sm, pin_dm, 2);
pio_sm_set_set_pins(pio, sm, pin_dm, 2);
pio_sm_set_sideset_pins(pio, sm, pin_dm);
}
}
static inline void usb_tx_fs_program_init(PIO pio, uint sm, uint offset,
uint pin_dp) {
pio_sm_set_pins_with_mask(pio, sm, (0b01 << pin_dp), (0b11 << pin_dp));
uint pin_dp, uint pin_dm) {
pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dp), ((1 << pin_dp) | (1 << pin_dm)));
gpio_pull_down(pin_dp);
gpio_pull_down(pin_dp + 1); // dm
gpio_pull_down(pin_dm);
pio_gpio_init(pio, pin_dp);
pio_gpio_init(pio, pin_dp + 1); // dm
pio_gpio_init(pio, pin_dm);
pio_sm_config c = usb_tx_fs_program_get_default_config(offset);
pio_sm_config c = usb_tx_dpdm_program_get_default_config(offset);
// shifts to left, autopull, 8bit
sm_config_set_out_shift(&c, true, true, 8);
@ -184,20 +246,20 @@ low2:
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
usb_tx_configure_pins(pio, sm, pin_dp);
usb_tx_configure_pins(pio, sm, pin_dp, pin_dm);
pio_sm_set_enabled(pio, sm, true);
}
static inline void usb_tx_ls_program_init(PIO pio, uint sm, uint offset,
uint pin_dp) {
pio_sm_set_pins_with_mask(pio, sm, (0b10 << pin_dp), (0b11 << pin_dp));
uint pin_dp, uint pin_dm) {
pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dm), ((1 << pin_dp) | (1 << pin_dm)));
gpio_pull_down(pin_dp);
gpio_pull_down(pin_dp + 1); // dm
gpio_pull_down(pin_dm);
pio_gpio_init(pio, pin_dp);
pio_gpio_init(pio, pin_dp + 1); // dm
pio_gpio_init(pio, pin_dm);
pio_sm_config c = usb_tx_ls_program_get_default_config(offset);
pio_sm_config c = usb_tx_dmdp_program_get_default_config(offset);
// shifts to left, autopull, 8bit
sm_config_set_out_shift(&c, true, true, 8);
@ -210,8 +272,8 @@ low2:
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
usb_tx_configure_pins(pio, sm, pin_dp);
usb_tx_configure_pins(pio, sm, pin_dp, pin_dm);
pio_sm_set_enabled(pio, sm, true);
}
%}
%}