rapberrypi-pico的pio状态机奇怪的问题

发布于 2025-02-09 11:36:25 字数 4324 浏览 2 评论 0原文

我尝试使用PIO实现TFT控件。我为我的TFT的每个同步信号(Clock,de,hsync,vsync)编写了4台PIO状态机。其中3个工作无缝工作,但是如果我添加vsync模块,则整个pico冻结。它不会更改引脚,也不会使用重复计时器的LED眨眼。 以下是我的初始化的样子:

PIO pio = pio0;

uint h_offset = pio_add_program(pio, &hsync_program);
uint v_offset = pio_add_program(pio, &vsync_program);
uint c_offset = pio_add_program(pio, &clock_program);
uint d_offset = pio_add_program(pio, &de_program);

hsync_program_init(pio, 0, h_offset, HSYNC_PIN);
vsync_program_init(pio, 1, v_offset, VSYNC_PIN);
clock_program_init(pio, 2, c_offset, CLOCK_PIN);
de_program_init(pio, 3, d_offset, DE_PIN);

pio_sm_set_enabled(pio, 0, true);
pio_sm_set_enabled(pio, 1, true);
pio_sm_set_enabled(pio, 2, true);
pio_sm_set_enabled(pio, 3, true);
pio_sm_put_blocking(pio, 0, TFT_WIDTH);
pio_sm_put_blocking(pio, 1, TFT_HEIGHT);

这是vsync.pio的内容:

.define v_back_porch  12
.define v_front_porch 8
.define v_sync_len    4

.program vsync
    pull block
    mov y, osr
.wrap_target
    set pins, 0
    set x, v_sync_len
vactive:
    wait 1 irq 2
    jmp x-- vactive
; back porch
    set pins, 1
    set x, (v_back_porch - v_sync_len)
 vbporch:
     wait 1 irq 2
     jmp x-- vbporch
; main cycle
    mov x, y
vmain:
    wait 1 irq 2
    jmp x-- vmain
    set x, v_front_porch
vfporch:
    wait 1 irq 2
    jmp x-- vfporch
; set sync interrupt for RGB
;    irq 3
.wrap             ; sync forever!

% c-sdk {
// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin

void vsync_program_init(PIO pio, uint sm, uint offset, uint pin) {
   pio_gpio_init(pio, pin);
   pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
   pio_sm_config c = vsync_program_get_default_config(offset);
   sm_config_set_set_pins(&c, pin, 1);
   pio_sm_init(pio, sm, offset, &c);
}
%}

如果我删除了Vsync状态机的每一行代码,则一切都可以正常工作并生成了我想要的。 添加uint v_offset = pio_add_program(pio,& vsync_program)之后;它不再起作用了。汇编过程中没有错误或评论。我已经尝试了几乎所有事情。看来,X和Y寄存器是错误的,但是如果不使用它们,我就无法做出反击。 我在hsync.pio中具有相同的代码,但是我没有任何问题。 这是vsync.pio的编译结果:

static const uint16_t vsync_program_instructions[] = {
    0x80a0, //  0: pull   block                      
    0xa047, //  1: mov    y, osr                     
            //     .wrap_target
    0xe000, //  2: set    pins, 0                    
    0xe024, //  3: set    x, 4                       
    0x20c2, //  4: wait   1 irq, 2                   
    0x0044, //  5: jmp    x--, 4                     
    0xe001, //  6: set    pins, 1                    
    0xe028, //  7: set    x, 8                       
    0x20c2, //  8: wait   1 irq, 2                   
    0x0048, //  9: jmp    x--, 8                     
    0xa022, // 10: mov    x, y                       
    0x20c2, // 11: wait   1 irq, 2                   
    0x004b, // 12: jmp    x--, 11                    
    0xe028, // 13: set    x, 8                       
    0x20c2, // 14: wait   1 irq, 2                   
    0x004e, // 15: jmp    x--, 14                    
            //     .wrap
};

供hsync.pio进行比较:

static const uint16_t hsync_program_instructions[] = {
    0x80a0, //  0: pull   block                      
    0xa047, //  1: mov    y, osr                     
            //     .wrap_target
    0xe000, //  2: set    pins, 0                    
    0xe022, //  3: set    x, 2                       
    0x20c0, //  4: wait   1 irq, 0                   
    0x0044, //  5: jmp    x--, 4                     
    0xe001, //  6: set    pins, 1                    
    0xe022, //  7: set    x, 2                       
    0x20c0, //  8: wait   1 irq, 0                   
    0x0048, //  9: jmp    x--, 8                     
    0xc001, // 10: irq    nowait 1                   
    0xa022, // 11: mov    x, y                       
    0x20c0, // 12: wait   1 irq, 0                   
    0x004c, // 13: jmp    x--, 12                    
    0xc001, // 14: irq    nowait 1                   
    0xe024, // 15: set    x, 4                       
    0x20c0, // 16: wait   1 irq, 0                   
    0x0050, // 17: jmp    x--, 16                    
    0xc002, // 18: irq    nowait 2                   
            //     .wrap
};

我没有看到任何显着差异。 这样的行为可能会有什么?

I try to implement TFT control using PIO. I have written 4 PIO state machines for every sync signal of my TFT (CLOCK, DE, HSYNC, VSYNC). 3 of them work seamless, but if I add the VSYNC module, the whole Pico freezes. It doesn't change pins and doesn't blink with a LED using repeating timer.
Here is how my initialization looks like:

PIO pio = pio0;

uint h_offset = pio_add_program(pio, &hsync_program);
uint v_offset = pio_add_program(pio, &vsync_program);
uint c_offset = pio_add_program(pio, &clock_program);
uint d_offset = pio_add_program(pio, &de_program);

hsync_program_init(pio, 0, h_offset, HSYNC_PIN);
vsync_program_init(pio, 1, v_offset, VSYNC_PIN);
clock_program_init(pio, 2, c_offset, CLOCK_PIN);
de_program_init(pio, 3, d_offset, DE_PIN);

pio_sm_set_enabled(pio, 0, true);
pio_sm_set_enabled(pio, 1, true);
pio_sm_set_enabled(pio, 2, true);
pio_sm_set_enabled(pio, 3, true);
pio_sm_put_blocking(pio, 0, TFT_WIDTH);
pio_sm_put_blocking(pio, 1, TFT_HEIGHT);

Here is the content of the vsync.pio:

.define v_back_porch  12
.define v_front_porch 8
.define v_sync_len    4

.program vsync
    pull block
    mov y, osr
.wrap_target
    set pins, 0
    set x, v_sync_len
vactive:
    wait 1 irq 2
    jmp x-- vactive
; back porch
    set pins, 1
    set x, (v_back_porch - v_sync_len)
 vbporch:
     wait 1 irq 2
     jmp x-- vbporch
; main cycle
    mov x, y
vmain:
    wait 1 irq 2
    jmp x-- vmain
    set x, v_front_porch
vfporch:
    wait 1 irq 2
    jmp x-- vfporch
; set sync interrupt for RGB
;    irq 3
.wrap             ; sync forever!

% c-sdk {
// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin

void vsync_program_init(PIO pio, uint sm, uint offset, uint pin) {
   pio_gpio_init(pio, pin);
   pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
   pio_sm_config c = vsync_program_get_default_config(offset);
   sm_config_set_set_pins(&c, pin, 1);
   pio_sm_init(pio, sm, offset, &c);
}
%}

If I remove every line of code for the vsync state machine, everything works and generates exactly that, what I want.
After adding uint v_offset = pio_add_program(pio, &vsync_program); it doesn't work anymore. There are no errors or comments during the compilation. I have already tried almost everything. It seems, that registers x and y are faulty, but I can't make a counter without using them.
I have pretty the same code in the hsync.pio, but I don't have any problems with it.
Here is a compiled result for the vsync.pio:

static const uint16_t vsync_program_instructions[] = {
    0x80a0, //  0: pull   block                      
    0xa047, //  1: mov    y, osr                     
            //     .wrap_target
    0xe000, //  2: set    pins, 0                    
    0xe024, //  3: set    x, 4                       
    0x20c2, //  4: wait   1 irq, 2                   
    0x0044, //  5: jmp    x--, 4                     
    0xe001, //  6: set    pins, 1                    
    0xe028, //  7: set    x, 8                       
    0x20c2, //  8: wait   1 irq, 2                   
    0x0048, //  9: jmp    x--, 8                     
    0xa022, // 10: mov    x, y                       
    0x20c2, // 11: wait   1 irq, 2                   
    0x004b, // 12: jmp    x--, 11                    
    0xe028, // 13: set    x, 8                       
    0x20c2, // 14: wait   1 irq, 2                   
    0x004e, // 15: jmp    x--, 14                    
            //     .wrap
};

and for the hsync.pio to compare:

static const uint16_t hsync_program_instructions[] = {
    0x80a0, //  0: pull   block                      
    0xa047, //  1: mov    y, osr                     
            //     .wrap_target
    0xe000, //  2: set    pins, 0                    
    0xe022, //  3: set    x, 2                       
    0x20c0, //  4: wait   1 irq, 0                   
    0x0044, //  5: jmp    x--, 4                     
    0xe001, //  6: set    pins, 1                    
    0xe022, //  7: set    x, 2                       
    0x20c0, //  8: wait   1 irq, 0                   
    0x0048, //  9: jmp    x--, 8                     
    0xc001, // 10: irq    nowait 1                   
    0xa022, // 11: mov    x, y                       
    0x20c0, // 12: wait   1 irq, 0                   
    0x004c, // 13: jmp    x--, 12                    
    0xc001, // 14: irq    nowait 1                   
    0xe024, // 15: set    x, 4                       
    0x20c0, // 16: wait   1 irq, 0                   
    0x0050, // 17: jmp    x--, 16                    
    0xc002, // 18: irq    nowait 2                   
            //     .wrap
};

I don't see any significant differences there.
What could be the reasong for such a behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨夜星沙 2025-02-16 11:36:25

它非常小,但是每个PIO实例(不是实例中的每个状态机!)仅允许32个说明。因此,我必须使用PIO1,但是还有另一个问题 - 一个PIO的IRQ不会与另一个PIO相互作用。

pico pio的结构让我真的很难过:(

It's very pitty, but every PIO instance (not every state machine in the instance!) allows 32 instructions only. So I have to use PIO1, but there is another problem - IRQs from one PIO don't interact with another PIO.

The structure of the Pico PIO makes me really sad :(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文