Advertisement
Guest User

Untitled

a guest
Dec 11th, 2017
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.24 KB | None | 0 0
  1. #include "ws2812.h"
  2.  
  3. #define PWM_FREQ            800000UL                    /* Number in units of hertz */
  4. #define PWM_1US             (1000000UL / PWM_FREQ)      /* Number of PWM pulses for 1 us */
  5. #define RESET_LEN           100UL                       /* 50us pulse length */
  6. #define RESET_BYTES_COUNT  (RESET_LEN * PWM_1US)        /* Number of reset pulses */
  7.  
  8. #define BYTES_PER_LED       24                          /* Number of bytes per led */
  9.  
  10. #define WS2812_LAST_SLOT_LEN    1                       /* Additional 1 byte at the end */
  11. #define WS2812_1            (2 * TIM_PERIOD / 3)        /* Logical 1 value */
  12. #define WS2812_0            (TIM_PERIOD / 3)            /* Logical 0 value */
  13. #define WS2812_RST          0                           /* Reset value */
  14.  
  15. #define TIM_PRESCALER       0
  16. #define TIM_PERIOD          44 //works
  17.  
  18. TIM_HandleTypeDef htim3;
  19. DMA_HandleTypeDef hdma_tim3_ch1_trig;
  20. uint32_t data[RESET_BYTES_COUNT + LED_COUNT * BYTES_PER_LED + WS2812_LAST_SLOT_LEN + RESET_BYTES_COUNT];
  21.  
  22. void WS_Init(void) {
  23.     TIM_MasterConfigTypeDef sMasterConfig;
  24.     TIM_OC_InitTypeDef sConfigOC;
  25.     GPIO_InitTypeDef GPIO_InitStruct;
  26.      
  27.     /* DMA controller clock enable */
  28.     __HAL_RCC_DMA1_CLK_ENABLE();
  29.     __HAL_RCC_TIM3_CLK_ENABLE();
  30.     __HAL_RCC_GPIOB_CLK_ENABLE();
  31.  
  32.     /* Init GPIO */
  33.     GPIO_InitStruct.Pin = GPIO_PIN_4;
  34.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  35.     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  36.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  37.     GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
  38.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  39.  
  40.     /* Init timer */
  41.     htim3.Instance = TIM3;
  42.     htim3.Init.Prescaler = TIM_PRESCALER;
  43.     htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  44.     htim3.Init.Period = TIM_PERIOD;
  45.     htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  46.     HAL_TIM_PWM_Init(&htim3);
  47.  
  48.     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  49.     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  50.     HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
  51.  
  52.     /* Init PWM channel */
  53.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  54.     sConfigOC.Pulse = htim3.Init.Period / 2;
  55.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  56.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  57.     HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
  58.    
  59.     hdma_tim3_ch1_trig.Instance = DMA1_Channel6;
  60.     hdma_tim3_ch1_trig.Init.Direction = DMA_MEMORY_TO_PERIPH;
  61.     hdma_tim3_ch1_trig.Init.PeriphInc = DMA_PINC_DISABLE;
  62.     hdma_tim3_ch1_trig.Init.MemInc = DMA_MINC_ENABLE;
  63.     hdma_tim3_ch1_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  64.     hdma_tim3_ch1_trig.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  65.     hdma_tim3_ch1_trig.Init.Mode = DMA_NORMAL;
  66.     hdma_tim3_ch1_trig.Init.Priority = DMA_PRIORITY_LOW;
  67.     HAL_DMA_Init(&hdma_tim3_ch1_trig);
  68.  
  69.     /* Several peripheral DMA handle pointers point to the same DMA handle.
  70.     Be aware that there is only one channel to perform all the requested DMAs. */
  71.     __HAL_LINKDMA(&htim3, hdma[TIM_DMA_ID_CC1], hdma_tim3_ch1_trig);
  72.     __HAL_LINKDMA(&htim3, hdma[TIM_DMA_ID_TRIGGER], hdma_tim3_ch1_trig);
  73.  
  74.     /* DMA interrupt init */
  75.     /* DMA1_Channel6_IRQn interrupt configuration */
  76.     HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
  77.     HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
  78. }
  79.  
  80.  
  81. void WS_Update(void) {
  82.     HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, data, sizeof(data) / sizeof(data[0])); /* Start sending and don't wait for it */
  83.     while (htim3.hdma[TIM_DMA_ID_CC1]->Instance->CNDTR > 0);    /* Check if anything to send */
  84. }
  85.  
  86. void WS_SetColor(uint32_t ledIndex, uint8_t r, uint8_t g, uint8_t b, uint8_t update) {
  87.     uint8_t i = 0;
  88.     ledIndex = ledIndex % LED_COUNT;
  89.    
  90.     for (i = 0; i < 8; i++) {                           /* Set colors, order is green, red, blue */
  91.         data[RESET_BYTES_COUNT + ledIndex * BYTES_PER_LED + 0 + i] = ((g << i) & 0x80) ? WS2812_1 : WS2812_0;
  92.         data[RESET_BYTES_COUNT + ledIndex * BYTES_PER_LED + 8 + i] = ((r << i) & 0x80) ? WS2812_1 : WS2812_0;
  93.         data[RESET_BYTES_COUNT + ledIndex * BYTES_PER_LED + 16 + i] = ((b << i) & 0x80) ? WS2812_1 : WS2812_0;
  94.     }
  95.    
  96.     if (update) {                                       /* Update leds on demand */
  97.         WS_Update();
  98.     }
  99. }
  100.  
  101. void WS_SetColorAll(uint8_t r, uint8_t g, uint8_t b, uint8_t update) {
  102.     uint16_t ledIndex = 0;
  103.    
  104.     /* Set color for all leds */
  105.     for (ledIndex = 0; ledIndex < LED_COUNT; ledIndex++) {
  106.         WS_SetColor(ledIndex, r, g, b, 0);              /* Set colors without immediatelly update process */
  107.     }
  108.    
  109.     if (update) {                                       /* Update leds on demand */
  110.         WS_Update();
  111.     }
  112. }
  113.  
  114. void WS_ScrollForwardColor(uint8_t r, uint8_t g, uint8_t b) { ///It is red, green, blue
  115.     uint8_t index;
  116.    
  117.     for (index = 0; index < LED_COUNT; index++) {
  118.         WS_SetColorAll(0, 0, 0, 0);                     /* Set colors for all leds and don't update immediatelly */
  119.         WS_SetColor(index, r, g, b, 1);                 /* Set color for specific led and update */
  120.         HAL_Delay(50);                                 /* Little delay */
  121.     }
  122. }
  123.  
  124. /* Interrupt function service routine */
  125. void DMA1_Channel6_IRQHandler(void) {
  126.   HAL_DMA_IRQHandler(&hdma_tim3_ch1_trig);
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement