HPM6000:DMA方式推GPIO

HPM6000是先楫半导体的高性能MCU。本文章主要讲HPM6000 MCU如何通过DMA的方式推GPIO,实现任意的输出波形。该方法通过硬件方式来实现波形的设置,不会占用CPU处理时间。

/*
 * Copyright (c) 2021 HPMicro
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include "board.h"
#include <stdio.h>
#include "hpm_debug_console.h"
#include "hpm_sysctl_drv.h"
#include "hpm_pwm_drv.h"
#include "hpm_trgm_drv.h"
#include "hpm_clock_drv.h"
#include "hpm_synt_drv.h"
#include "hpm_gpio_drv.h"
#include "hpm_gptmr_drv.h"
#include "hpm_dma_drv.h"
#include "hpm_dmamux_drv.h"

#define zh_led_PWM_FREQ 36 //160M/8.89M

ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(8) uint32_t g_u32LedBufForGpio32[4096] = {0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0};


void isr_dma(void)
{
    uint32_t stat;

    stat = dma_check_transfer_status(HPM_HDMA, 0);

    if (0 != (stat & DMA_CHANNEL_STATUS_TC)) {
      printf("Transfer done!");
    }
}
SDK_DECLARE_EXT_ISR_M(BOARD_APP_HDMA_IRQ, isr_dma)


/***
static void zh_led_gpio_config(void)
{
    uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);

    HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_PWM0_P_1;
    // HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_GPIO_C_01;
    // HPM_IOC->PAD[IOC_PAD_PC01].PAD_CTL = pad_ctl;
    
    
    HPM_IOC->PAD[IOC_PAD_PB00].FUNC_CTL = IOC_PB00_FUNC_CTL_GPIO_B_00;
    HPM_IOC->PAD[IOC_PAD_PB00].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB01].FUNC_CTL = IOC_PB01_FUNC_CTL_GPIO_B_01;
    HPM_IOC->PAD[IOC_PAD_PB01].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_GPIO_B_02;
    HPM_IOC->PAD[IOC_PAD_PB02].PAD_CTL = pad_ctl;
    
    HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_GPIO_B_03;
    HPM_IOC->PAD[IOC_PAD_PB03].PAD_CTL = pad_ctl;
    
    HPM_IOC->PAD[IOC_PAD_PB04].FUNC_CTL = IOC_PB04_FUNC_CTL_GPIO_B_04;
    HPM_IOC->PAD[IOC_PAD_PB04].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_GPIO_B_05;
    HPM_IOC->PAD[IOC_PAD_PB05].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_GPIO_B_06;
    HPM_IOC->PAD[IOC_PAD_PB06].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_GPIO_B_07;
    HPM_IOC->PAD[IOC_PAD_PB07].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB08].FUNC_CTL = IOC_PB08_FUNC_CTL_GPIO_B_08;
    HPM_IOC->PAD[IOC_PAD_PB08].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB09].FUNC_CTL = IOC_PB09_FUNC_CTL_GPIO_B_09;
    HPM_IOC->PAD[IOC_PAD_PB09].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB10].FUNC_CTL = IOC_PB10_FUNC_CTL_GPIO_B_10;
    HPM_IOC->PAD[IOC_PAD_PB10].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_GPIO_B_11;
    HPM_IOC->PAD[IOC_PAD_PB11].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12;
    HPM_IOC->PAD[IOC_PAD_PB12].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_GPIO_B_13;
    HPM_IOC->PAD[IOC_PAD_PB13].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB14].FUNC_CTL = IOC_PB14_FUNC_CTL_GPIO_B_14;
    HPM_IOC->PAD[IOC_PAD_PB14].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB15].FUNC_CTL = IOC_PB15_FUNC_CTL_GPIO_B_15;
    HPM_IOC->PAD[IOC_PAD_PB15].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB16].FUNC_CTL = IOC_PB16_FUNC_CTL_GPIO_B_16;
    HPM_IOC->PAD[IOC_PAD_PB16].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB17].FUNC_CTL = IOC_PB17_FUNC_CTL_GPIO_B_17;
    HPM_IOC->PAD[IOC_PAD_PB17].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_GPIO_B_18;
    HPM_IOC->PAD[IOC_PAD_PB18].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_GPIO_B_19;
    HPM_IOC->PAD[IOC_PAD_PB19].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB20].FUNC_CTL = IOC_PB20_FUNC_CTL_GPIO_B_20;
    HPM_IOC->PAD[IOC_PAD_PB20].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_GPIO_B_21;
    HPM_IOC->PAD[IOC_PAD_PB21].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_GPIO_B_22;
    HPM_IOC->PAD[IOC_PAD_PB22].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_GPIO_B_23;
    HPM_IOC->PAD[IOC_PAD_PB23].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_GPIO_B_24;
    HPM_IOC->PAD[IOC_PAD_PB24].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_GPIO_B_25;
    HPM_IOC->PAD[IOC_PAD_PB25].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB26].FUNC_CTL = IOC_PB26_FUNC_CTL_GPIO_B_26;
    HPM_IOC->PAD[IOC_PAD_PB26].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB27].FUNC_CTL = IOC_PB27_FUNC_CTL_GPIO_B_27;
    HPM_IOC->PAD[IOC_PAD_PB27].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB28].FUNC_CTL = IOC_PB28_FUNC_CTL_GPIO_B_28;
    HPM_IOC->PAD[IOC_PAD_PB28].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB29].FUNC_CTL = IOC_PB29_FUNC_CTL_GPIO_B_29;
    HPM_IOC->PAD[IOC_PAD_PB29].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB30].FUNC_CTL = IOC_PB30_FUNC_CTL_GPIO_B_30;
    HPM_IOC->PAD[IOC_PAD_PB30].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PB31].FUNC_CTL = IOC_PB31_FUNC_CTL_GPIO_B_31;
    HPM_IOC->PAD[IOC_PAD_PB31].PAD_CTL = pad_ctl;

    for(int i=0; i<32; i++) {
        gpio_set_pin_output(HPM_GPIO0, GPIO_DO_GPIOB, i);
        gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOB, i, 0);
    }

    for(int i=0; i<32; i++) {
        gpio_set_pin_output(HPM_GPIO0, GPIO_DO_GPIOB, i);
        gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOB, i, 0);
    }

}
***/

static void zh_led_gpio_config(void)
{
    uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);

    HPM_IOC->PAD[IOC_PAD_PC00].FUNC_CTL = IOC_PC00_FUNC_CTL_GPIO_C_00;
    HPM_IOC->PAD[IOC_PAD_PC00].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_GPIO_C_01;
    HPM_IOC->PAD[IOC_PAD_PC01].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC02].FUNC_CTL = IOC_PC02_FUNC_CTL_GPIO_C_02;
    HPM_IOC->PAD[IOC_PAD_PC02].PAD_CTL = pad_ctl;
    
    HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PC03_FUNC_CTL_GPIO_C_03;
    HPM_IOC->PAD[IOC_PAD_PC03].PAD_CTL = pad_ctl;
    
    HPM_IOC->PAD[IOC_PAD_PC04].FUNC_CTL = IOC_PC04_FUNC_CTL_GPIO_C_04;
    HPM_IOC->PAD[IOC_PAD_PC04].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC05].FUNC_CTL = IOC_PC05_FUNC_CTL_GPIO_C_05;
    HPM_IOC->PAD[IOC_PAD_PC05].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_GPIO_C_06;
    HPM_IOC->PAD[IOC_PAD_PC06].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC07].FUNC_CTL = IOC_PC07_FUNC_CTL_GPIO_C_07;
    HPM_IOC->PAD[IOC_PAD_PC07].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_GPIO_C_08;
    HPM_IOC->PAD[IOC_PAD_PC08].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC09].FUNC_CTL = IOC_PC09_FUNC_CTL_GPIO_C_09;
    HPM_IOC->PAD[IOC_PAD_PC09].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC10].FUNC_CTL = IOC_PC10_FUNC_CTL_GPIO_C_10;
    HPM_IOC->PAD[IOC_PAD_PC10].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC11].FUNC_CTL = IOC_PC11_FUNC_CTL_GPIO_C_11;
    HPM_IOC->PAD[IOC_PAD_PC11].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC12].FUNC_CTL = IOC_PC12_FUNC_CTL_GPIO_C_12;
    HPM_IOC->PAD[IOC_PAD_PC12].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_GPIO_C_13;
    HPM_IOC->PAD[IOC_PAD_PC13].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_GPIO_C_14;
    HPM_IOC->PAD[IOC_PAD_PC14].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC15].FUNC_CTL = IOC_PC15_FUNC_CTL_GPIO_C_15;
    HPM_IOC->PAD[IOC_PAD_PC15].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC16].FUNC_CTL = IOC_PC16_FUNC_CTL_GPIO_C_16;
    HPM_IOC->PAD[IOC_PAD_PC16].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC17].FUNC_CTL = IOC_PC17_FUNC_CTL_GPIO_C_17;
    HPM_IOC->PAD[IOC_PAD_PC17].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_GPIO_C_18;
    HPM_IOC->PAD[IOC_PAD_PC18].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_GPIO_C_19;
    HPM_IOC->PAD[IOC_PAD_PC19].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_GPIO_C_20;
    HPM_IOC->PAD[IOC_PAD_PC20].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_GPIO_C_21;
    HPM_IOC->PAD[IOC_PAD_PC21].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_GPIO_C_22;
    HPM_IOC->PAD[IOC_PAD_PC22].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_GPIO_C_23;
    HPM_IOC->PAD[IOC_PAD_PC23].PAD_CTL = pad_ctl;

    HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_GPIO_C_24;
    HPM_IOC->PAD[IOC_PAD_PC24].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_GPIO_C_25;
    //HPM_IOC->PAD[IOC_PAD_PC25].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_GPIO_C_26;
    //HPM_IOC->PAD[IOC_PAD_PC26].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_GPIO_C_27;
    //HPM_IOC->PAD[IOC_PAD_PC27].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_GPIO_C_28;
    //HPM_IOC->PAD[IOC_PAD_PC28].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_GPIO_C_29;
    //HPM_IOC->PAD[IOC_PAD_PC29].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC30].FUNC_CTL = IOC_PC30_FUNC_CTL_GPIO_C_30;
    //HPM_IOC->PAD[IOC_PAD_PC30].PAD_CTL = pad_ctl;

    //HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_GPIO_C_31;
    //HPM_IOC->PAD[IOC_PAD_PC31].PAD_CTL = pad_ctl;

    for(int i=0; i<24; i++) {
        gpio_set_pin_output(HPM_GPIO0, GPIO_DO_GPIOC, i);
        gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOC, i, 0);
    }

    for(int i=0; i<24; i++) {
        gpio_set_pin_output(HPM_GPIO0, GPIO_DO_GPIOC, i);
        gpio_write_pin(HPM_GPIO0, GPIO_DO_GPIOC, i, 0);
    }

}

static void zh_led_dma_config(void)
{
    dma_channel_config_t ch_config = { 0 };
    unsigned int i = 0;

    for(i = 0;i<4096;i++)
    {
      g_u32LedBufForGpio32[i] = (i&1)?(~0):(0);
      //g_u32LedBufForGpio32[i] = ~0;
      //if(i%5 == 0)
      //{
      //  g_u32LedBufForGpio32[i] = ~0;
      //}
      //else
      //{
      //  g_u32LedBufForGpio32[i] = 0;
      //}
    }

    dma_reset(HPM_HDMA);

    intc_m_enable_irq_with_priority(BOARD_APP_HDMA_IRQ, 1);

    dma_default_channel_config(HPM_HDMA, &ch_config);

    ch_config.src_addr = (uint32_t)&g_u32LedBufForGpio32[0];

    ch_config.dst_addr = (uint32_t)&HPM_GPIO0->DO[GPIO_DO_GPIOC].VALUE;
    ch_config.src_width = DMA_TRANSFER_WIDTH_WORD;                                                             // 32位
    ch_config.dst_width = DMA_TRANSFER_WIDTH_WORD;                                                             // 32位
    ch_config.src_addr_ctrl = DMA_ADDRESS_CONTROL_INCREMENT;
    ch_config.dst_addr_ctrl = DMA_ADDRESS_CONTROL_FIXED;
    ch_config.size_in_byte = sizeof(g_u32LedBufForGpio32); //32 * sizeof(uint32_t); 
    ch_config.dst_mode = DMA_HANDSHAKE_MODE_NORMAL;
    ch_config.src_burst_size = 0;

    if (status_success != dma_setup_channel(HPM_HDMA, 0, &ch_config, false))
    {
        printf(" dma setup channel failed\n");
        return;
    }

    dmamux_config(HPM_DMAMUX, DMAMUX_MUXCFG_HDMA_MUX0, HPM_DMA_SRC_MOT0_0, false);

    trgm_dma_request_config(HPM_TRGM0, 0, 18);

    pwm_enable_dma_request(HPM_PWM0, PWM_IRQ_CMP(18));

    synt_enable_counter(HPM_SYNT, true);
    pwm_start_counter(HPM_PWM0);
    dmamux_enable_channel(HPM_DMAMUX, DMAMUX_MUXCFG_HDMA_MUX0);
    dma_enable_channel(HPM_HDMA, 0);

}

/**
 * u8Phase from 1~18, 其中设置1 == 设置18, 设置1时 上升沿的边与数据的开始时刻对齐,随着设置的数字增大,上升沿的边向右移动,设置8时,上升沿的边大约在中间。
 *  */
static int zh_led_clk_config(uint8_t u8Phase)
{
    pwm_cmp_config_t cmp_config_ch0[4] = {0};
    pwm_config_t pwm_config = {0};
    uint32_t u32CmpValue[4];

    switch (u8Phase)
    {
        case 1:
            u32CmpValue[0] = 6;
            u32CmpValue[1] = 16;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 2:
            u32CmpValue[0] = 7;
            u32CmpValue[1] = 18;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 3:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 0;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 8;
            break;
        case 4:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 1;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 9;
            break;
        case 5:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 2;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 10;
            break;
        case 6:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 3;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 11;
            break;
        case 7:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 4;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 12;
            break;
        case 8:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 5;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 13;
            break;
        case 9:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 6;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 14;
            break;
        case 10:
            u32CmpValue[0] = 18;
            u32CmpValue[1] = 7;
            u32CmpValue[2] = 17;
            u32CmpValue[3] = 15;
            break;
        case 11:
            u32CmpValue[0] = 18;
            u32CmpValue[1] = 8;
            u32CmpValue[2] = 17;
            u32CmpValue[3] = 16;
            break;
        case 12:
            u32CmpValue[0] = 17;
            u32CmpValue[1] = 9;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 13:
            u32CmpValue[0] = 0;
            u32CmpValue[1] = 10;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 14:
            u32CmpValue[0] = 1;
            u32CmpValue[1] = 11;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 15:
            u32CmpValue[0] = 2;
            u32CmpValue[1] = 12;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 16:
            u32CmpValue[0] = 3;
            u32CmpValue[1] = 13;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 17:
            u32CmpValue[0] = 4;
            u32CmpValue[1] = 14;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
        case 18:
            u32CmpValue[0] = 5;
            u32CmpValue[1] = 15;
            u32CmpValue[2] = 18;
            u32CmpValue[3] = 18;
            break;
            break;
        default:
            break;
    }

    pwm_stop_counter(HPM_PWM0);
    pwm_set_reload(HPM_PWM0, 0, zh_led_PWM_FREQ-1);
    pwm_set_start_count(HPM_PWM0, 0, 0);

    pwm_config.enable_output = true;
    pwm_config.invert_output = false;
    pwm_config.update_trigger = pwm_shadow_register_update_on_modify;
    pwm_config.fault_mode = pwm_fault_mode_force_output_highz;
    pwm_config.fault_recovery_trigger = pwm_fault_recovery_on_fault_clear;
    pwm_config.force_source = pwm_force_source_software;
    pwm_config.dead_zone_in_half_cycle = 0;

    /*cmp0 cmp1 cmp2 cmp3 for pwm ch0*/
    cmp_config_ch0[0].cmp = u32CmpValue[0];
    cmp_config_ch0[0].enable_ex_cmp = false;
    cmp_config_ch0[0].mode = pwm_cmp_mode_output_compare;
    cmp_config_ch0[0].update_trigger = pwm_shadow_register_update_on_hw_event;
    cmp_config_ch0[0].ex_cmp = 0;    
    cmp_config_ch0[0].half_clock_cmp = 0;
    cmp_config_ch0[0].jitter_cmp = 0;   

    cmp_config_ch0[1].cmp = u32CmpValue[1];
    cmp_config_ch0[1].enable_ex_cmp = false;
    cmp_config_ch0[1].mode = pwm_cmp_mode_output_compare;
    cmp_config_ch0[1].update_trigger = pwm_shadow_register_update_on_hw_event;
    cmp_config_ch0[1].ex_cmp = 0;    
    cmp_config_ch0[1].half_clock_cmp = 0;
    cmp_config_ch0[1].jitter_cmp = 0;  

    cmp_config_ch0[2].cmp = u32CmpValue[2];
    cmp_config_ch0[2].enable_ex_cmp = false;
    cmp_config_ch0[2].mode = pwm_cmp_mode_output_compare;
    cmp_config_ch0[2].update_trigger = pwm_shadow_register_update_on_hw_event;
    cmp_config_ch0[2].ex_cmp = 0;    
    cmp_config_ch0[2].half_clock_cmp = 0;
    cmp_config_ch0[2].jitter_cmp = 0;  

    cmp_config_ch0[3].cmp = u32CmpValue[3];
    cmp_config_ch0[3].enable_ex_cmp = false;
    cmp_config_ch0[3].mode = pwm_cmp_mode_output_compare;
    cmp_config_ch0[3].update_trigger = pwm_shadow_register_update_on_hw_event;
    cmp_config_ch0[3].ex_cmp = 0;    
    cmp_config_ch0[3].half_clock_cmp = 0;
    cmp_config_ch0[3].jitter_cmp = 0;  
    if (status_success != pwm_setup_waveform(HPM_PWM0, 1, &pwm_config, 0, cmp_config_ch0, 4)) {
        printf("failed to setup waveform for ch0\n");
        return status_fail;
    }

    cmp_config_ch0[0].cmp = zh_led_PWM_FREQ-1;
    cmp_config_ch0[0].update_trigger = pwm_shadow_register_update_on_modify;
    pwm_load_cmp_shadow_on_match(HPM_PWM0, 4, &cmp_config_ch0[0]);

    pwm_issue_shadow_register_lock_event(HPM_PWM0);

    /* enable pwm fault protect */
    pwm_fault_source_config_t config;
    //config.external_fault_active_low = false;
    config.source_mask = PWM_GCR_FAULTI0EN_MASK;
    config.fault_recover_at_rising_edge = false;
    config.fault_output_recovery_trigger = 0;
    pwm_config_fault_source(HPM_PWM0, &config);


    return status_success;
}

static void zh_led_trgm_config(void)
{
    trgm_output_t stTrgmOutput;

    stTrgmOutput.invert = false;
    stTrgmOutput.type = trgm_output_same_as_input;
    
    stTrgmOutput.input = 44;
    trgm_output_config(HPM_TRGM0, 14, &stTrgmOutput);
    
    pwm_enable_reload_at_synci(HPM_PWM0);

    synt_reset_counter(HPM_SYNT);
    synt_set_reload(HPM_SYNT, zh_led_PWM_FREQ-1);
    synt_set_comparator(HPM_SYNT, 0, zh_led_PWM_FREQ-1);
}

extern int zh_led_main(void);
int main(void)
{
    unsigned int i=0,j=3;
    board_init();
    zh_led_gpio_config();
    zh_led_clk_config(2);
    zh_led_trgm_config();
    zh_led_dma_config();

    printf("start\n");

    while(j--)
    {
      printf("j = %d\n", j);
        //i = 10000;
        // while(i--);
      /* config trgm */
      //trgm_output_update_source(HPM_TRGM0, TRGM_TRGOCFG_PWM_FAULTI0, HPM_TRGM0_INPUT_SRC_VDD);//暂停PWM
              // i = 10000;
        // while(i--)
         //{
         //HPM_GPIO0->DO[GPIO_DO_GPIOB].VALUE =~0;
        // HPM_GPIO0->DO[GPIO_DO_GPIOB].VALUE =0;
         //};
      //dma_reset(HPM_HDMA);
      zh_led_dma_config();
      //trgm_output_update_source(HPM_TRGM0, TRGM_TRGOCFG_PWM_FAULTI0, HPM_TRGM0_INPUT_SRC_VSS);//重启PWM
      //pwm_clear_fault(HPM_PWM0);
      pwm_start_counter(HPM_PWM0);
    };

    printf("stop\n");

    while(1);
     //zh_led_main();
    return 0;
}

开启DMA传输完成中断:

intc_m_enable_irq_with_priority(BOARD_APP_HDMA_IRQ, 1);

配置DMA传输完成回调函数:

void isr_dma(void)
{
    uint32_t stat;

    stat = dma_check_transfer_status(HPM_HDMA, 0);

    if (0 != (stat & DMA_CHANNEL_STATUS_TC)) {
      printf("Transfer done!");
    }
}
SDK_DECLARE_EXT_ISR_M(BOARD_APP_HDMA_IRQ, isr_dma)

测试结果:

测量GPIO的波形:

 

因为HDMA访问AHB SRAM速度更快,可以将数据存储到AHB SRAM来提高刷新速度。

__attribute__ ((section(".ahb_sram"))) uint32_t g_u32LedBufForGpio32[1024]={0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0};

用示波器测量波形如下图所示:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenSun-1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值