rapberrypi-pico的pio状态机奇怪的问题
我尝试使用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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它非常小,但是每个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 :(