硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3126|回复: 7
收起左侧

直接在C语言文件中定义pio汇编二进制指令数组,免去汇编器

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2022-3-17 18:08:05 | 显示全部楼层 |阅读模式
直接在C语言中定义pio汇编二进制常量数组,免去用ASM汇编器自动生成 xxx.pio.h 文件。

2022-11-27 V1.1 升级更新
pio_asm_def.h (4.63 KB, 下载次数: 28)

2022-03-17 V1.0 初版
pio_asm_def.h (3.68 KB, 下载次数: 18)
blink.c (2.47 KB, 下载次数: 26)
范例: 闪烁3个引脚
blink.c :
[C] 纯文本查看 复制代码
#include "pio_asm_def.h"

#define blink_wrap_target 2
#define blink_wrap 7


static const uint16_t blink_program_instructions[] = {
    // 0x80a0, 0: pull   block
    C_PULL | PULL_BLOCK,
   
    //  0x6040, 1: out    y, 32
    C_OUT | OUT_SRC_Y | BIT_COUNT_32,
   
    //     .wrap_target
    // 0xa022,  2: mov    x, y
    C_MOV | MOV_DEST_X | MOV_SRC_Y,
   
    // 0xe001,  3: set    pins, 1
    C_SET | SET_DEST_PINS | 1,
   
    //  0x0044, 4: jmp    x--, 4      
    C_JMP | IF_X_DEC_EQU_1 | 4,
   
    //  0xa022, 5: mov    x, y        
    C_MOV | MOV_DEST_X | MOV_SRC_Y,
        
    // 0xe000,  6: set    pins, 0
    C_SET | SET_DEST_PINS | 0,
        
    //  0x0047, 7: jmp    x--, 7                     
    C_JMP | IF_X_DEC_EQU_1 | 7
   
    //     .wrap
};


static const struct pio_program blink_program = {
    .instructions = blink_program_instructions,
    .length = 8,
    .origin = -1,
};


static inline pio_sm_config blink_program_get_default_config(uint offset) {
    pio_sm_config c = pio_get_default_sm_config();
    sm_config_set_wrap(&c, offset + blink_wrap_target, offset + blink_wrap);
    return c;
}


// 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 blink_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 = blink_program_get_default_config(offset);
    sm_config_set_set_pins(&c, pin, 1);
    pio_sm_init(pio, sm, offset, &c);
}


void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq);


int TestPioMain() {
    setup_default_uart();


    // todo get free sm
    PIO pio = pio0;
    uint offset = pio_add_program(pio, &blink_program);
    printf("Loaded program at %d\n", offset);


    blink_pin_forever(pio, 0, offset, 0, 3);
    blink_pin_forever(pio, 1, offset, 6, 4);
    blink_pin_forever(pio, 2, offset, 11, 1);
}


void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) {
    blink_program_init(pio, sm, offset, pin);
    pio_sm_set_enabled(pio, sm, true);
   
    pio->txf[sm] = clock_get_hz(clk_sys) / (2 * freq);
}



pio_asm_def.h:
[Lua] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*    模块名称 : RP2040 PIO指令代码定义
*    文件名称 : pio_asm_def.h
*    版    本 : V1.1
*    说    明 : 用C语言宏直接构建PIO指令二进制代码
*    修改记录 :
*        版本号  日期         作者       说明
*        V1.0    2022-03-19   armfly     正式发布
*        V1.1    2022-11-27   armfly     修改几个bug:
*                               - MOV_OP_INVERT, SET_DEST_PINS, SET_DEST_X,SET_DEST_Y
*                               - SET_DEST_PINDIRS, MOV_OP_INVERT
*                               - 新增 SIDE_SET(x), IRQ_SET
*                               - 更名 IF_X_DEC_EQU_1 -> IF_X_DEC_NONE_ZERO
*                               - 更名 IF_Y_DEC_EQU_1 -> IF_Y_DEC_NONE_ZERO
*
*    Copyright (C), 2022-2030, 安富莱电子 [url]www.anfulai.cn[/url]、[url]www.armbbs.cn[/url]
*
*********************************************************************************************************
*/

#ifndef _PIO_ASM_DEF_H
#define _PIO_ASM_DEF_H

#define C_JMP   (0 << 13)
    enum IFEnum
    {
        IF_X_EQU_0          = (1 << 5),
        IF_X_DEC_NONE_ZERO  = (2 << 5),
        IF_Y_EQU_0          = (3 << 5),
        IF_Y_DEC_NONE_ZERO  = (4 << 5),
        IF_X_NOT_EQU_Y      = (5 << 5),
        IF_PIN              = (6 << 5),
        IF_OSR_NOT_EMPTY    = (7 << 5)
    };
    enum TAREnum
    {
        TAR_0,  TAR_1,  TAR_2,  TAR_3,  TAR_4,  TAR_5,  TAR_6,  TAR_7,
        TAR_8,  TAR_9,  TAR_10, TAR_11, TAR_12, TAR_13, TAR_14, TAR_15,
        TAR_16, TAR_17, TAR_18, TAR_19, TAR_20, TAR_21, TAR_22, TAR_23,
        TAR_24, TAR_25, TAR_26, TAR_27, TAR_28, TAR_29, TAR_30, TAR_31   
    };

#define C_WAIT  (1 << 13)
    enum WaitForEnum
    {
        WAIT_FOR_0 = (0 << 7),
        WAIT_FOR_1 = (1 << 7)	         
    };
    enum WaitSrcEnum
    {
        WAIT_SRC_GPIO = (0 << 5),
        WAIT_SRC_PIN  = (1 << 5),
        WAIT_SRC_IRQ  = (2 << 5),
    };

#define C_IN    (2 << 13)
    enum InSrcEnum
    {
        IN_SRC_PINS   = (0 << 5),
        IN_SRC_X      = (1 << 5),
        IN_SRC_Y      = (2 << 5),
        IN_SRC_NULL   = (3 << 5),
        IN_SRC_ISR    = (6 << 5),
        IN_SRC_OSR    = (7 << 5),    
    };

#define C_OUT   (3 << 13)
    enum OutDestEnum
    {
        OUT_DEST_PINS = (0 << 5),
        OUT_DEST_X    = (1 << 5),
        OUT_DEST_Y    = (2 << 5),
        OUT_DEST_NULL = (3 << 5),
        OUT_DEST_PINDIRS = (4 << 5),
        OUT_DEST_PC   = (5 << 5),    
        OUT_DEST_ISR  = (6 << 5),
        OUT_DEST_EXEC = (7 << 5),    
    };

    enum 
    {
        BIT_COUNT_32 = 0, 
        BIT_COUNT_1, BIT_COUNT_2, BIT_COUNT_3, BIT_COUNT_4, 
        BIT_COUNT_5, BIT_COUNT_6, BIT_COUNT_7, BIT_COUNT_8, 
        BIT_COUNT_9, BIT_COUNT_10, BIT_COUNT_11, BIT_COUNT_12, 
        BIT_COUNT_13, BIT_COUNT_14, BIT_COUNT_15, BIT_COUNT_16, 
        BIT_COUNT_17, BIT_COUNT_18, BIT_COUNT_19, BIT_COUNT_20, 
        BIT_COUNT_21, BIT_COUNT_22, BIT_COUNT_23, BIT_COUNT_24,
        BIT_COUNT_25, BIT_COUNT_26, BIT_COUNT_27, BIT_COUNT_28, 
        BIT_COUNT_29, BIT_COUNT_30, BIT_COUNT_31,
    };
    
#define C_PUSH  (4 << 13)
    enum
    {
        IF_FULL      = (1 << 6),
        PUSH_BLOCK   = (1 << 5),
    };
#define C_PULL  ((4 << 13) | (1 << 7))
    enum
    {
        IF_EMPTY     = (1 << 6),
        PULL_BLOCK   = (1 << 5),
    };
#define C_MOV   (5 << 13)
    enum
    {
	    MOV_DEST_PINS = (0 << 5),
        MOV_DEST_X    = (1 << 5),
        MOV_DEST_Y    = (2 << 5),
        MOV_DEST_EXEC = (4 << 5),
        MOV_DEST_PC   = (5 << 5),
        MOV_DEST_ISR  = (6 << 5),
        MOV_DEST_OSR  = (7 << 5),
    };
    enum
    {
        MOV_OP_NONE      = (0 << 3),
        MOV_OP_INVERT    = (1 << 3),
    };
    enum
    {
        MOV_SRC_PINS   = (0 << 0),
        MOV_SRC_X      = (1 << 0),
        MOV_SRC_Y      = (2 << 0),
        MOV_SRC_NULL   = (3 << 0),
        MOV_SRC_STATUS = (5 << 0),
        MOV_SRC_ISR    = (6 << 0),
        MOV_SRC_OSR    = (7 << 0),    
    };

#define C_IRQ   (6 << 13)
    enum
    {
        IRQ_SET        = (0 << 6),
        IRQ_CLEAR      = (1 << 6),
        
        IRQ_WAIT       = (1 << 5), 
    };

#define C_SET   (7 << 13)
    enum
    {
        SET_DEST_PINS    = (0 << 5),
        SET_DEST_X       = (1 << 5),
        SET_DEST_Y       = (2 << 5),
        SET_DEST_PINDIRS = (4 << 5),
    };
#endif

/* 侧集指令 Delay/side-set  5 bits */
#define SIDE_SET(x)  (x << 8)

/****************************** END ***************************************************/










回复

使用道具 举报

13

主题

86

回帖

125

积分

初级会员

积分
125
发表于 2022-10-27 18:02:36 | 显示全部楼层
有几个指令没移位或移错位,让我调了几晚上。。。。
回复

使用道具 举报

8

主题

78

回帖

102

积分

初级会员

积分
102
发表于 2022-10-28 19:33:48 来自手机 | 显示全部楼层
lg676041036 发表于 2022-10-27 18:02
有几个指令没移位或移错位,让我调了几晚上。。。。

哪里错了,交流一下呗
回复

使用道具 举报

13

主题

86

回帖

125

积分

初级会员

积分
125
发表于 2022-10-29 23:47:23 | 显示全部楼层
he2002512 发表于 2022-10-28 19:33
哪里错了,交流一下呗

主要是SET指令和IRQ指令对照数据手册对比一下就行了
我改了一下
[C] 纯文本查看 复制代码
// -------------------------------------------------- //
// 文件名 : pio_asm_def.h
// 说  明 : 用C语言宏直接构建PIO指令二进制代码。安富莱电子
// 作  者 : 安富莱电子, 可免费试用
// -------------------------------------------------- //

#ifndef _PIO_ASM_DEF_H
#define _PIO_ASM_DEF_H

#define SIDEONE 12
#define HIGH 1
#define LOW 0
#define DELAY 8
#define C_JMP   (0 << 13)
    enum IFEnum
    {
        IF_X_EQU_0       = (1 << 5),
        IF_X_DEC_EQU_1   = (2 << 5),
        IF_Y_EQU_0       = (3 << 5),
        IF_Y_DEC_EQU_1   = (4 << 5),
        IF_X_NOT_EQU_Y   = (5 << 5),
        IF_PIN           = (6 << 5),
        IF_OSR_NOT_EMPTY = (7 << 5)
    };
    enum TAREnum
    {
        TAR_0,  TAR_1,  TAR_2,  TAR_3,  TAR_4,  TAR_5,  TAR_6,  TAR_7,
        TAR_8,  TAR_9,  TAR_10, TAR_11, TAR_12, TAR_13, TAR_14, TAR_15,
        TAR_16, TAR_17, TAR_18, TAR_19, TAR_20, TAR_21, TAR_22, TAR_23,
        TAR_24, TAR_25, TAR_26, TAR_27, TAR_28, TAR_29, TAR_30, TAR_31   
    };

#define C_WAIT  (1 << 13)
    enum WaitForEnum
    {
        WAIT_FOR_0 = (0 << 7),
        WAIT_FOR_1 = (1 << 7)	         
    };
    enum WaitSrcEnum
    {
        WAIT_SRC_GPIO = (0 << 5),
        WAIT_SRC_PIN  = (1 << 5),
        WAIT_SRC_IRQ  = (2 << 5),
    };

#define C_IN    (2 << 13)
    enum InSrcEnum
    {
        IN_SRC_PINS   = (0 << 5),
        IN_SRC_X      = (1 << 5),
        IN_SRC_Y      = (2 << 5),
        IN_SRC_NULL   = (3 << 5),
        IN_SRC_ISR    = (6 << 5),
        IN_SRC_OSR    = (7 << 5),    
    };

#define C_OUT   (3 << 13)
    enum OutSrcEnum
    {
        OUT_SRC_PINS = (0 << 5),
        OUT_SRC_X    = (1 << 5),
        OUT_SRC_Y    = (2 << 5),
        OUT_SRC_NULL = (3 << 5),
        OUT_SRC_PINDIRS = (4 << 5),
        OUT_SRC_PC   = (5 << 5),    
        OUT_SRC_ISR  = (6 << 5),
        OUT_SRC_EXEC = (7 << 5),    
    };

    enum 
    {
        BIT_COUNT_32 = 0, 
        BIT_COUNT_1, BIT_COUNT_2, BIT_COUNT_3, BIT_COUNT_4, 
        BIT_COUNT_5, BIT_COUNT_6, BIT_COUNT_7, BIT_COUNT_8, 
        BIT_COUNT_9, BIT_COUNT_10, BIT_COUNT_11, BIT_COUNT_12, 
        BIT_COUNT_13, BIT_COUNT_14, BIT_COUNT_15, BIT_COUNT_16, 
        BIT_COUNT_17, BIT_COUNT_18, BIT_COUNT_19, BIT_COUNT_20, 
        BIT_COUNT_21, BIT_COUNT_22, BIT_COUNT_23, BIT_COUNT_24,
        BIT_COUNT_25, BIT_COUNT_26, BIT_COUNT_27, BIT_COUNT_28, 
        BIT_COUNT_29, BIT_COUNT_30, BIT_COUNT_31,
    };
    
#define C_PUSH  (4 << 13)
    enum
    {
        IF_FULL      = (1 << 6),
        PUSH_BLOCK   = (1 << 5),
    };
#define C_PULL  ((4 << 13) | (1 << 7))
    enum
    {
        IF_EMPTY     = (1 << 6),
        PULL_BLOCK   = (1 << 5),
    };
#define C_MOV   (5 << 13)
    enum
    {
	    MOV_DEST_PINS = (0 << 5),
        MOV_DEST_X    = (1 << 5),
        MOV_DEST_Y    = (2 << 5),
        MOV_DEST_EXEC = (4 << 5),
        MOV_DEST_PC   = (5 << 5),
        MOV_DEST_ISR  = (6 << 5),
        MOV_DEST_OSR  = (7 << 5),
    };
    enum
    {
        MOV_OP_NONE      = (0 << 3),
        MOV_OP_INVERT    = (1 << 3),
    };
    enum
    {
        MOV_SRC_PINS   = (0 << 0),
        MOV_SRC_X      = (1 << 0),
        MOV_SRC_Y      = (2 << 0),
        MOV_SRC_NULL   = (3 << 0),
        MOV_SRC_STATUS = (5 << 0),
        MOV_SRC_ISR    = (6 << 0),
        MOV_SRC_OSR    = (7 << 0),    
    };

#define C_IRQ   (6 << 13)
    enum
    {
        IRQ_CLEAR      = (1 << 6),
        IRQ_WAIT       = (1 << 5), 
    };

#define C_SET   (7 << 13)
    enum
    {
        SET_DEST_PINS = (0<<5),
        SET_DEST_X = (1<<5),
        SET_DEST_Y = (2<<5),
        SET_DEST_PINDIRS = (4<<5),
    };
#endif

/****************************** END ***************************************************/


回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2022-11-27 09:25:16 | 显示全部楼层
lg676041036 发表于 2022-10-29 23:47
主要是SET指令和IRQ指令对照数据手册对比一下就行了
我改了一下
[mw_shl_code=c,true]// ------------- ...

谢谢支持。我已更新楼主位文件。

*    修改记录 :
*        版本号  日期         作者       说明
*        V1.0    2022-03-19   armfly     正式发布
*        V1.1    2022-11-27   armfly     修改几个bug:
*                               - MOV_OP_INVERT, SET_DEST_PINS, SET_DEST_X,SET_DEST_Y
*                               - SET_DEST_PINDIRS, MOV_OP_INVERT
*                               - 新增 SIDE_SET(x), IRQ_SET
*                               - 更名 IF_X_DEC_EQU_1 -> IF_X_DEC_NONE_ZERO
*                               - 更名 IF_Y_DEC_EQU_1 -> IF_Y_DEC_NONE_ZERO

回复

使用道具 举报

1

主题

26

回帖

29

积分

新手上路

积分
29
发表于 2022-11-29 17:53:39 | 显示全部楼层
厉害  学习学习
回复

使用道具 举报

19

主题

129

回帖

186

积分

初级会员

积分
186
QQ
发表于 2023-6-4 10:45:00 | 显示全部楼层
请教一下,pio是不是跟dma差不多,非CPU干预,但是需要自己编程很多事件来做IO的控制流程,从来没接触过这个
回复

使用道具 举报

13

主题

86

回帖

125

积分

初级会员

积分
125
发表于 2023-6-19 17:18:26 | 显示全部楼层
lovelessing... 发表于 2023-6-4 10:45
请教一下,pio是不是跟dma差不多,非CPU干预,但是需要自己编程很多事件来做IO的控制流程,从来没接触过这 ...

相当于一个超精简指令的单片机,有两个PIO,每个PIO最多四个单片机,每个PIO程序存储器最多32条(忘了具体数目了),四个单片机一起用,至于RAM是没有的,只能操作寄存器。然后可以与DMA配合使用读写数据。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 21:45 , Processed in 0.182803 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表