先楫半导体HPMicro
直播中

王桂兰

7年用户 1180经验值
私信 关注
[经验]

通过***构建一个同步八进制计数器的代码示例

一个简单的 PLA 例程,详情可见 https://zhuanlan.zhihu.com/p/634267224




#include "board.h"
#include "hpm_sysctl_drv.h"
#include "hpm_gptmr_drv.h"
#include "hpm_trgm_drv.h"
#include "hpm_pla_drv.h"

void set_pla0_channel0();
void set_pla0_channel1();
void set_pla0_channel2();

int main(void)
{
    board_init();

    // GPTMR0CH2, f = 1m, reload = 100m/1m = 100 使用 GPTMR0 CH2 生成一个频率为 1M,占空比 50% 的 PWM
    uint32_t reload = 100;
    gptmr_channel_config_t config_ch2;
    gptmr_channel_get_default_config(HPM_GPTMR0, &config_ch2);
    config_ch2.reload = reload;
    config_ch2.cmp[0] = reload*0.5;
    config_ch2.cmp[1] = reload;
    config_ch2.enable_software_sync = true;
    config_ch2.cmp_initial_polarity_high = false;
    gptmr_channel_config(HPM_GPTMR0, 2, &config_ch2, false);
    gptmr_channel_reset_count(HPM_GPTMR0, 2);

    // GPTMR0CH2 -> TRGM0 -> PB23 将 PWM 输出到 PB23 引脚
    HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_TRGM0_P_03;
    trgm_output_t trgm_output_cfg_pb23;
    trgm_output_cfg_pb23.invert = false;
    trgm_output_cfg_pb23.type = trgm_output_same_as_input;
    trgm_output_cfg_pb23.input = HPM_TRGM0_INPUT_SRC_GPTMR0_OUT2;
    trgm_output_config(HPM_TRGM0, TRGM_TRGOCFG_TRGM_OUT3, &trgm_output_cfg_pb23);
    trgm_enable_io_output(HPM_TRGM0, 1 << TRGM_TRGOCFG_TRGM_OUT3);

    // GPTMR0CH2 -> TRGM0 -> PLA0IN0 将 PWM 输出到 PLA0 IN0 中
    trgm_output_t trgm_out_cfg_pla0in0;
    trgm_out_cfg_pla0in0.invert = false;
    trgm_out_cfg_pla0in0.type = trgm_output_same_as_input;
    trgm_out_cfg_pla0in0.input = HPM_TRGM0_INPUT_SRC_GPTMR0_OUT2;
    trgm_output_config(HPM_TRGM0, TRGM_TRGOCFG_PLA_IN0, &trgm_out_cfg_pla0in0);

    // PLA0OUT0 -> TRGM0 -> PB22
    HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_TRGM0_P_02;
    trgm_output_t trgm_output_cfg_pb22;
    trgm_output_cfg_pb22.invert = false;
    trgm_output_cfg_pb22.type = trgm_output_same_as_input;
    trgm_output_cfg_pb22.input = HPM_TRGM0_INPUT_SRC_PLA0_OUT0;
    trgm_output_config(HPM_TRGM0, TRGM_TRGOCFG_TRGM_OUT2, &trgm_output_cfg_pb22);
    trgm_enable_io_output(HPM_TRGM0, 1 << TRGM_TRGOCFG_TRGM_OUT2);

    // PLA0OUT1 -> TRGM0 -> PB30
    HPM_IOC->PAD[IOC_PAD_PB30].FUNC_CTL = IOC_PB30_FUNC_CTL_TRGM0_P_10;
    trgm_output_t trgm_output_cfg_pb30;
    trgm_output_cfg_pb30.invert = false;
    trgm_output_cfg_pb30.type = trgm_output_same_as_input;
    trgm_output_cfg_pb30.input = HPM_TRGM0_INPUT_SRC_PLA0_OUT1;
    trgm_output_config(HPM_TRGM0, TRGM_TRGOCFG_TRGM_OUT10, &trgm_output_cfg_pb30);
    trgm_enable_io_output(HPM_TRGM0, 1 << TRGM_TRGOCFG_TRGM_OUT10);

    // PLA0OUT2 -> TRGM0 -> PB31
    HPM_IOC->PAD[IOC_PAD_PB31].FUNC_CTL = IOC_PB31_FUNC_CTL_TRGM0_P_11;
    trgm_output_t trgm_output_cfg_pb31;
    trgm_output_cfg_pb31.invert = false;
    trgm_output_cfg_pb31.type = trgm_output_same_as_input;
    trgm_output_cfg_pb31.input = HPM_TRGM0_INPUT_SRC_PLA0_OUT2;
    trgm_output_config(HPM_TRGM0, TRGM_TRGOCFG_TRGM_OUT11, &trgm_output_cfg_pb31);
    trgm_enable_io_output(HPM_TRGM0, 1 << TRGM_TRGOCFG_TRGM_OUT11);

    // filter1 对所有通道开启同步
    pla_filter_cfg_t filter_1st_chn_cfg;
    filter_1st_chn_cfg.val = 0;
    filter_1st_chn_cfg.sync_edge_filter_disable = true;
    filter_1st_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for(int i=0;i<8;i++){
        pla_set_filter1_in(HPM_PLA0, i, &filter_1st_chn_cfg);
    }
    for(int i=0;i<8;i++){
        pla_set_filter1_out(HPM_PLA0, i, &filter_1st_chn_cfg);
    }

    set_pla0_channel0();
    set_pla0_channel1();
    set_pla0_channel2();

    //start pwm
    gptmr_start_counter(HPM_GPTMR0, 2);

    while(1)
    {

    }
    return 0;
}

void set_pla0_channel0(){
    pla_aoi_16to8_chn_cfg_t aoi_16to8_chn_cfg;
    pla_filter_cfg_t filter_2nd_chn_cfg;
    pla_aoi_8to7_chn_cfg_t aoi_8to7_cfg;
    pla_filter_cfg_t filter_3rd_chn_cfg;

    // 与门部分
    aoi_16to8_chn_cfg.chn = pla_chn_0;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_0; // pla0ch0 16to8 gate0 负责生成 T 触发器的 T 信号
    for(int i=0;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1; // 先将全部 MUX 设为输出逻辑 1
        aoi_16to8_chn_cfg.input.signal = i;
    }
    aoi_16to8_chn_cfg.input[9].op = pla_aoi_operation_and_1;
    aoi_16to8_chn_cfg.input[9].signal = 9;
    aoi_16to8_chn_cfg.input[10].op = pla_aoi_operation_and_1;
    aoi_16to8_chn_cfg.input[10].signal = 10;
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    aoi_16to8_chn_cfg.chn = pla_chn_0;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_1; // pla0ch0 16to8 gate1 负责将 PLA IN0 的 PWM 信号引入
    aoi_16to8_chn_cfg.input[0].op = pla_aoi_operation_and_1; // 引入 PWM 原信号
    aoi_16to8_chn_cfg.input[0].signal = 0;
    for(int i=1;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1;
        aoi_16to8_chn_cfg.input.signal = i;
    }
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    // FILTER2 同步
    filter_2nd_chn_cfg.val = 0;
    filter_2nd_chn_cfg.sync_edge_filter_disable = true;
    filter_2nd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = pla_filter2_chn0; i <= pla_filter2_chn7; i++) {
        pla_set_filter2(HPM_PLA0, pla_chn_0, i, &filter_2nd_chn_cfg);
    }

    // pla0ch0 8to7 gate0
    aoi_8to7_cfg.chn = pla_chn_0;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_0;   // pla0ch0 8to7 gate0 输出与 pla0ch0 16to8 gate0 一致的信号
    aoi_8to7_cfg.input[0].op = pla_aoi_operation_and_1;
    aoi_8to7_cfg.input[0].signal = 0;
    for(int i=1;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_0;
        aoi_8to7_cfg.input.signal = i;
    }
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // pla0ch0 8to7 gate1
    aoi_8to7_cfg.chn = pla_chn_0;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_1;   // pla0ch0 8to7 gate1 输出与 pla0ch0 16to8 gate1 一致的信号
    for(int i=0;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_0;
        aoi_8to7_cfg.input.signal = i;
    }
    aoi_8to7_cfg.input[1].op = pla_aoi_operation_and_1;
    aoi_8to7_cfg.input[1].signal = 1;
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // FILTER3 同步
    filter_3rd_chn_cfg.val = 0;
    filter_3rd_chn_cfg.sync_edge_filter_disable = true;
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = 0; i < 2; i++) {  // T 和时钟使用原信号输入
        pla_set_filter3(HPM_PLA0, pla_chn_0, i, &filter_3rd_chn_cfg);
    }
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for async reset
    pla_set_filter3(HPM_PLA0, pla_chn_0, 2, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for async set
    pla_set_filter3(HPM_PLA0, pla_chn_0, 3, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for enable
    pla_set_filter3(HPM_PLA0, pla_chn_0, 4, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for sync reset
    pla_set_filter3(HPM_PLA0, pla_chn_0, 5, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for sync set
    pla_set_filter3(HPM_PLA0, pla_chn_0, 6, &filter_3rd_chn_cfg);

    // pla0ch0 ff
    pla_ff_cfg_t pla_ff_cfg;
    pla_ff_cfg.val = 0;
    pla_ff_cfg.sel_cfg_ff_type = pla_ff_type_trigger_ff;
    pla_ff_cfg.sel_clk_source = 1;
    pla_set_ff(HPM_PLA0, pla_chn_0, &pla_ff_cfg);

    pla_channel_enable(HPM_PLA0, pla_chn_0);
}

void set_pla0_channel1(){
    pla_aoi_16to8_chn_cfg_t aoi_16to8_chn_cfg;
    pla_filter_cfg_t filter_2nd_chn_cfg;
    pla_aoi_8to7_chn_cfg_t aoi_8to7_cfg;
    pla_filter_cfg_t filter_3rd_chn_cfg;

    // 与门部分
    aoi_16to8_chn_cfg.chn = pla_chn_1;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_0; // pla0ch1 16to8 gate0 负责生成 T 触发器的 T 信号
    for(int i=0;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1; // 先将全部 MUX 设为输出逻辑 1
        aoi_16to8_chn_cfg.input.signal = i;
    }
    aoi_16to8_chn_cfg.input[10].op = pla_aoi_operation_and_1;
    aoi_16to8_chn_cfg.input[10].signal = 10;
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    aoi_16to8_chn_cfg.chn = pla_chn_1;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_1; // pla0ch1 16to8 gate1 负责将 PLA IN0 的 PWM 信号引入
    aoi_16to8_chn_cfg.input[0].op = pla_aoi_operation_and_1; // 引入 PWM 原信号
    aoi_16to8_chn_cfg.input[0].signal = 0;
    for(int i=1;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1;
        aoi_16to8_chn_cfg.input.signal = i;
    }
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    // FILTER2 同步
    filter_2nd_chn_cfg.val = 0;
    filter_2nd_chn_cfg.sync_edge_filter_disable = true;
    filter_2nd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = pla_filter2_chn0; i <= pla_filter2_chn7; i++) {
        pla_set_filter2(HPM_PLA0, pla_chn_1, i, &filter_2nd_chn_cfg);
    }

    // pla0ch1 8to7 gate0
    aoi_8to7_cfg.chn = pla_chn_1;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_0;   // pla0ch1 8to7 gate0 输出与 pla0ch1 16to8 gate0 一致的信号
    aoi_8to7_cfg.input[0].op = pla_aoi_operation_and_1;
    aoi_8to7_cfg.input[0].signal = 0;
    for(int i=1;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_0;
        aoi_8to7_cfg.input.signal = i;
    }
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // pla0ch0 8to7 gate1
    aoi_8to7_cfg.chn = pla_chn_1;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_1;   // pla0ch1 8to7 gate1 输出与 pla0ch1 16to8 gate1 一致的信号
    for(int i=0;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_0;
        aoi_8to7_cfg.input.signal = i;
    }
    aoi_8to7_cfg.input[1].op = pla_aoi_operation_and_1;
    aoi_8to7_cfg.input[1].signal = 1;
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // FILTER3 同步
    filter_3rd_chn_cfg.val = 0;
    filter_3rd_chn_cfg.sync_edge_filter_disable = true;
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = 0; i < 2; i++) {  // T 和时钟使用原信号输入
        pla_set_filter3(HPM_PLA0, pla_chn_1, i, &filter_3rd_chn_cfg);
    }
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for async reset
    pla_set_filter3(HPM_PLA0, pla_chn_1, 2, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for async set
    pla_set_filter3(HPM_PLA0, pla_chn_1, 3, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for enable
    pla_set_filter3(HPM_PLA0, pla_chn_1, 4, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for sync reset
    pla_set_filter3(HPM_PLA0, pla_chn_1, 5, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for sync set
    pla_set_filter3(HPM_PLA0, pla_chn_1, 6, &filter_3rd_chn_cfg);

    // pla0ch0 ff
    pla_ff_cfg_t pla_ff_cfg;
    pla_ff_cfg.val = 0;
    pla_ff_cfg.sel_cfg_ff_type = pla_ff_type_trigger_ff;
    pla_ff_cfg.sel_clk_source = 1;
    pla_set_ff(HPM_PLA0, pla_chn_1, &pla_ff_cfg);

    pla_channel_enable(HPM_PLA0, pla_chn_1);
}

void set_pla0_channel2(){  // Channel 0
    pla_aoi_16to8_chn_cfg_t aoi_16to8_chn_cfg;
    pla_filter_cfg_t filter_2nd_chn_cfg;
    pla_aoi_8to7_chn_cfg_t aoi_8to7_cfg;
    pla_filter_cfg_t filter_3rd_chn_cfg;

    // 与门部分
    aoi_16to8_chn_cfg.chn = pla_chn_2;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_0;
    for(int i=0;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1;
        aoi_16to8_chn_cfg.input.signal = i;
    }
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    aoi_16to8_chn_cfg.chn = pla_chn_2;
    aoi_16to8_chn_cfg.aoi_16to8_chn = pla_aoi_16to8_chn_1; // pla0ch2 16to8 gate1 负责将 PLA IN0 的 PWM 信号引入
    aoi_16to8_chn_cfg.input[0].op = pla_aoi_operation_and_1;
    aoi_16to8_chn_cfg.input[0].signal = 0;
    for(int i=1;i<16;i++){
        aoi_16to8_chn_cfg.input.op = pla_aoi_operation_or_1;
        aoi_16to8_chn_cfg.input.signal = i;
    }
    pla_set_aoi_16to8_one_channel(HPM_PLA0, &aoi_16to8_chn_cfg);

    // FILTER2 同步
    filter_2nd_chn_cfg.val = 0;
    filter_2nd_chn_cfg.sync_edge_filter_disable = true;
    filter_2nd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = pla_filter2_chn0; i <= pla_filter2_chn7; i++) {
        pla_set_filter2(HPM_PLA0, pla_chn_2, i, &filter_2nd_chn_cfg);
    }

    // pla0ch1 8to7 gate0
    aoi_8to7_cfg.chn = pla_chn_2;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_0;
    for(int i=0;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_1;
        aoi_8to7_cfg.input.signal = i;
    }
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // pla0ch0 8to7 gate1
    aoi_8to7_cfg.chn = pla_chn_2;
    aoi_8to7_cfg.aoi_8to7_chn = pla_aoi_8to7_chn_1;
    for(int i=0;i<8;i++){
        aoi_8to7_cfg.input.op = pla_aoi_operation_and_0;
        aoi_8to7_cfg.input.signal = i;
    }
    aoi_8to7_cfg.input[1].op = pla_aoi_operation_and_1;
    aoi_8to7_cfg.input[1].signal = 1;
    pla_set_aoi_8to7_one_channel(HPM_PLA0,&aoi_8to7_cfg);

    // FILTER3 同步
    filter_3rd_chn_cfg.val = 0;
    filter_3rd_chn_cfg.sync_edge_filter_disable = true;
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_disable;
    for (uint16_t i = 0; i < 2; i++) {  // T 和时钟使用原信号输入
        pla_set_filter3(HPM_PLA0, pla_chn_2, i, &filter_3rd_chn_cfg);
    }
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for async reset
    pla_set_filter3(HPM_PLA0, pla_chn_2, 2, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for sync set
    pla_set_filter3(HPM_PLA0, pla_chn_2, 3, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for enable
    pla_set_filter3(HPM_PLA0, pla_chn_2, 4, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_height; // for sync reset
    pla_set_filter3(HPM_PLA0, pla_chn_2, 5, &filter_3rd_chn_cfg);
    filter_3rd_chn_cfg.software_inject = pla_filter_sw_inject_low; // for sync set
    pla_set_filter3(HPM_PLA0, pla_chn_2, 6, &filter_3rd_chn_cfg);

    // pla0ch2 ff
    pla_ff_cfg_t pla_ff_cfg;
    pla_ff_cfg.val = 0;
    pla_ff_cfg.sel_cfg_ff_type = pla_ff_type_trigger_ff;
    pla_ff_cfg.sel_clk_source = 1;
    pla_set_ff(HPM_PLA0, pla_chn_2, &pla_ff_cfg);

    pla_channel_enable(HPM_PLA0, pla_chn_2);
}

更多回帖

×
20
完善资料,
赚取积分