/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / DMA1 Channel 5 under Circle OS 3.8

Username:     
Password:     
             

Forum

# 1   2010-01-28 05:36:02 DMA1 Channel 5 under Circle OS 3.8

cronicon
New member
Registered: 2009-02-09
Posts: 7

DMA1 Channel 5 under Circle OS 3.8

I have looked through most of the posts in the forums on setting up the DMA and ADC1, but I could not fine a solution to what I am experience. I have also successfully compiled the examples in the library but still no luck.
I have been trying to configure the DMA1 channel 5 to read ADC1 in continues conversion mode, but every time I run my program, DMA1 Channel 5 does not want to read my ADC, it stays idle. But the moment I change the DMA channel to channel 1 it suddenly works, but channel 1 of DMA1 is used for battery monitoring by the circle OS 3.8. When i copy the example code to my circle OS application and try to run it compiles but I have the same problem. The DMA values stays idle and nothing happens.

I would really like some advice on my next step.

sad

Offline

 

# 2   2010-01-28 07:09:22 DMA1 Channel 5 under Circle OS 3.8

yrt
Administrator
From: Grenoble-France
Registered: 2008-06-11
Posts: 520
Website

Re: DMA1 Channel 5 under Circle OS 3.8

Hi,

In STM32, DMA channels requests are preaffected to peripherals.
ADC1 requests are send to DMA1 Channel1. The channel 5 is connected to SPI2/USART1/I2C2_Rx ans some TIM).

Refer to the reference manual (RM008, paragraph "Summary of DMA1 requests for each channel") that you can download from ST website, at this URL http://www.st.com/stonline/products/lit … /13902.pdf

Yves

Offline

 

# 3   2010-01-28 07:38:33 DMA1 Channel 5 under Circle OS 3.8

cronicon
New member
Registered: 2009-02-09
Posts: 7

Re: DMA1 Channel 5 under Circle OS 3.8

neutral 
lol

It’s like having one of those moments that everything is quiet, and you look around to see if someone is looking at you while you crawling under a rock.


Thanks for the help 'yrt'.

Offline

 

# 4   2010-01-30 21:30:54 DMA1 Channel 5 under Circle OS 3.8

cronicon
New member
Registered: 2009-02-09
Posts: 7

Re: DMA1 Channel 5 under Circle OS 3.8

I have the following problem:
ADC1 is configured to be serviced by DMA1 channel 1.
But the end of transfer complete interrupt does not want to work although I have set it up as in the examples.   
I have done the following setup:

Code:

 

/* Includes ------------------------------------------------------------------*/

#include "circle_api.h"
#include "myinclude.h"


/* Private defines -----------------------------------------------------------*/


#define ADC1_DR_Address    ((uint32_t)0x4001244C)// address of ADC data register in memory


// The following should be the minimal CircleOS version needed by your application
#define NEEDEDVERSION "V 3.7"

/* Private functions ---------------------------------------------------------*/
static enum MENU_code MsgVersion(void);

void RCC_Setup(void);
void GPIO_Setup(void);
void NVIC_Setup(void);//interrupt setup
void DMA_Setup(void);
void ADC_Setup(void);

/* Public variables ----------------------------------------------------------*/
const char Application_Name[8+1] = {"ADC_DMA"};      // Max 8 characters
uint32_t sourceclock;
uint32_t ADC_Clock_Prev;

u32 uGain;


/* Private variables ---------------------------------------------------------*/
RCC_ClocksTypeDef RCC_Clocks;// 
GPIO_InitTypeDef GPIO_InitStructure;//Step 0.5
NVIC_InitTypeDef NVIC_InitStructure;//
DMA_InitTypeDef DMA_InitStructure;//
ADC_InitTypeDef ADC_InitStructure;//




  

/*******************************************************************************
* Function Name  : Application_Ini
* Description    : Initialization function of Circle_App. This function will
*                  be called only once by CircleOS.
* Input          : None
* Return         : MENU_CONTINUE_COMMAND
*******************************************************************************/
enum MENU_code Application_Ini(void)
    {
    // Ensure that the current OS version is recent enough
    if(strcmp(UTIL_GetVersion(), NEEDEDVERSION) < 0)
        {
        return MsgVersion();
        }
        
      RCC_Setup();

    NVIC_Setup();
    DMA_Setup();

    ADC_Setup();


    //debug code
    uGain =0;
    ///////////////////
    // TODO: Write your application initialization function here.


    return MENU_CONTINUE_COMMAND;
    }

/*******************************************************************************
* Function Name  : Application_Handler
* Description    : Management of the Circle_App.
*
* Input          : None
* Return         : MENU_CONTINUE
*******************************************************************************/
enum MENU_code Application_Handler(void)
    {


    // TODO: Write your application handling here.


    // This routine will get called repeatedly by CircleOS, until we
    // return MENU_LEAVE

#if 1
    // If the button is pressed, the application is exited
    if(BUTTON_GetState() == BUTTON_PUSHED)
        {
        BUTTON_WaitForRelease();
        return MENU_Quit();
        }
#endif

    return MENU_CONTINUE;   // Returning MENU_LEAVE will quit to CircleOS
    }

/*******************************************************************************
* Function Name  : MsgVersion
* Description    : Display the current CircleOS version and the version needed
*                  exit to main menu after 4 secondes
*
* Input          : None
* Return         : MENU_REFRESH
*******************************************************************************/
static enum MENU_code MsgVersion(void)
   {
   int hh,mm,ss,ss2;
   
   DRAW_DisplayString(5,60,"CircleOS",17);
   DRAW_DisplayString(80,60,UTIL_GetVersion(),6);
   DRAW_DisplayString(5,34,NEEDEDVERSION,6);
   DRAW_DisplayString(50,34," required",12);
   
   RTC_GetTime( &hh, &mm, &ss);
   ss = ss + 4;                  // 4 secondes 
   ss = ss%60;
   
   do
        {
        RTC_GetTime( &hh, &mm, &ss2 );
        }
   while ( ss2 != ss );           // do while < 4 secondes
   
   DRAW_Clear();
   return MENU_REFRESH;
   }
/****************************************************************************
 *
 * NAME: RCC_Setup
 *
 * DESCRIPTION:
 * Configures the RCC pheriperals clocks
 * 
 * 
 * RETURNS:
 * Zero returns.
 *
 ****************************************************************************/
void RCC_Setup(void)
{
    /* Enable DMA1 clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
    // Enable PORT clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
    /* Enable ADC1 clock */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE );
    

}
/****************************************************************************
 *
 * NAME: NVIC_Setup
 *
 * DESCRIPTION:
 * Configures the NVIC -- Interrupt controller
 *     
 *    
 *
 * RETURNS:
 * Zero returns.
 *
 ****************************************************************************/
void NVIC_Setup(void)
{
  /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;//    
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//    
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//    
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// 
    NVIC_Init(&NVIC_InitStructure);//
 }
/****************************************************************************
 *
 * NAME: DMA_Setup
 *
 * DESCRIPTION:
 * Configures the DMA  
 *
 * RETURNS:
 * Zero returns.
 *
 ****************************************************************************/
void DMA_Setup(void)
{

    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//    
    DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)&ADCConvertedValue;//    
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//    
    DMA_InitStructure.DMA_BufferSize = 1;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//    
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//Hight priority
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// tomemory transfer
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);// 
    /* Enable DMA1 channel1 */
    DMA_Cmd(DMA1_Channel1, ENABLE);




}
/****************************************************************************
 *
 * NAME: ADC_Setup
 *
 * DESCRIPTION:
 * Configures the ADC pheriperal 
 *
 * RETURNS:
 * Zero returns.
 *
 ****************************************************************************/
void ADC_Setup(void)
{
    
    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//    
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;//    
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//    
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;// 
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//    
    ADC_InitStructure.ADC_NbrOfChannel = 1;//
    ADC_Init(ADC1, &ADC_InitStructure);

      /* ADC1 regular channel14 configuration */ 
    ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5);
    
    /* Enable ADC1 DMA */
    ADC_DMACmd(ADC1, ENABLE);
  
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);

    /* Enable ADC1 reset calibaration register */   
    ADC_ResetCalibration(ADC1);
    /* Check the end of ADC1 reset calibration register */
    while(ADC_GetResetCalibrationStatus(ADC1));

    /* Start ADC1 calibaration */
    ADC_StartCalibration(ADC1);
    /* Check the end of ADC1 calibration */
    while(ADC_GetCalibrationStatus(ADC1));
     
    /* Start ADC1 Software Conversion */ 
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);



}
/****************************************************************************
 *
 * NAME: GPIO_Setup
 *
 * DESCRIPTION:
 * Configures the GPIO pheriperal 
 *
 * RETURNS:
 * Zero returns.
 *
 ****************************************************************************/
void GPIO_Setup(void)
{

    
    /* Configure pin as analog input ---------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
   
}

What I want to accomplish with this code is to read the ADC1 in to a memory area by using the DMA controller.
Then afterwards write the logged data to the external SDCARD interface. This is my DMA interrupt handler for my DMA interrupt.

Code:

/
******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/
/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
void DMA1_Channel1_IRQHandler(void)
{
    ADCValue_DMA1 = ADCConvertedValue;
    
}

I do not know what I’m doing wrong.
Any suggestions or help maybe?

Offline

 

# 5   2010-02-01 08:32:50 DMA1 Channel 5 under Circle OS 3.8

yrt
Administrator
From: Grenoble-France
Registered: 2008-06-11
Posts: 520
Website

Re: DMA1 Channel 5 under Circle OS 3.8

Hi Cronicon,

The ADC1_Channel_14 (Primer2's CX_ADC1 signal) is wired to the port PC4 of the STM32 and not PC14, as you wrote int the GPIO_Setup function.

Yves

Offline

 

# 6   2010-02-01 09:25:03 DMA1 Channel 5 under Circle OS 3.8

cronicon
New member
Registered: 2009-02-09
Posts: 7

Re: DMA1 Channel 5 under Circle OS 3.8

I noticed it and have made changes to it to Pin_4. This change had no effect on generating a DMA_IT_TC interrupt from the DMA controller.
I started a new application without the circle OS and used exactly the same code setup for NVIC, DMA, ADC and it worked.

I don’t know any more. It may be that my priorities are setup wrong  or something.

Any advice?

Offline

 

# 7   2010-02-01 20:04:26 DMA1 Channel 5 under Circle OS 3.8

cronicon
New member
Registered: 2009-02-09
Posts: 7

Re: DMA1 Channel 5 under Circle OS 3.8

I got it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! big_smile

I finaly got it right, and the only bit of code i missed was "UTIL_SetIrqHandler" see section below.

Code:

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  

    UTIL_SetIrqHandler(108, (tHandler)DMA1_Channel1_IRQHandler); // <-------------This Code and vector address I needed to add


    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC    , ENABLE);//

hope this help some one else also.

lol

Last edited by cronicon (2010-02-01 20:05:14)

Offline

 

Board footer