Skip to main content
hibou
Associate
May 30, 2014
Question

while(!DMA_GetFlagStatus(...)); never pass ....

Posted on May 30, 2014 at 11:31

Hi,
I have a big problem,I try to use a WS2812 (LED card), with a stm32f4
But it doesn t work at all ....
I try in debug and the program is blocked here:while(!DMA_GetFlagStatus(DMA1_Stream5, DMA_FLAG_TCIF5));
please help ...

#include ''main.h''
#include ''usbd_hid_core.h''
#include ''usbd_usr.h''
#include ''usbd_desc.h''
#define TESTRESULT_ADDRESS 0x080FFFFC
#define ALLTEST_PASS 0x00000000
#define ALLTEST_FAIL 0x55555555
#define TIM3_CCR1_Address 0x40000434 // physical memory address of Timer 3
CCR1 register
#define d2r (3.14159265/180)

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment = 4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END;
uint16_t PrescalerValue = 0;
__IO uint32_t TimingDelay;
__IO uint8_t DemoEnterCondition = 0x00;
__IO uint8_t UserButtonPressed = 0x00;
LIS302DL_InitTypeDef LIS302DL_InitStruct;
LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct;
__IO int8_t X_Offset, Y_Offset, Z_Offset = 0x00;
uint8_t Buffer[6];
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure1;
uint16_t LED_BYTE_Buffer[100];
uint8_t eightbit[766][3] =
{
{255, 0, 0},
 ........ // big tab ^^
{255, 0, 0},
};

void
Timer3_init(
void
)
{
uint16_t PrescalerValue;
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Compute the prescaler value */
PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 29; 
// 800kHz
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
/* configure DMA */
/* DMA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_DeInit(DMA1_Stream5);
/* Configure DMA Stream */
DMA_InitStructure1.DMA_Channel = DMA_Channel_5;
DMA_InitStructure1.DMA_PeripheralBaseAddr = 0x40000434;
DMA_InitStructure1.DMA_Memory0BaseAddr = (uint32_t)LED_BYTE_Buffer;
DMA_InitStructure1.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure1.DMA_BufferSize = 42;
DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure1.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure1.DMA_Priority = DMA_Priority_High;
DMA_InitStructure1.DMA_FIFOMode = DMA_FIFOMode_Disable;
//DMA_InitStructure1.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure1.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure1.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream5, &DMA_InitStructure1);
/* TIM3 CC1 DMA Request enable */
TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE);
}
void
WS2812_send(uint8_t (*color)[3], uint16_t len)
{
uint8_t j;
uint8_t led;
uint16_t memaddr;
uint16_t buffersize;
buffersize = (len*24)+42; 
// number of bytes needed is #LEDs * 24 bytes +
42 trailing bytes
memaddr = 0; 
// reset buffer memory index
led = 0; 
// reset led index
// fill transmit buffer with correct compare values to achieve
// correct pulse widths according to color values
while
(len)
{
for
(j = 0; j < 8; j++) 
// GREEN data
{
if
( (color[led][1]<<j) & 0x80 ) 
// data sent MSB first, j = 0 is MSB j
= 7 
is
LSB
{
LED_BYTE_Buffer[memaddr] = 17; 
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = 9; 
// compare value for logical 0
}
memaddr++;
}
for
(j = 0; j < 8; j++) 
// RED data
{
if
( (color[led][0]<<j) & 0x80 ) 
// data sent MSB first, j = 0 is MSB j
= 7 
is
LSB
{
LED_BYTE_Buffer[memaddr] = 17; 
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = 9; 
// compare value for logical 0
}
memaddr++;
}
for
(j = 0; j < 8; j++) 
// BLUE data
{
if
( (color[led][2]<<j) & 0x80 ) 
// data sent MSB first, j = 0 is MSB j
= 7 
is
LSB
{
LED_BYTE_Buffer[memaddr] = 17; 
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = 9; 
// compare value for logical 0
}
memaddr++;
}
led++;
len--;
}
// add needed delay at end of byte cycle, pulsewidth = 0
while
(memaddr < buffersize)
{
LED_BYTE_Buffer[memaddr] = 0;
memaddr++;
}
DMA_SetCurrDataCounter(DMA1_Stream5, buffersize);
DMA_Cmd(DMA1_Stream5, ENABLE);
TIM_Cmd(TIM3, ENABLE);
while
(!DMA_GetFlagStatus(DMA1_Stream5, DMA_FLAG_TCIF5)); 
TIM_Cmd(TIM3, DISABLE); 
DMA_Cmd(DMA1_Stream5, DISABLE); 
DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5);
}
int
main(
void
)
{
int16_t i;
Timer3_init();
while
(1){
/* first cycle through the colors on 2 LEDs chained together
* last LED in the chain will receive first sent triplet
* --> last LED in the chain will 'lead'
*/
for
(i = 0; i < 766; i += 2)
{
WS2812_send(&eightbit[i], 2);
Delay(50000L);
}
/* cycle through the colors on only one LED
* this time only the first LED that data is
* fed into will update
*/
for
(i = 0; i < 766; i += 1)
{
WS2812_send(&eightbit[i], 1);
Delay(50000L);
}
}
}
void
Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while
(TimingDelay != 0);
}
/**
* @brief Decrements the TimingDelay variable.
* @param None
* @retval None
*/
void
TimingDelay_Decrement(
void
)
{
if
(TimingDelay != 0x00)
{
TimingDelay--;
}
}
/**
* @brief This function handles the test program fail.
* @param None
* @retval None
*/
void
Fail_Handler(
void
)
{
/* Erase last sector */
FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
/* Write FAIL code at last word in the flash memory */
FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_FAIL);
while
(1)
{
/* Toggle Red LED */
STM_EVAL_LEDToggle(LED5);
Delay(5);
}
}
/**
* @brief MEMS accelerometre management of the timeout situation.
* @param None.
* @retval None.
*/
uint32_t LIS302DL_TIMEOUT_UserCallback(
void
)
{
/* MEMS Accelerometer Timeout error occured during Test program
execution */
if
(DemoEnterCondition == 0x00)
{
/* Timeout error occured for SPI TXE/RXNE flags waiting loops.*/
Fail_Handler();
}
/* MEMS Accelerometer Timeout error occured during Demo execution */
else
{
while
(1)
{
}
}
return
0;
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void
assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line
number,
ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file,
line) */
/* Infinite loop */
while
(1)
{
}
}
#endif

#ws2812-stm32-led-pwm-dma
This topic has been closed for replies.

20 replies

Tesla DeLorean
Guru
May 30, 2014
Posted on May 30, 2014 at 15:28

Yes, I haven't review everything, but you aren't using the right stream. You need to review the DMA trigger table in RM0090

TIM3_CH1 is Stream 4 (Channel 5, DMA1)

TIM3_UP is Stream 2 (Channel 5, DMA1)

You don't get a TC signal because there are no transfers occurring, and you can't make random associations.

Expressing the peripheral address as (uint32_t)&TIM3->CCR1; might be preferable to a define. I don't recall if TIM3 is 32-bit or 16-bit, this will of course impact the width of CCR1
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
hibou
hibouAuthor
Associate
May 30, 2014
Posted on May 30, 2014 at 18:01

hey, thanks for your answer, but I don't understand because like you can see here (page 9):

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00046011.pdf

We have on DMA1, TIM3_CH2 in stream5, channel 5

In fact we have a STM32F407 but I guess it's the same ?

So is it good to use stream5, channel5 with TIM3 please ?

hibou
hibouAuthor
Associate
June 2, 2014
Posted on June 02, 2014 at 10:15

Any ideas, please ?

stm322399
Senior
June 2, 2014
Posted on June 02, 2014 at 10:50

Either use Stream4 as Clive recommended, or change TIM3_CH1 for TIM3_CH2 if you really prefer to use Stream5.

waclawek.jan
Super User
June 2, 2014
Posted on June 02, 2014 at 10:52

You don't use CH2, so why would the related DMA stream/channel be relevant?

JW
hibou
hibouAuthor
Associate
June 2, 2014
Posted on June 02, 2014 at 11:56

Thank you for your answer ...

I'm a beginner and I don't understand how to use this channel 2 in fact ... so please if you can indicate me ... what to do

waclawek.jan
Super User
June 2, 2014
Posted on June 02, 2014 at 12:13

> I'm a beginner and I don't understand how to use this channel 2 in fact ... so please if you can indicate me ... what to do

The timer has 4 channels, i.e. 4 ''outputs'' - think of it as if it would be an integrated circuit with 4 output pins, except it's integrated within the microcontroller - and every output goes to a different DMA stream/channel. So if you configure output on channel 1 usin

g
TIM_OC1Init()

, you then should use the DMA Stream/Channel connected to that one, i.e. DMA1/Stream4/Channel5. JW
hibou
hibouAuthor
Associate
June 2, 2014
Posted on June 02, 2014 at 13:15

Thank you for your answer

Oh ok so I must change Stream5 by Stream4, good.

Is it good to say that I can, also, use 

TIM_OC2Init() instead of 

TIM_OC1Init() ?

I will try with stream4 btw, thanks

hibou
hibouAuthor
Associate
June 2, 2014
Posted on June 02, 2014 at 18:43

SO i tried with Stream4, I change all stream5 by Stream4 ... and it doesn't work again .... program block on the same while ... transfer never finish ...

Please help 

waclawek.jan
Super User
June 2, 2014
Posted on June 02, 2014 at 18:59

Post the content of TIM and DMA registers when stopped in the while loop.

JW