Naming tx programs based on pinout rather than transfer speed
This commit is contained in:
parent
98275fe1dd
commit
52ebecb8b4
6 changed files with 146 additions and 61 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)(
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
142
src/usb_tx.pio
142
src/usb_tx.pio
|
|
@ -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);
|
||||
}
|
||||
|
||||
%}
|
||||
%}
|
||||
Loading…
Reference in a new issue