查看: 196|回复: 2

[求助] K60 SPI DMA配置问题和如何触发硬件DMA请求

[复制链接]
  • TA的每日心情
    擦汗
    2024-2-23 16:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    4

    帖子

    0

    注册会员

    Rank: 2

    积分
    102
    最后登录
    2024-4-19
    发表于 2024-3-12 11:22:39 | 显示全部楼层 |阅读模式
    我在FPGA板中搭了一个K60 的核,在测试其中SPI 使用DMA发送和接收数据,受限于数据结构只能直接对寄存器编写,我该怎么确认DMA在运作,SPI 的DMA请求是怎么触发的,我可以主动进行触发吗
    我知道答案 目前已有2人回答
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-2-23 16:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    4

    帖子

    0

    注册会员

    Rank: 2

    积分
    102
    最后登录
    2024-4-19
     楼主| 发表于 2024-3-12 11:23:29 | 显示全部楼层
    uint32_t i;
    uint32_t S1_status = 0,count = 0;
    uint32_t tx_data[8] = {0xAA,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
    uint32_t rx_data[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint32_t DMA_TX_data[10] = {0x55};
    uint32_t A,B,C,D,E,F,G,H,I,J,mode=0;

    #define BANDRATE                         9600
    uint32_t BandRateCode = 50000000/16/BANDRATE;

    NVIC_InitTypeDef NVIC_InitStruct = {
            .NVIC_IRQChannel = DMA_Channel0_IRQn,
            .NVIC_IRQChannelPriority = 0x01,
            .NVIC_IRQChannelCmd = ENABLE
    };
    int main(void)
    {
            /*gpio clk rst set*/
            CLKGEN->icg_ctrl2 |= BIT0;//0x00000001;
            RSTGEN->soft_reset_ctrl4 |= BIT0;//0x00000001;
           
            /*SPI clk rst set*/
            CLKGEN->icg_ctrl1|= BIT20;//0x00010000;
            RSTGEN->soft_reset_ctrl2 |= BIT16;//0x10000000;
           
            /*uart clk rst set*/
            CLKGEN->icg_ctrl1 |= BIT16;//0x00010000;
            RSTGEN->soft_reset_ctrl1 |= BIT28;//0x10000000;
           
            /*dma clk rst set*/
            CLKGEN->icg_ctrl0 |= BIT16|BIT12;//0x00010000;
            RSTGEN->soft_reset_ctrl1 |= BIT8|BIT12;//0x00000100;  
           
            /*dma io mux clk rst set*/
            CLKGEN->icg_ctrl2 |= BIT28;//0x10000000;
            RSTGEN->soft_reset_ctrl3 |= BIT16;//0x00010000;
           
                    // 将[10:8]位设置为4,对应GPIO2,, DO
            IOMUX->func_sel0 &= ~(0x7 << 0);  // 先将[2:0]位清零
            IOMUX->func_sel0 |= (2 << 0);     // 设置[2:0]位为4

            // 将[6:4]位设置为4,对应GPIO1,,CS
            IOMUX->func_sel0 &= ~(0x7 << 4);  // 先将[6:4]位清零
            IOMUX->func_sel0 |= (2 << 4);     // 设置[6:4]位为4
           
            IOMUX->func_sel0 &= ~(0x7 << 8);  // 先将[10:8]位清零
            IOMUX->func_sel0 |= (1 << 8);     // 设置[10:8]位为4

            // 将[14:12]位设置为4,对应GPIO3,  DI
            IOMUX->func_sel0 &= ~(0x7 << 12);  // 先将[14:12]位清零
            IOMUX->func_sel0 |= (1 << 12);     // 设置[14:12]位为4
           

    //         unsigned char *ptr = (unsigned char *)0x4001d020;
    //   
    //    // 将0x55写入地址0x1000
    //    *ptr = 0x66;
             
             
            //transmitter enable,receiver enable
    //        UART->C2 = 0x0c;
    //       
    //        UART->C2 |= BIT5;                        /* Enable Receiver interrupts*/

            ////////////////////////////////////////////////////////////////////////
           
                    //----------------------------通道0---------------------------//
           
            DMA_CH_MUX->CHCFG0=0;//通道选择
           
      DMA_CH_MUX->CHCFG0=0x8E000000;//BIT7|BIT6|BIT0|BIT1;//通道选择                          0~5选择DMA源
            //0X00
            DMA_TCD->TCD0.SADDR= 0x2000000C ;   //源地址
           
            //0X04
            DMA_TCD->TCD0.SOFF_ATTR|=(0 << 0);  // SOFF  源地址偏移量,在每个源读取完成时,应用于当前源地址的符号扩展偏移量,以形成下一状态值。

            DMA_TCD->TCD0.SOFF_ATTR|=(2 << 16); // DSIZE 目标数据大小
            DMA_TCD->TCD0.SOFF_ATTR|=(0 << 19); // DMOD
            DMA_TCD->TCD0.SOFF_ATTR|=(2 << 24); // SSIZE 源地址数据大小
            DMA_TCD->TCD0.SOFF_ATTR|=(0 << 27); // SMOD
           
            //0X08
            //-------------------------小循环未开启时
            DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(8 << 0); // NBYTES 最小字节传输
            //-------------------------小循环开启,offset未设置
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 0); // NBYTES
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 30); // DMLOE
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 31); // SMLOE
            //-------------------------小循环开启,offset设置
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 0); // NBYTES
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 10); // MLOFF
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 30); // DMLOE
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES|=(0 << 31); // SMLOE
           
            //0X0C
            DMA_TCD->TCD0.SLAST|=0X01; //SLAST 最后一次调整目标地址
           
            //0X10
            DMA_TCD->TCD0.DADDR=0x4000D01C;  //目标地址
           
            //0X14
            DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(0 << 0); // DOFF 目标地址
            //-------------------------通道链接开启时
    //        DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(0<< 16); // CITER 主循环计数
    //        DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(0 << 25); // LINKCH 链接通道
    //        DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(0 << 31); // ELINK 小循环结束时链接的通道
           
            //-------------------------通道链接未开启时
            DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(1 << 16); // CITER 主循环计数
            DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO|=(0 << 31); // ELINK
           
            //0X18
            DMA_TCD->TCD0.DLASTSGA=0X00;//DLASTSGA
           
            //0X1C
            DMA_TCD->TCD0.CSR|=(0<<0);//START    使能请求-软件触发
            DMA_TCD->TCD0.CSR|=(1<<1);//INTMAJOR 主循环结束时启用中断
            DMA_TCD->TCD0.CSR|=(0<<2);//INTHALF  主循环一半中断
            DMA_TCD->TCD0.CSR|=(0<<3);//DREQ     禁用请求
            DMA_TCD->TCD0.CSR|=(1<<4);//ESG      
            DMA_TCD->TCD0.CSR|=(0<<5);//MAJORELINK 在主环路完成时启用通道到通道连接

            DMA_TCD->TCD0.CSR|=(0<<6);//ACTIVE   通道使能
            DMA_TCD->TCD0.CSR|=(0<<7);//DONE      
            DMA_TCD->TCD0.CSR|=(0<<8);//MAJORLINKCH
            DMA_TCD->TCD0.CSR|=(2<<14);//BWC     带宽设置

            //通道链接打开
            DMA_TCD->TCD0.CSR|=(4<<16);//BITER   重载主循环计数值
            DMA_TCD->TCD0.CSR|=(0<<25);//LINKCH
            DMA_TCD->TCD0.CSR|=(0<<31);//ELINK

           

                                                                             
                                                                   
           
           
    //         DMA_TCD->TCD0.SOFF_ATTR=BIT17|BIT25 ;//                                       0X04
    //        DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO=0X00010000;  //  16`24 CITER        0x14
    //        DMA_TCD->TCD0.CSR =0X0001C008;  //                                            0x1c
    //        DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES=0X00000004; //                     0x08  
    //        DMA_TCD ->TCD0.SLAST=0X00000001;//                                            0x0c
            DMA->ERQ=BIT0 |BIT1|BIT3;
            B=DMA->ES;
            A=DMA_TCD->TCD0.SOFF_ATTR;
            B=DMA_TCD->TCD0.DOFF_CITER_ELINKYES_ELINKNO;
            C=DMA_TCD->TCD0.CSR;
            D=DMA_TCD->TCD0.NBYTES_MLNO_MLOFFNO_MLOFFYES;
            E=DMA_TCD ->TCD0.SLAST;
            F=DMA_TCD->TCD0.SADDR;
            G=DMA_TCD->TCD0.DADDR;
            H= DMA_CH_MUX->CHCFG0 ;


    //-------------------------UART----------------------------------
            UART->BDH =(BandRateCode>>8) & 0xff;
            UART->BDL =BandRateCode & 0xff;
           
            NVIC_Init(&NVIC_InitStruct);
           
            //ctrl reg1
            UART->C1 = 0;
            //----------------------------------
            UART->S1=0XC0;
            //----------------------------------
            UART->C5=0x80;
            //UART->PFIFO=80;
            //----------------------------------
            UART->C2=0X80;//发送DMA请求
            //----------------------------------
            UART->C2=0X08;//
                    for(i=0;i<100;i++);

            UART->C2=0x0c;//使能串口传输

            A=UART->D ;

            while (1)
            {
                    DMA->ERQ=BIT0|BIT1;

                    B=DMA->ES;
                    for(i=0;i<10000;i++);

    }

           
           
           
    }


    uint32_t rx_count = 0;
    void DMA_Channel0_IRQHandler(void)
    {
            if((UART->S1 & BIT5) && (UART->C2 & BIT5))
            {
                    rx_data[rx_count++] = UART->D;
                    if(rx_count>=10)rx_count = 0;
            }
    }
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-2-23 16:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    4

    帖子

    0

    注册会员

    Rank: 2

    积分
    102
    最后登录
    2024-4-19
     楼主| 发表于 2024-3-12 11:24:07 | 显示全部楼层
    #ifndef __REG_DMA_H
    #define __REG_DMA_H


    /* Files includes ----------------------------------------------------------------------------------------------------*/
    #include <core_cm0plus.h>


    /**
      * @brief DMA Base Address Definition
      */
    #define  DMA_BASE                                  0x4001c000                                       /*!<Base Address: 0x4001c000*/
    #define  DMA_TCD_BASE                              0x4001d000                                       /*!<Base Address: 0x4001d000*/

    /**
      * @brief DMA Register Structure Definition
      */
            #pragma pack(4)
           
    typedef struct
    {
        __IO uint32_t CR;                      /*!< offset: 0x00*/
        __IO uint32_t ES;                      /*!< offset: 0x04*/
        __IO uint32_t RES02;                   /*!< offset: 0x08*/
        __IO uint32_t ERQ;                     /*!< offset: 0x0C*/
        __IO uint32_t RES04;                   /*!< offset: 0x10*/
        __IO uint32_t EEI;                     /*!< offset: 0x14*/
        __IO uint32_t CEEI;                    /*!< offset: 0x18*///CEEI,SEEI,CERQ,CERQ
        __IO uint32_t CDNE;                    /*!< offset: 0x1C*///CDNE,SSRT,CERR,CINT
        __IO uint32_t RES08;                   /*!< offset: 0x20*/
        __IO uint32_t INT;                     /*!< offset: 0x24*/
              __IO uint32_t RES10;                   /*!< offset: 0x28*/
        __IO uint32_t ERR;                     /*!< offset: 0x2C*/
        __IO uint32_t RES12;                   /*!< offset: 0x30*/
        __IO uint32_t HRS;                     /*!< offset: 0x34*/
        __IO uint32_t RES14;                   /*!< offset: 0x38*/
        __IO uint32_t RES15;                   /*!< offset: 0x3C*/
    } DMA_TypeDef;                                         

    /**
      * @brief DMA Register Structure Definition
      */
            #pragma pack(4)
    typedef struct
    {
        __IO uint32_t SADDR;                                                                                                        /*!< offset: 0x00*/
        __IO uint32_t SOFF_ATTR;                                                                                        /*!< offset: 0x04*/
        __IO uint32_t NBYTES_MLNO_MLOFFNO_MLOFFYES;                /*!< offset: 0x08*/
        __IO uint32_t SLAST;                                                                                                        /*!< offset: 0x0C*/
        __IO uint32_t DADDR;                                                                                                        /*!< offset: 0x10*/
        __IO uint32_t DOFF_CITER_ELINKYES_ELINKNO;                /*!< offset: 0x14*/
        __IO uint32_t DLASTSGA;                                                                                                /*!< offset: 0x18*/
        __IO uint32_t CSR;                                                                                                                /*!< offset: 0x1C*/
        __IO uint32_t BITER_ELINKYES_ELINKNO;                                        /*!< offset: 0x1E*/
    } TCD_TypeDef;

    typedef struct
    {
            TCD_TypeDef TCD0;
            TCD_TypeDef TCD1;
            TCD_TypeDef TCD2;
            TCD_TypeDef TCD3;
            TCD_TypeDef TCD4;
            TCD_TypeDef TCD5;
            TCD_TypeDef TCD6;
            TCD_TypeDef TCD7;
            TCD_TypeDef TCD8;
            TCD_TypeDef TCD9;
            TCD_TypeDef TCD10;
            TCD_TypeDef TCD11;
            TCD_TypeDef TCD12;
            TCD_TypeDef TCD13;
            TCD_TypeDef TCD14;
            TCD_TypeDef TCD15;
    } DMA_TCD_TypeDef;
    /**
      * @brief DMA type pointer Definition
      */
    #define DMA                                       ((DMA_TypeDef *)DMA_BASE)
    #define DMA_TCD                                   ((DMA_TCD_TypeDef *)DMA_TCD_BASE)

    #endif
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-29 06:22 , Processed in 0.122150 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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