PICOでUART2個増設
解決したいこと
PICO でUART増設したい(追加2個)
PIO0とPIO1で同じコード動かしたい同じ機能の(FORMAT)のUART増設したい
例)
使用ツールは SDK。
解決方法を教えて下さい。
発生している問題・エラー
下記コードで PIO0は動作します
PIIO1でうまく動作しません
該当するソースコード
int main()
{
stdio_init_all();
//Uart 2
PIO pio = pio0; // values: pio0, pio1 正しく動く
// PIO pio = pio1; // values: pio0, pio1 動かない
uint pin = 20; //20= No.26Pin rx pin. Any gpio is valid
uint irq = PIO0_IRQ_0; // values for pio0: PIO0_IRQ_0, PIO0_IRQ_1. values for pio1:O1_IRQ_0, PIO1_IRQ_1
uint baudrate = 9600;
uart_rx_init(pio, pin, baudrate);
uart_rx_set_handler(rx_handler, irq);
//Uart 3
//
PIO pio2 = pio0; // values: pio0, pio1
uint pin2 = 21; //21= No.27Pin rx pin. Any gpio is valid
uint irq2 = PIO0_IRQ_0; // values for pio0: PIO0_IRQ_0, PIO0_IRQ_1. values for pio1: PIO1_IRQ_0, PIO1_IRQ_1
uint baudrate2 = 9600;
// uart_rx_init(pio2, pin2, baudrate2);
// uart_rx_set_handler(rx_handler2, irq2);
### 自分で試したこと
pio1:O1_IRQ_0, PIO1_IRQ_1 色々変えてみたが駄目です
-----
#include "uart_rx.h"
#define BUFFER_SIZE (1 << UART_RX_BUFFER_RING_BITS)
static const uint reload_counter_ = 0xffffffff;
static uint sm_, offset_, buffer_pos_, irq_, dma_channel_, dma_channel_reload_counter_;
static PIO pio_;
static void (*handler_)() = NULL;
static uint8_t buffer_[BUFFER_SIZE] __attribute__((aligned(BUFFER_SIZE * sizeof(uint8_t))));
static inline void handler_pio(void);
void uart_rx_init(PIO pio, uint pin, uint baudrate)
{
// init pio
pio_ = pio;
sm_ = pio_claim_unused_sm(pio_, true);
pio_sm_set_consecutive_pindirs(pio_, sm_, pin, 1, false);
// pio_sm_set_consecutive_pindirs(pio_, sm_, pin, 1, false);
pio_gpio_init(pio_, pin);
gpio_pull_up(pin);
offset_ = pio_add_program(pio_, &uart_rx_program);
pio_sm_config pio_config = uart_rx_program_get_default_config(offset_);
sm_config_set_in_pins(&pio_config, pin);
sm_config_set_jmp_pin(&pio_config, pin);
sm_config_set_in_shift(&pio_config, true, false, 32);
sm_config_set_fifo_join(&pio_config, PIO_FIFO_JOIN_RX);
float div = (float)clock_get_hz(clk_sys) / (8 * baudrate);
sm_config_set_clkdiv(&pio_config, div);
pio_sm_init(pio_, sm_, offset_, &pio_config);
// init dma reload counter
dma_channel_reload_counter_ = dma_claim_unused_channel(true);
dma_channel_ = dma_claim_unused_channel(true);
dma_channel_config config_dma_channel_reload_counter = dma_channel_get_default_config(dma_channel_reload_counter_);
channel_config_set_transfer_data_size(&config_dma_channel_reload_counter, DMA_SIZE_32);
channel_config_set_write_increment(&config_dma_channel_reload_counter, false);
channel_config_set_read_increment(&config_dma_channel_reload_counter, false);
dma_channel_configure(
dma_channel_reload_counter_,
&config_dma_channel_reload_counter,
&dma_hw->ch[dma_channel_].al1_transfer_count_trig, // write address
&reload_counter_, // read address
1,
false);
// init dma buffer
dma_channel_config config_dma = dma_channel_get_default_config(dma_channel_);
channel_config_set_transfer_data_size(&config_dma, DMA_SIZE_8);
channel_config_set_ring(&config_dma, true, UART_RX_BUFFER_RING_BITS);
channel_config_set_write_increment(&config_dma, true);
channel_config_set_read_increment(&config_dma, false);
channel_config_set_dreq(&config_dma, pio_get_dreq(pio_, sm_, false));
channel_config_set_chain_to(&config_dma, dma_channel_reload_counter_);
dma_channel_configure(
dma_channel_,
&config_dma,
&buffer_, // write address
(uint8_t *)&pio0->rxf[0] + 3, // read address
0xffffffff,
false);
dma_channel_start(dma_channel_);
pio_sm_set_enabled(pio_, sm_, true);
}
void uart_rx_set_handler(uart_rx_handler_t handler, uint irq)
{
handler_ = handler;
if (irq == PIO0_IRQ_0 || irq == PIO1_IRQ_0)
pio_set_irq0_source_enabled(pio_, (enum pio_interrupt_source)(pis_interrupt0 + UART_RX_IRQ_NUM), true);
else
pio_set_irq1_source_enabled(pio_, (enum pio_interrupt_source)(pis_interrupt0 + UART_RX_IRQ_NUM), true);
pio_interrupt_clear(pio_, UART_RX_IRQ_NUM);
irq_set_exclusive_handler(irq, handler_pio);
irq_set_enabled(irq, true);
}
char uart_rx_read(void)
{
uint transfer_count = 0xffffffff - dma_hw->ch[dma_channel_].transfer_count;
if (uart_rx_overflow())
buffer_pos_ = transfer_count - BUFFER_SIZE;
char value = buffer_[buffer_pos_ % BUFFER_SIZE];
if (buffer_pos_ < transfer_count)
buffer_pos_++;
return value;
}
char uart_rx_peek(void)
{
uint transfer_count = 0xffffffff - dma_hw->ch[dma_channel_].transfer_count;
if (uart_rx_overflow())
buffer_pos_ = transfer_count - BUFFER_SIZE;
return buffer_[buffer_pos_ % BUFFER_SIZE];
}
uint uart_rx_available(void)
{
uint available = 0xffffffff - dma_hw->ch[dma_channel_].transfer_count - buffer_pos_;
if (available > BUFFER_SIZE)
available = BUFFER_SIZE;
return available;
}
bool uart_rx_overflow(void)
{
uint transfer_count = 0xffffffff - dma_hw->ch[dma_channel_].transfer_count;
if (transfer_count - buffer_pos_ > BUFFER_SIZE)
return true;
return false;
}
void uart_rx_remove(void)
{
handler_ = NULL;
pio_remove_program(pio_, &uart_rx_program, offset_);
pio_sm_unclaim(pio_, sm_);
dma_channel_abort(dma_channel_);
dma_channel_unclaim(dma_channel_);
}
static inline void handler_pio(void)
{
if (handler_)
handler_();
pio_interrupt_clear(pio_, UART_RX_IRQ_NUM);
}