stm-ledstrip : Driver and test routine for WS2811 RGB-LED

  1. #include "ws2812.h"
  2. #include <stm32f4xx.h>
  3. #include <stm32f4xx_rcc.h>
  4. #include <stm32f4xx_gpio.h>
  5. #include <stm32f4xx_tim.h>
  6. #include <stm32f4xx_dma.h>
  7.  
  8. static uint16_t PWM_Buffer[ PWM_BUFFER_SIZE ];
  9. uint32_t frame_pos = ;
  10. int incomplete_return = ;
  11.  
  12. void Update_Buffer( uint16_t* buffer );
  13.  
  14. static void start_dma( void )
  15. {
  16. static DMA_InitTypeDef dma_init =
  17. { .DMA_BufferSize = PWM_BUFFER_SIZE, .DMA_Channel = DMA_Channel_5, .DMA_DIR =
  18. DMA_DIR_MemoryToPeripheral, .DMA_FIFOMode = DMA_FIFOMode_Disable,
  19. .DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull, .DMA_Memory0BaseAddr =
  20. (uint32_t) PWM_Buffer, .DMA_MemoryBurst = DMA_MemoryBurst_Single,
  21. .DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord, .DMA_MemoryInc =
  22. DMA_MemoryInc_Enable, .DMA_Mode = DMA_Mode_Circular,
  23. .DMA_PeripheralBaseAddr = (uint32_t) &TIM3->CCR4, .DMA_PeripheralBurst =
  24. DMA_PeripheralBurst_Single, .DMA_PeripheralDataSize =
  25. DMA_PeripheralDataSize_HalfWord, .DMA_PeripheralInc =
  26. DMA_PeripheralInc_Disable, .DMA_Priority = DMA_Priority_Medium };
  27.  
  28. DMA_Init( DMA1_Stream2, &dma_init );
  29. DMA_Cmd( DMA1_Stream2, ENABLE );
  30. TIM_DMACmd( TIM3, TIM_DMA_CC4, ENABLE );
  31. }
  32.  
  33. static void init_buffers( void )
  34. {
  35. for ( int i = ; i < PWM_BUFFER_SIZE; i++ )
  36. {
  37. PWM_Buffer[ i ] = ;
  38. }
  39. for ( int i = ; i < FRAMEBUFFER_SIZE; i++ )
  40. {
  41. ws2812_framebuffer[ i ].red = ;
  42. ws2812_framebuffer[ i ].green = ;
  43. ws2812_framebuffer[ i ].blue = ;
  44. }
  45. }
  46.  
  47. void ws2812_init( )
  48. {
  49. init_buffers( );
  50.  
  51. //InitStructures...
  52. GPIO_InitTypeDef GPIO_InitStructure;
  53. TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
  54. TIM_OCInitTypeDef TIM_OC_InitStructure;
  55. NVIC_InitTypeDef nvic_init;
  56.  
  57. //Clock für GPIO setzen
  58. RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOC, ENABLE );
  59.  
  60. //Clock für TIM4 setzen
  61. RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
  62.  
  63. //GPIO_PIN konfigurieren
  64.  
  65. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  66. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  67. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  68. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  69. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  70. GPIO_Init( GPIOC, &GPIO_InitStructure );
  71.  
  72. //GPIO Alternate function verbinden
  73. GPIO_PinAFConfig( GPIOC, GPIO_PinSource9, GPIO_AF_TIM3 );
  74.  
  75. TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  76. TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  77. TIM_TimeBase_InitStructure.TIM_Period = ;
  78. TIM_TimeBase_InitStructure.TIM_Prescaler = ;
  79. TIM_TimeBaseInit( TIM3, &TIM_TimeBase_InitStructure );
  80.  
  81. TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  82. TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  83. TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
  84. TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  85. TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  86. TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
  87. TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
  88. TIM_OC_InitStructure.TIM_Pulse = ;
  89. TIM_OC4Init( TIM3, &TIM_OC_InitStructure );
  90.  
  91. TIM_CtrlPWMOutputs( TIM3, ENABLE );
  92.  
  93. TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Enable );
  94. TIM_ARRPreloadConfig( TIM3, ENABLE );
  95.  
  96. TIM_CCxCmd( TIM3, TIM_Channel_4, TIM_CCx_Enable );
  97. TIM_Cmd( TIM3, ENABLE );
  98.  
  99. // DMA
  100. RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA1, ENABLE );
  101. TIM_DMACmd( TIM3, TIM_DMA_CC4, ENABLE );
  102. DMA_ITConfig( DMA1_Stream2, DMA_IT_HT, ENABLE );
  103. DMA_ITConfig( DMA1_Stream2, DMA_IT_TC, ENABLE );
  104.  
  105. start_dma( );
  106.  
  107. // NVIC for DMA
  108. nvic_init.NVIC_IRQChannel = DMA1_Stream2_IRQn;
  109. nvic_init.NVIC_IRQChannelPreemptionPriority = ;
  110. nvic_init.NVIC_IRQChannelSubPriority = ;
  111. nvic_init.NVIC_IRQChannelCmd = ENABLE;
  112. NVIC_Init( &nvic_init );
  113. }
  114.  
  115. // writes the pwm values of one byte into the array which will be used by the dma
  116. static inline void color2pwm( uint16_t ** const dest, const uint8_t color )
  117. {
  118. uint8_t mask = 0x80;
  119.  
  120. do
  121. {
  122. if ( color & mask )
  123. {
  124. * *dest = ;
  125. }
  126. else
  127. {
  128. * *dest = ;
  129. }
  130. *dest += ;
  131. mask >>= ;
  132. }while ( mask != );
  133. }
  134.  
  135. void Update_Buffer( uint16_t* buffer )
  136. {
  137. struct led *framebufferp;
  138. uint32_t i, j;
  139. uint16_t * bufp;
  140.  
  141. for ( i = ; i < ( PWM_BUFFER_SIZE / ) / ; i++ )
  142. {
  143. if ( incomplete_return )
  144. {
  145. incomplete_return = ;
  146. for ( j = ; j < ; j++ )
  147. {
  148. buffer[ i * + j ] = ;
  149. }
  150.  
  151. }
  152. else
  153. {
  154. if ( frame_pos == FRAMEBUFFER_SIZE )
  155. {
  156. incomplete_return = ;
  157. frame_pos = ;
  158.  
  159. for ( j = ; j < ; j++ )
  160. {
  161. buffer[ i * + j ] = ;
  162. }
  163. }
  164. else
  165. {
  166. framebufferp = &ws2812_framebuffer[ frame_pos++ ];
  167. bufp = buffer + ( i * );
  168.  
  169. // edit here to change order of colors in "ws2812_framebuffer" (0x00RRGGBB, 0x00GGBBRR, etc)
  170. // the chip needs G R B
  171. color2pwm( &bufp, framebufferp->green ); // green
  172. color2pwm( &bufp, framebufferp->red ); // red
  173. color2pwm( &bufp, framebufferp->blue ); // blue
  174. }
  175. }
  176. }
  177. }
  178.  
  179. void DMA1_Stream2_IRQHandler( void )
  180. {
  181. // Half-Transfer completed
  182. if ( DMA_GetITStatus( DMA1_Stream2, DMA_IT_HTIF2 ) )
  183. {
  184. DMA_ClearITPendingBit( DMA1_Stream2, DMA_IT_HTIF2 );
  185. Update_Buffer( PWM_Buffer );
  186. }
  187.  
  188. // Transfer completed
  189. if ( DMA_GetITStatus( DMA1_Stream2, DMA_IT_TCIF2 ) )
  190. {
  191. DMA_ClearITPendingBit( DMA1_Stream2, DMA_IT_TCIF2 );
  192. Update_Buffer( PWM_Buffer + ( PWM_BUFFER_SIZE / ) );
  193. }
  194.  
  195. }

stm-ledstrip : Driver and test routine for WS2811 RGB-LED的更多相关文章

  1. 0xWS2812 STM32 driver for WS2812(B) RGB LEDs

    0xWS2812 STM32 driver for WS2812(B) RGB LEDs 0xWS2812 pronounced "hex-WS2812" This code ai ...

  2. kernel/printk.c

    /* *  linux/kernel/printk.c * *  Copyright (C) 1991, 1992  Linus Torvalds * * Modified to make sys_s ...

  3. 关于IoCallDriver

    通常我们所知IoCallDriver是把irp传递给下一层设备,传递到底是什么意思呢?IoCallDriver中实际调用了IopfCallDriver,其代码如下:NTSTATUSFORCEINLIN ...

  4. IRP小结 0x01 IRP & IO_STACK_LOCATION(结合WRK理解)

    写博客整理记录一下IRP相关的知识点,加深一下印象. 所有的I/O请求都是以IRP的形式提交的.当I/O管理器为了响应某个线程调用的的I/O API的时候,就会构造一个IRP,用于在I/O系统处理这个 ...

  5. tiny4412 串口驱动分析七 --- log打印的几个阶段之内核启动阶段(earlyprintk)

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

  6. linux内核中mtd架构分析

    一. 引言 MTD(memory technology device内存技术设备)是用于访问memory设备(RAM.ROM.flash)的Linux的子系统.MTD的主要目的是为了使新的memory ...

  7. Device Drivers

    Types of Device Drivers Windows可能会有User-mode的驱动,但是我们只关注Kernel-Mode的驱动. WDM Drivers WDM是一种驱动模型,是比较常用的 ...

  8. linux内核更新前后配置文件的比较

    说明:这里先给出一个比较的结果,作为记录,后续会给出内核配置差异的详细解释. [root@xiaolyu linux-4.7.2]# diff .config .config_bak  3c3< ...

  9. linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxx ...

随机推荐

  1. 用于阻止缓冲区溢出攻击的 Linux 内核参数与 gcc 编译选项

    先来看看基于 Red Hat 与 Fedora 衍生版(例如 CentOS)系统用于阻止栈溢出攻击的内核参数,主要包含两项: kernel.exec-shield 可执行栈保护,字面含义比较“绕”, ...

  2. 【转载】chmod命令详解

    查看linux文件的权限:ls -l 文件名称 查看linux文件夹的权限:ls -ld 文件夹名称(所在目录) 修改文件及文件夹权限: sudo chmod -(代表类型)×××(所有者)×××(组 ...

  3. 初始ASP.NET数据控件【续 ListView】

    ListView控件   ListView控件可以用来显示数据,它还提供编辑,删除,插入,分页与排序等功能.ListView是GridView与DataList的融合体,它具有GridView控件编辑 ...

  4. (windows下)安装mysql

    一.先从mysql的官网上下载对应版本的mysql zip包(适用于windows下的) 二.解压zip包放到自定义的文件夹下(我放的是e盘,路径为E:\mysql-5.6.40-winx64) 三. ...

  5. 【前端vue开发】vue知识点超链接学习笔记

    1.如何去除vue项目中的 # --- History模式: https://www.cnblogs.com/zhuzhenwei918/p/6892066.html 2.三分钟教你写个Vue组件: ...

  6. DOM文档对象模型简介

    DOM简介     DOM是W3C(万维网联盟)的标准 "W3C文档对象模型DOM是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容.结构.样式".W3C DOM ...

  7. Web前端开发规范文档你需要知道的事

    Web前端开发规范文档你需要知道的事 规范目的 为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档. 本规范文档一经确认, 前端开发人员必须按本文档规范进 ...

  8. C++ code:动态内存

    C++给我们提供了动态内存分配的new和delete操作.一般而论,new和delete操作多用在内存需求捉摸不定的场合.然而,需要处理的数据,如果变动范围很小,我们可以用STL中通用型的容器来做,大 ...

  9. MFC命名规范

    属性部分 全局变量:g_ 常量:c_ c++类成员变量:m_ 静态变量:s_ 类型部分 指针:p 函数:fn 无效:v 句柄:h 长整型:l 布尔:b 浮点型(有时也指文件):f 双字:dw 字符串: ...

  10. vs2010 快捷键

    我自己的快捷键: visual studio 2010快捷键: visual studio 2010快捷键: 强迫智能感知:Ctrl+J撤销:Ctrl+Z强迫显示参数信息:Ctrl+Shift+空格重 ...