Exemplo n.º 1
0
//======================================================================
//函数名称:DMA_Disable()
//函数功能:关闭1个DMA模块
//输    入:DMA_Struct_TypeDef      *DMA_Struct         DMA结构体地址
//输    出:无
//返    回: 0          :       成功
//          -1          :       失败
//======================================================================
int DMA_Disable(DMA_Struct_TypeDef *DMA_Struct)
{
    const DMAMUX_x_TypeDef DMAMUX_x = DMAMUX_x_GET((*DMA_Struct).DMAMUX_Source);

    switch ((*DMA_Struct).DMA_CHn)
    {
    case DMA_CH0:
        disable_irq(DMA_CH0_IRQn);
        break;
    case DMA_CH1:
        disable_irq(DMA_CH1_IRQn);
        break;
    case DMA_CH2:
        disable_irq(DMA_CH2_IRQn);
        break;
    case DMA_CH3:
        disable_irq(DMA_CH3_IRQn);
        break;
    default:
        return (-1);
    }

    DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DSR_BCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DSR_BCR_BCR_MASK;

    return (0);
}
Exemplo n.º 2
0
/*!
 *  @brief      DMA初始化,读取端口数据到内存
 *  @param      DMA_CHn         通道号(DMA_CH0 ~ DMA_CH15)
 *  @param      SADDR           源地址( (void * )&PTx_Bn_IN 或 (void * )&PTx_Wn_IN   )
 *  @param      DADDR           目的地址
 *  @param      PTxn            触发端口
 *  @param      DMA_BYTEn       每次DMA传输字节数
 *  @param      count           一个主循环传输字节数
 *  @param      cfg             DMA传输配置,从DMA_cfg里选择
 *  @since      v5.0
 *  @note       DMA PTXn触发源默认上升沿触发传输,若需修改,则初始化后调用 port_init 配置DMA 触发方式
                初始化后,需要调用 DMA_EN 来实现
 *  Sample usage:   uint8 buff[10];
                    dma_portx2buff_init(DMA_CH0, PTB_B0_IN, buff, PTA7, DMA_BYTE1, 10, DADDR_RECOVER);
                    //DMA初始化,源地址:PTB_B0_IN,目的地址:buff,PTA7触发(默认上升沿),每次传输1字节,共传输 10次 ,传输结束后恢复地址

                    port_init(PTA7,ALT1 | DMA_FALLING);             //默认触发源是上升沿,此处改为 下降沿触发

                    DMA_EN(DMA_CH0);                //需要使能 DMA 后才能传输数据
 */
void dma_portx2buff_init(DMA_CHn CHn, void *SADDR, void *DADDR, PTXn_e ptxn, DMA_BYTEn byten, uint32 count)
{
    uint8 BYTEs = (byten == DMA_BYTE1 ? 1 : (byten == DMA_BYTE2 ? 2 : (byten == DMA_BYTE4 ? 4 : 0 ) ) ); //计算传输字节数    uint8 ptx0;

    //断言,检测传递进来参数是否正确
    ASSERT(                                             //用断言检测 源地址和每次传输字节数是否正确
        (   (byten == DMA_BYTE1)                    //传输一个字节
            && ( (SADDR >= &PTA_B0_IN) && (SADDR <= ( &PTE_B3_IN )))
        )

        || (   (byten == DMA_BYTE2)                   //传输两个字节(注意,不能跨端口)
               && ( (SADDR >= &PTA_B0_IN)
                    && (SADDR <= ( &PTE_W1_IN ))
                    && (((uint32)SADDR & 0x03) != 0x03) )         //保证不跨端口
           )

        || (   (byten == DMA_BYTE4)                   //传输四个字节
               && ((SADDR >= &PTA_B0_IN) && (SADDR <= ( &PTE_B0_IN )))
               && (((uint32)SADDR & 0x03) == 0x00)           //保证不跨端口
           )
    );

    ASSERT(count < 0x8000); //断言,最大只支持0x7FFF

    //DMA 寄存器 配置

    /* 开启时钟 */
    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;                        //打开DMA模块时钟

#if (defined(MK60DZ10)|| defined(MKL26Z4))
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;                     //打开DMA多路复用器时钟
#elif defined(MK60F15)
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX0_MASK;                    //打开DMA多路复用器时钟
#endif

    DMAMUX0_CHCFG(CHn)=0x00;
    DMA_DSR_BCR(CHn)|=DMA_DSR_BCR_DONE_MASK;

    /* 配置 DMA 通道 的 传输控制块 TCD ( Transfer Control Descriptor ) */
    DMA_SAR(CHn) =    (uint32)SADDR;                      // 设置  源地址
    DMA_DAR(CHn) =    (uint32)DADDR;                      // 设置目的地址
    DMA_DCR(CHn) =    (0
                       | DMA_DCR_SSIZE(byten)
                       | DMA_DCR_DSIZE(byten)
                       //| DMA_DCR_SINC_MASK                  //传输后源地址增加(根据位宽)
                       | DMA_DCR_DINC_MASK                  //传输后目的地址增加(根据位宽)
                       | DMA_DCR_CS_MASK                  // 0为不停得传输,直到BCR为0;1为一次请求传输一次
                       //| DMA_DCR_START_MASK               //软件触发传输
                       | DMA_DCR_ERQ_MASK                   //硬件触发传输(与上面START二选一)
                       | DMA_DCR_D_REQ_MASK                 //传输完成后硬件自动清ERQ

                       );
    DMA_DSR_BCR(CHn) =   (0
                     | DMA_DSR_BCR_BCR(count)              //传输数目
                     );


    /* 配置 DMA 触发源 */
#if defined(MK60DZ10)
    DMAMUX_CHCFG_REG(DMAMUX_BASE_PTR, CHn) = (0
#elif (defined(MK60F15) || defined(MKL26Z4))
    DMAMUX_CHCFG_REG(DMAMUX0_BASE_PTR, CHn) = (0
#endif
            | DMAMUX_CHCFG_ENBL_MASK                        /* Enable routing of DMA request */
            //| DMAMUX_CHCFG_TRIG_MASK                        /* Trigger Mode: Periodic   PIT周期触发传输模式   通道1对应PIT1,必须使能PIT1,且配置相应的PIT定时触发 */
            | DMAMUX_CHCFG_SOURCE( PTX(ptxn) + DMA_PORTA) /* 通道触发传输源:     */
                                             );

    //配置触发源(默认是 上升沿触发)
    port_init(ptxn, ALT1 | DMA_RISING);

    /*  配置输入源   */
    dma_gpio_input_init(SADDR,BYTEs);

    DMA_DIS(CHn);                                    //使能通道CHn 硬件请求
    //DMA_IRQ_CLEAN(CHn);

    /* 开启中断 */
    //DMA_EN(CHn);                                    //使能通道CHn 硬件请求
    //DMA_IRQ_EN(CHn);                                //允许DMA通道传输
}
Exemplo n.º 3
0
//======================================================================
//函数名称:DMA_Init()
//函数功能:初始化1个DMA模块
//输    入:DMA_Struct_TypeDef      *DMA_Struct         需要初始化的DMA结构体地址
//输    出:无
//返    回: 0          :       成功
//          -1          :       失败
//          -2          :       传输字节数超出范围(<0x0FFFFF)
//======================================================================
int DMA_Init(DMA_Struct_TypeDef *DMA_Struct)
{
    if ((*DMA_Struct).DMA_BytesCount > 0x0FFFFF)
        return (-2);

    const DMAMUX_x_TypeDef DMAMUX_x = DMAMUX_x_GET((*DMA_Struct).DMAMUX_Source);

    switch (DMAMUX_x)
    {
    case DMAMUX0:
        SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
        break;
    default:
        return (-1);
    }

    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;

    DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DMOD_MASK;

    const DMAMUX_SRC_TypeDef DMAMUX_SRC = DMAMUX_SRC_GET((*DMA_Struct).DMAMUX_Source);

    if (DMAMUX_SRC == DMA_SoftTrig)
    {
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_ERQ_MASK;
    }
    else
    {
        DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) |= DMAMUX_CHCFG_SOURCE(DMAMUX_SRC);

        if ((*DMA_Struct).DMAMUX_Trig == DMA_Periodic)
            DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) |= DMAMUX_CHCFG_TRIG_MASK;
        else
            DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) &= ~DMAMUX_CHCFG_TRIG_MASK;
    }

    //Source
    DMA_SAR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) =
        DMA_SAR_SAR((*DMA_Struct).DMA_Source.DMA_Addr);

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SSIZE_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SSIZE((*DMA_Struct).DMA_Source.Data_Size);

    if ((*DMA_Struct).DMA_Source.Addr_INC == DMA_ADDR_INC)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SINC_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SINC_MASK;

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SMOD_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SMOD((*DMA_Struct).DMA_Source.Addr_MOD);

    //Destination
    DMA_DAR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) =
        DMA_SAR_SAR((*DMA_Struct).DMA_Destination.DMA_Addr);

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DSIZE_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DSIZE((*DMA_Struct).DMA_Destination.Data_Size);

    if ((*DMA_Struct).DMA_Destination.Addr_INC == DMA_ADDR_INC)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DINC_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DINC_MASK;

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DMOD((*DMA_Struct).DMA_Destination.Addr_MOD);

    DMA_DSR_BCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DSR_BCR_BCR_MASK;
    DMA_DSR_BCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DSR_BCR_BCR((*DMA_Struct).DMA_BytesCount);

    if ((*DMA_Struct).DMA_CycleSteal == DMA_CycleSteal)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_CS_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_CS_MASK;

    if (DMAMUX_SRC == DMA_SoftTrig)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_START_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_ERQ_MASK;

    //DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHx) |= DMAMUX_CHCFG_ENBL_MASK;

    return (0);
}
Exemplo n.º 4
0
//======================================================================
//函数名称:DMA_Strat()
//函数功能:开始DMA模块传输
//输    入:DMA_Struct_TypeDef      *DMA_Struct         DMA结构体地址
//输    出:无
//返    回:无
//======================================================================
void DMA_Start(DMA_Struct_TypeDef *DMA_Struct)
{
    DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x_GET((*DMA_Struct).DMAMUX_Source)],
                     (*DMA_Struct).DMA_CHn) |= DMAMUX_CHCFG_ENBL_MASK;
}