一个简单的 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);
}
|