2014-06-08 06:49 AM
I want to pilot LED on a ws2812: here is the datasheet
http://www.adafruit.com/datasheets/WS28pdf
Like you can see you need 24 bits for pilot one LED (change the color) ..My LEDs are only white every time ... I don't understand why because my table Led_Byte_Buffer is correct (I saw it whith the debug) and my times too (350ns for a 0 and 700ns for a 1). Help please Here the code:#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 3CCR1 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];
uint8_t led;
uint16_t memaddr;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure1;
uint16_t LED_BYTE_Buffer[240];
uint8_t eightbit[766][3] =
{
{255, 0, 0},
{254, 1, 0},
//...... BIG TABLE
{253, 0, 2},
{254, 0, 1},
{255, 0, 0},
};
void
Timer3_init(
void
)
{
uint16_t PrescalerValue;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Compute the prescaler value */
PrescalerValue = (uint16_t) (SystemCoreClock / 168000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 105;
// 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_Stream4);
/* Configure DMA Stream */
DMA_InitStructure1.DMA_Channel = DMA_Channel_5;
DMA_InitStructure1.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR1;
DMA_InitStructure1.DMA_Memory0BaseAddr = (uint32_t)LED_BYTE_Buffer;
DMA_InitStructure1.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure1.DMA_BufferSize = 1;
DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
//DMA_InitStructure1.DMA_MemoryBurst = DMA_MemoryBurst_Single;
//DMA_InitStructure1.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream4, &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;
uint16_t buffersize;
int
zero = 30;
int
un = 60;
buffersize = (len*24);
// 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][0]<<j) & 0x80)
// data sent MSB first, j = 0 is MSB j= 7 is LSB
{
LED_BYTE_Buffer[memaddr] = un;
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = zero;
// compare value for logical 0
}
memaddr++;
}
for
(j = 0; j < 8; j++)
// RED data
{
if
( (color[led][1]<<j) & 0x80 )
// data sent MSB first, j = 0 is MSB j= 7 is LSB
{
LED_BYTE_Buffer[memaddr] = un;
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = zero;
// 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] = un;
// compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = zero;
// 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_Stream4, buffersize);
DMA_Cmd(DMA1_Stream4, ENABLE);
TIM_Cmd(TIM3, ENABLE);
while
(!DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4));
TIM_Cmd(TIM3, DISABLE);
DMA_Cmd(DMA1_Stream4, DISABLE);
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
}
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 < 700; i += 1)
{
WS2812_send(&eightbit[i], 5);
Delay(40000L);
}
/* 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], 2);
// Delay(50000L);
}*/
}
}
void
Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while
(TimingDelay != 0) TimingDelay--;
}
/**
* @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-led-dma-stm32f407