Merge pull request #100 from sekigon-gonnoc/swap-dpdm-option-2

Support swapped DP/DM pins
This commit is contained in:
sekigon-gonnoc 2023-10-04 22:29:10 +09:00 committed by GitHub
commit 4e24f8ddcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 298 additions and 148 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,15 +215,15 @@ 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,
c->debug_pin_rx);
usb_rx_fs_program_init(pp->pio_usb_rx, pp->sm_rx, pp->offset_rx, port->pin_dp,
c->debug_pin_rx);
port->pin_dm, c->debug_pin_rx);
pp->rx_reset_instr = pio_encode_jmp(pp->offset_rx);
pp->rx_reset_instr2 = pio_encode_set(pio_x, 0);
@ -231,9 +231,10 @@ static void __no_inline_not_in_flash_func(initialize_host_programs)(
&usb_edge_detector_debug_program, &pp->offset_eop,
c->debug_pin_eop);
eop_detect_fs_program_init(pp->pio_usb_rx, c->sm_eop, pp->offset_eop,
port->pin_dp, true, c->debug_pin_eop);
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);
@ -261,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;
@ -430,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,14 +18,13 @@ 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
#define PIO_USB_DP_PIN_DEFAULT 0
#endif
#define PIO_USB_DM_PIN_DEFAULT (PIO_USB_DP_PIN_DEFAULT + 1)
#define PIO_USB_TX_DEFAULT 0
#define PIO_SM_USB_TX_DEFAULT 0
#define PIO_USB_DMA_TX_DEFAULT 0
@ -31,12 +35,12 @@ typedef struct {
#define PIO_USB_DEBUG_PIN_NONE (-1)
#define PIO_USB_DEFAULT_CONFIG \
{ \
PIO_USB_DP_PIN_DEFAULT, PIO_USB_TX_DEFAULT, PIO_SM_USB_TX_DEFAULT, \
PIO_USB_DMA_TX_DEFAULT, PIO_USB_RX_DEFAULT, PIO_SM_USB_RX_DEFAULT, \
PIO_SM_USB_EOP_DEFAULT, NULL, PIO_USB_DEBUG_PIN_NONE, \
PIO_USB_DEBUG_PIN_NONE, /*skip_alarm_pool=*/false \
#define PIO_USB_DEFAULT_CONFIG \
{ \
PIO_USB_DP_PIN_DEFAULT, PIO_USB_TX_DEFAULT, PIO_SM_USB_TX_DEFAULT, \
PIO_USB_DMA_TX_DEFAULT, PIO_USB_RX_DEFAULT, PIO_SM_USB_RX_DEFAULT, \
PIO_SM_USB_EOP_DEFAULT, NULL, PIO_USB_DEBUG_PIN_NONE, \
PIO_USB_DEBUG_PIN_NONE, false, PIO_USB_PINOUT_DPDM \
}
#define PIO_USB_EP_POOL_CNT 32

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)(
@ -333,11 +333,11 @@ void pio_usb_host_port_reset_start(uint8_t root_idx) {
root->suspended = true;
// Force line state to SE0
pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00 << root->pin_dp),
(0b11u << root->pin_dp));
pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, 0,
(1 << root->pin_dp) | (1 << root->pin_dm));
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx,
(0b11u << root->pin_dp),
(0b11u << root->pin_dp));
(1 << root->pin_dp) | (1 << root->pin_dm),
(1 << root->pin_dp) | (1 << root->pin_dm));
}
void pio_usb_host_port_reset_end(uint8_t root_idx) {
@ -345,9 +345,8 @@ void pio_usb_host_port_reset_end(uint8_t root_idx) {
pio_port_t *pp = PIO_USB_PIO_PORT(0);
// line state to input
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx,
(0b00u << root->pin_dp),
(0b11u << root->pin_dp));
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, 0,
(1 << root->pin_dp) | (1 << root->pin_dm));
busy_wait_us(100); // TODO check if this is neccessary
@ -596,15 +595,16 @@ static void on_device_connect(pio_port_t *pp, root_port_t *root,
fullspeed_flag = false;
}
pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00 << root->pin_dp),
(0b11u << root->pin_dp));
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b11u << root->pin_dp),
(0b11u << root->pin_dp));
pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, 0,
(1 << root->pin_dp) | (1 << root->pin_dm));
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx,
(1 << root->pin_dp) | (1 << root->pin_dm),
(1 << root->pin_dp) | (1 << root->pin_dm));
busy_wait_ms(100);
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, (0b00u << root->pin_dp),
(0b11u << root->pin_dp));
pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, 0,
(1 << root->pin_dp) | (1 << root->pin_dm));
busy_wait_us(100);

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

@ -171,12 +171,16 @@ static __always_inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint jmp_pin) {
(jmp_pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
}
static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, int pin_debug) {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dp, 2, false);
static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm, int pin_debug) {
if (pin_dp < pin_dm) {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dp, 2, false);
} else {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dm, 2, false);
}
gpio_pull_down(pin_dp);
gpio_pull_down(pin_dp + 1); // dm
gpio_pull_down(pin_dm);
gpio_set_inover(pin_dp, GPIO_OVERRIDE_INVERT);
gpio_set_inover(pin_dp + 1, GPIO_OVERRIDE_INVERT);
gpio_set_inover(pin_dm, GPIO_OVERRIDE_INVERT);
pio_sm_config c;
@ -204,7 +208,7 @@ static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pi
}
static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset,
uint pin_dp, bool is_fs, int pin_debug) {
uint pin_dp, uint pin_dm, bool is_fs, int pin_debug) {
pio_sm_config c;
if (pin_debug < 0) {
@ -218,7 +222,7 @@ static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset,
}
sm_config_set_in_pins(&c, pin_dp); // for WAIT, IN
sm_config_set_jmp_pin(&c, pin_dp + 1); // for JMP
sm_config_set_jmp_pin(&c, pin_dm); // for JMP
sm_config_set_in_shift(&c, false, false, 8);

View file

@ -188,12 +188,16 @@ static __always_inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint jmp_pin) {
(pio->sm[sm].execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) |
(jmp_pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
}
static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, int pin_debug) {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dp, 2, false);
static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm, int pin_debug) {
if (pin_dp < pin_dm) {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dp, 2, false);
} else {
pio_sm_set_consecutive_pindirs(pio, sm, pin_dm, 2, false);
}
gpio_pull_down(pin_dp);
gpio_pull_down(pin_dp + 1); // dm
gpio_pull_down(pin_dm);
gpio_set_inover(pin_dp, GPIO_OVERRIDE_INVERT);
gpio_set_inover(pin_dp + 1, GPIO_OVERRIDE_INVERT);
gpio_set_inover(pin_dm, GPIO_OVERRIDE_INVERT);
pio_sm_config c;
if (pin_debug < 0) {
c = usb_nrzi_decoder_program_get_default_config(offset);
@ -214,7 +218,7 @@ static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pi
pio_sm_set_enabled(pio, sm, false);
}
static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset,
uint pin_dp, bool is_fs, int pin_debug) {
uint pin_dp, uint pin_dm, bool is_fs, int pin_debug) {
pio_sm_config c;
if (pin_debug < 0) {
c = usb_edge_detector_program_get_default_config(offset);
@ -226,7 +230,7 @@ static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset,
sm_config_set_sideset_pins(&c, pin_debug);
}
sm_config_set_in_pins(&c, pin_dp); // for WAIT, IN
sm_config_set_jmp_pin(&c, pin_dp + 1); // for JMP
sm_config_set_jmp_pin(&c, pin_dm); // for JMP
sm_config_set_in_shift(&c, false, false, 8);
float div;
if (is_fs) {

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);
}
%}
%}

View file

@ -11,17 +11,17 @@
#define USB_TX_EOP_OFFSET 4
#define USB_TX_EOP_DISABLER_LEN 4
// --------- //
// usb_tx_fs //
// --------- //
// ----------- //
// usb_tx_dpdm //
// ----------- //
#define usb_tx_fs_wrap_target 2
#define usb_tx_fs_wrap 21
#define usb_tx_dpdm_wrap_target 2
#define usb_tx_dpdm_wrap 21
#define usb_tx_fs_IRQ_COMP 0
#define usb_tx_fs_IRQ_EOP 1
#define usb_tx_dpdm_IRQ_COMP 0
#define usb_tx_dpdm_IRQ_EOP 1
static const uint16_t __not_in_flash("fs_program") usb_tx_fs_program_instructions[] = {
static const uint16_t __not_in_flash("tx_program") usb_tx_dpdm_program_instructions[] = {
0xf445, // 0: set y, 5 side 1
0xe083, // 1: set pindirs, 3
// .wrap_target
@ -49,31 +49,31 @@ static const uint16_t __not_in_flash("fs_program") usb_tx_fs_program_instruction
};
#if !PICO_NO_HARDWARE
static const struct pio_program __not_in_flash("fs_program") usb_tx_fs_program = {
.instructions = usb_tx_fs_program_instructions,
static const struct pio_program __not_in_flash("tx_program") usb_tx_dpdm_program = {
.instructions = usb_tx_dpdm_program_instructions,
.length = 22,
.origin = -1,
};
static inline pio_sm_config usb_tx_fs_program_get_default_config(uint offset) {
static inline pio_sm_config usb_tx_dpdm_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + usb_tx_fs_wrap_target, offset + usb_tx_fs_wrap);
sm_config_set_wrap(&c, offset + usb_tx_dpdm_wrap_target, offset + usb_tx_dpdm_wrap);
sm_config_set_sideset(&c, 3, true, false);
return c;
}
#endif
// ------------- //
// usb_tx_fs_pre //
// ------------- //
// --------------- //
// usb_tx_pre_dpdm //
// --------------- //
#define usb_tx_fs_pre_wrap_target 2
#define usb_tx_fs_pre_wrap 21
#define usb_tx_pre_dpdm_wrap_target 2
#define usb_tx_pre_dpdm_wrap 21
#define usb_tx_fs_pre_IRQ_COMP 0
#define usb_tx_fs_pre_IRQ_EOP 1
#define usb_tx_pre_dpdm_IRQ_COMP 0
#define usb_tx_pre_dpdm_IRQ_EOP 1
static const uint16_t __not_in_flash("fs_program") usb_tx_fs_pre_program_instructions[] = {
static const uint16_t __not_in_flash("tx_program") usb_tx_pre_dpdm_program_instructions[] = {
0xf445, // 0: set y, 5 side 1
0xe083, // 1: set pindirs, 3
// .wrap_target
@ -101,31 +101,31 @@ static const uint16_t __not_in_flash("fs_program") usb_tx_fs_pre_program_instruc
};
#if !PICO_NO_HARDWARE
static const struct pio_program __not_in_flash("fs_program") usb_tx_fs_pre_program = {
.instructions = usb_tx_fs_pre_program_instructions,
static const struct pio_program __not_in_flash("tx_program") usb_tx_pre_dpdm_program = {
.instructions = usb_tx_pre_dpdm_program_instructions,
.length = 22,
.origin = -1,
};
static inline pio_sm_config usb_tx_fs_pre_program_get_default_config(uint offset) {
static inline pio_sm_config usb_tx_pre_dpdm_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + usb_tx_fs_pre_wrap_target, offset + usb_tx_fs_pre_wrap);
sm_config_set_wrap(&c, offset + usb_tx_pre_dpdm_wrap_target, offset + usb_tx_pre_dpdm_wrap);
sm_config_set_sideset(&c, 3, true, false);
return c;
}
#endif
// --------- //
// usb_tx_ls //
// --------- //
// ----------- //
// usb_tx_dmdp //
// ----------- //
#define usb_tx_ls_wrap_target 2
#define usb_tx_ls_wrap 21
#define usb_tx_dmdp_wrap_target 2
#define usb_tx_dmdp_wrap 21
#define usb_tx_ls_IRQ_COMP 0
#define usb_tx_ls_IRQ_EOP 1
#define usb_tx_dmdp_IRQ_COMP 0
#define usb_tx_dmdp_IRQ_EOP 1
static const uint16_t __not_in_flash("ls_program") usb_tx_ls_program_instructions[] = {
static const uint16_t __not_in_flash("tx_program") usb_tx_dmdp_program_instructions[] = {
0xf845, // 0: set y, 5 side 2
0xe083, // 1: set pindirs, 3
// .wrap_target
@ -153,33 +153,91 @@ static const uint16_t __not_in_flash("ls_program") usb_tx_ls_program_instruction
};
#if !PICO_NO_HARDWARE
static const struct pio_program __not_in_flash("ls_program") usb_tx_ls_program = {
.instructions = usb_tx_ls_program_instructions,
static const struct pio_program __not_in_flash("tx_program") usb_tx_dmdp_program = {
.instructions = usb_tx_dmdp_program_instructions,
.length = 22,
.origin = -1,
};
static inline pio_sm_config usb_tx_ls_program_get_default_config(uint offset) {
static inline pio_sm_config usb_tx_dmdp_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + usb_tx_ls_wrap_target, offset + usb_tx_ls_wrap);
sm_config_set_wrap(&c, offset + usb_tx_dmdp_wrap_target, offset + usb_tx_dmdp_wrap);
sm_config_set_sideset(&c, 3, true, false);
return c;
}
#endif
// --------------- //
// usb_tx_pre_dmdp //
// --------------- //
#define usb_tx_pre_dmdp_wrap_target 2
#define usb_tx_pre_dmdp_wrap 21
#define usb_tx_pre_dmdp_IRQ_COMP 0
#define usb_tx_pre_dmdp_IRQ_EOP 1
static const uint16_t __not_in_flash("tx_program") usb_tx_pre_dmdp_program_instructions[] = {
0xf845, // 0: set y, 5 side 2
0xe083, // 1: set pindirs, 3
// .wrap_target
0x00ea, // 2: jmp !osre, 10
0xa142, // 3: nop [1]
0xdb01, // 4: irq nowait 1 side 2 [3]
0xe080, // 5: set pindirs, 0
0xa042, // 6: nop
0xa042, // 7: nop
0xc020, // 8: irq wait 0
0x0000, // 9: jmp 0
0x6021, // 10: out x, 1
0x002e, // 11: jmp !x, 14
0x1882, // 12: jmp y--, 2 side 2
0xa242, // 13: nop [2]
0xf445, // 14: set y, 5 side 1
0x00f1, // 15: jmp !osre, 17
0x0104, // 16: jmp 4 [1]
0x6021, // 17: out x, 1
0x0035, // 18: jmp !x, 21
0x148f, // 19: jmp y--, 15 side 1
0xa242, // 20: nop [2]
0xf845, // 21: set y, 5 side 2
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program __not_in_flash("tx_program") usb_tx_pre_dmdp_program = {
.instructions = usb_tx_pre_dmdp_program_instructions,
.length = 22,
.origin = -1,
};
static inline pio_sm_config usb_tx_pre_dmdp_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + usb_tx_pre_dmdp_wrap_target, offset + usb_tx_pre_dmdp_wrap);
sm_config_set_sideset(&c, 3, true, false);
return c;
}
#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_sm_config c = usb_tx_fs_program_get_default_config(offset);
pio_gpio_init(pio, pin_dm);
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);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
@ -188,17 +246,17 @@ static inline pio_sm_config usb_tx_ls_program_get_default_config(uint offset) {
float div = (float)clock_get_hz(clk_sys) / (48000000UL);
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_sm_config c = usb_tx_ls_program_get_default_config(offset);
pio_gpio_init(pio, pin_dm);
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);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
@ -207,7 +265,7 @@ static inline pio_sm_config usb_tx_ls_program_get_default_config(uint offset) {
float div = (float)clock_get_hz(clk_sys) / (6000000UL);
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);
}