10 years, 6 months ago.

Lock program by DMA IRQ.

Now I try (DMA) Dubble memory buffers transfer to I2S peripheral By DMA ,CIRCULAR mode program.

First ,Disable DMA IRQ ,DMA is running well ,I2S stream is good,

pc.printf("DMA CR =%4x %4x \n\r" ,DMA1_Stream4->CR ,DMA1->HISR); main() loop

I can see DMA dubble buffers alternate swiching !! sine wave sound out to i2s-D/A converter..

printf out

DMA CR =42d5f   30   M0 buffer select
DMA CR =42d5f   30
DMA CR =42d5f   30
DMA CR =c2d5f   30   M1 buffer select
DMA CR =c2d5f   30
DMA CR =c2d5f   30
DMA CR =c2d5f   30
DMA CR =42d5f   30   M0 buffer select
DMA CR =42d5f   30

But Enable DMA IRQ(Line 196),it seems program lock. STOP Printf.... main program.

Only DMA is runnig, sine wave sound out continue.

Certainly called my_irq_handler (Line 136) ,but "DMA1 HISR = 0" there is No status of DMA "in my_irq_handler(void)

What happen?

printf out

CPU SystemCoreClock is 84000000 Hz
DMA1 HISR =   0
DM------stop printf

program is here

/*
    Nucleo F401RE Board
    DMA Transmit sample   

    I2S Master Transmit (Enable MCK out)
    Phillips Format 16bit
    Dubble DMA Buffer
*/

#include "mbed.h"
#include <math.h>
#include "cmsis.h"
#include "pinmap.h"
#include "PinNames.h"
#include "error.h"
#include "stm32f401xe.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_dma_ex.h"
#include "stm32f4xx_hal_dma.h"
#include "stm32f4xx_hal_i2s.h"
#include "sine_wave.h"
#include "saw_wave.h"
#include "ST_F401_84MHZ.h" 
#include "synthesizer.h"

Serial pc(SERIAL_TX, SERIAL_RX);
DigitalOut myled(LED1);

#define I2S_BUFFERSIZE 256
#define DMA_TRANSFERCOUNT (I2S_BUFFERSIZE<<1) 

/* DMA Buffer */
volatile U16 request;
volatile U16 dma_bufnumber;

int16_t dmabuffer[2][DMA_TRANSFERCOUNT];//DMA Double Buffer

static const PinMap PinMap_I2S_MCK[] = {
    {PC_6,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {NC,    NC,    0}
};

static const PinMap PinMap_I2S_CK[] = {
    {PB_10,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {PB_13,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {NC,    NC,    0}
};

static const PinMap PinMap_I2S_WS[] = {
    {PB_12,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {PB_9,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {NC,    NC,    0}
};

static const PinMap PinMap_I2S_SD[] = {
    {PC_3,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {PB_15,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
    {NC,    NC,    0}
};

   
  DMA_InitTypeDef DMA_InitType ={
    DMA_CHANNEL_0,
    DMA_MEMORY_TO_PERIPH,
    DMA_PINC_DISABLE,
    DMA_MINC_ENABLE,             
    DMA_PDATAALIGN_HALFWORD,
    DMA_MDATAALIGN_WORD,//DMA_MDATAALIGN_HALFWORD,// 
    DMA_CIRCULAR,// DMA_PFCTRL,// 
    DMA_PRIORITY_LOW,// DMA_PRIORITY_HIGH,
    DMA_FIFOMODE_DISABLE,//DMA_FIFOMODE_ENABLE,// 
    DMA_FIFO_THRESHOLD_HALFFULL,
    DMA_MBURST_SINGLE,
    DMA_PBURST_SINGLE
   };

DMA_HandleTypeDef DMA_HandleType ={
    DMA1_Stream4,/*!< Register base address                  */
    DMA_InitType,/*!< DMA communication parameters           */ 
    HAL_UNLOCKED, /*!< DMA locking object                     */ 
    HAL_DMA_STATE_READY, /*!< DMA transfer state                     */ //HAL_DMA_STATE_RESET
    NULL,/*!< Parent object state                    */
    NULL,// dma_buf0full,/*!< DMA transfer complete callback         */
    NULL,/*!< DMA Half transfer complete callback    */
    NULL,// (*dma_buf0full),/*!< DMA transfer complete Memory1 callback */
    NULL,/*!< DMA transfer error callback            */
    NULL  /*!< DMA Error code                         */   
};

I2S_InitTypeDef my_I2S_InitType ={
    I2S_MODE_MASTER_TX,
    I2S_STANDARD_PHILLIPS,
    I2S_DATAFORMAT_16B,
    I2S_MCLKOUTPUT_ENABLE,
    I2S_AUDIOFREQ_44K,
    I2S_CPOL_LOW,
    I2S_CLOCK_PLL,
    I2S_FULLDUPLEXMODE_DISABLE    
};

HAL_I2S_StateTypeDef my_I2S_StateType={
   HAL_I2S_STATE_READY// HAL_I2S_STATE_RESET     
};

HAL_I2S_ErrorTypeDef my_I2S_ErorType={
    HAL_I2S_ERROR_NONE
};
    
I2S_HandleTypeDef my_I2S_HandleTypeDef = {
     SPI2,
     my_I2S_InitType,
     (uint16_t*)&dmabuffer[0][0],  
     I2S_BUFFERSIZE,
     NULL,
     NULL,
     NULL,
     NULL,
     &DMA_HandleType,//&my_DMA_HamdleType,    
     NULL,
     HAL_UNLOCKED, 
     my_I2S_StateType,
     my_I2S_ErorType  
};    

void init_dmabuffer(void){
    for (int i =0;i < I2S_BUFFERSIZE;i++){
        dmabuffer[0][i*2] = sine_wave[i];// 1st Buffer Lch 
        dmabuffer[0][i*2+1] = saw_wave[i];// 1nd Buffer Rch 
        dmabuffer[1][i*2] = sine_wave[i];// 2nd Buffer Lch
        dmabuffer[1][i*2+1] = saw_wave[i];// 2nd Buffer Rch
    }
}

static uint32_t my_irq_handler(void){
    pc.printf("DMA1 HISR =%4x \n\r"  ,DMA1->HISR);// Stream4 HIFR = 0 ?? DMA status is none? 
    HAL_DMA_IRQHandler(&DMA_HandleType);
    return 0;
}    

void dma_buf0full(DMA_HandleTypeDef *hdma){
    dma_bufnumber = 0;
    request |= REQUEST_BUFFERFULL;
}

void dma_buf1full(DMA_HandleTypeDef *hdma){
    //myled = 1;// for debug
    dma_bufnumber = 1;
     request |= REQUEST_BUFFERFULL;
}

#define PLLI2S_N  271
#define PLLI2S_R  2
    
int main() {
    F401_init84 myinit(0); 
    pc.baud(9600);
    pc.printf("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);
    request = REQUEST_NONE;
    init_dmabuffer();
    DMA_HandleType.XferCpltCallback = dma_buf0full;// HAL_DMA_IRQHandler call it when Transmit complete .

    DMA_HandleType.XferM1CpltCallback = dma_buf1full;;//HAL_DMA_IRQHandler call it when Transmit M1 buffer .

    /* Configure the I2S PLL */
    RCC->PLLI2SCFGR = (PLLI2S_N << 6) | (PLLI2S_R << 28);
    /* Enable the I2S PLL */
    RCC->CR |= RCC_CR_PLLI2SON;
    /* Wait until the I2S PLL is ready */
    while (!(RCC->CR & RCC_CR_PLLI2SRDY));

    __SPI2_CLK_ENABLE();
    __DMA1_CLK_ENABLE();

    pinmap_pinout(PC_6, PinMap_I2S_MCK);
    pinmap_pinout(PB_13, PinMap_I2S_CK);
    pinmap_pinout(PB_12, PinMap_I2S_WS);
    pinmap_pinout(PB_15, PinMap_I2S_SD);

    pin_mode(PC_6, PullUp);
    pin_mode(PB_13, PullUp);
    pin_mode(PB_12, PullUp);
    pin_mode(PB_15, PullUp);
 
    if(HAL_DMA_Init(&DMA_HandleType)!= HAL_OK) pc.printf("Eror in HAL_DMA_Init \n\r");
    
    if (HAL_I2S_Init(&my_I2S_HandleTypeDef)!= HAL_OK)  pc.printf("Eror in HAL_I2S_Init \n\r");

    volatile uint32_t *I2S_DR = &SPI2->DR; 
    if(HAL_DMAEx_MultiBufferStart_IT(&DMA_HandleType ,(uint32_t)&dmabuffer[0][0] ,(uint32_t )I2S_DR ,(uint32_t)&dmabuffer[1][0] ,DMA_TRANSFERCOUNT)!=HAL_OK) pc.printf("Eror in HAL_DMAEx_MultiBufferStart_IT \n\r");

    DMA1_Stream4->FCR = 0;

    NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t )my_irq_handler());// void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
    HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 3, 3);
    HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);// DMA IRQ Enable

    
    SPI2->I2SCFGR |= SPI_I2SCFGR_I2SE;// I2S Enable

     /* Enable Tx DMA Request */  
    SPI2->CR2 |= SPI_CR2_TXDMAEN;// DMA Enable  Start DMA
    
    pc.printf("DMA CR =%4x \n\r"  ,DMA1_Stream4->CR);
    pc.printf("DMA FCR =%4x \n\r"  ,DMA1_Stream4->FCR);

    pc.printf("DMA M0AR =%4x M1AR =%4x PAR = %4x \n\r"  ,DMA1_Stream4->M0AR  ,DMA1_Stream4->M1AR ,DMA1_Stream4->PAR);
    pc.printf("I2S CR2 = %4x \n\r" ,SPI2->CR2);
    pc.printf("I2S SR = %4x \n\r" ,SPI2->SR);
    pc.printf("I2S I2SCFGR = %4x \n\r" ,SPI2->I2SCFGR);
    pc.printf("I2S I2SPR = %4x \n\r" ,SPI2->I2SPR);
    pc.printf("RCC->PLLI2SCFGR = %4x \n\r" ,RCC->PLLI2SCFGR);
 
  while(1) {
        if (dma_bufnumber){
            myled = 1;    
        }else{
            myled = 0;
        }         
        pc.printf("DMA CR =%4x %4x \n\r"  ,DMA1_Stream4->CR ,DMA1->HISR);// Not reach this ???

  }
}
 

1 Answer

6 years, 7 months ago.

Hi, probably much too late, but I just noticed, but maybe it helps other friends.

    NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t )my_irq_handler());

should be function name without ():

    NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t )my_irq_handler);