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

#include "ws2812.h"
#include <stm32f4xx.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_tim.h>
#include <stm32f4xx_dma.h> static uint16_t PWM_Buffer[ PWM_BUFFER_SIZE ];
uint32_t frame_pos = ;
int incomplete_return = ; void Update_Buffer( uint16_t* buffer ); static void start_dma( void )
{
static DMA_InitTypeDef dma_init =
{ .DMA_BufferSize = PWM_BUFFER_SIZE, .DMA_Channel = DMA_Channel_5, .DMA_DIR =
DMA_DIR_MemoryToPeripheral, .DMA_FIFOMode = DMA_FIFOMode_Disable,
.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull, .DMA_Memory0BaseAddr =
(uint32_t) PWM_Buffer, .DMA_MemoryBurst = DMA_MemoryBurst_Single,
.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord, .DMA_MemoryInc =
DMA_MemoryInc_Enable, .DMA_Mode = DMA_Mode_Circular,
.DMA_PeripheralBaseAddr = (uint32_t) &TIM3->CCR4, .DMA_PeripheralBurst =
DMA_PeripheralBurst_Single, .DMA_PeripheralDataSize =
DMA_PeripheralDataSize_HalfWord, .DMA_PeripheralInc =
DMA_PeripheralInc_Disable, .DMA_Priority = DMA_Priority_Medium }; DMA_Init( DMA1_Stream2, &dma_init );
DMA_Cmd( DMA1_Stream2, ENABLE );
TIM_DMACmd( TIM3, TIM_DMA_CC4, ENABLE );
} static void init_buffers( void )
{
for ( int i = ; i < PWM_BUFFER_SIZE; i++ )
{
PWM_Buffer[ i ] = ;
}
for ( int i = ; i < FRAMEBUFFER_SIZE; i++ )
{
ws2812_framebuffer[ i ].red = ;
ws2812_framebuffer[ i ].green = ;
ws2812_framebuffer[ i ].blue = ;
}
} void ws2812_init( )
{
init_buffers( ); //InitStructures...
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
TIM_OCInitTypeDef TIM_OC_InitStructure;
NVIC_InitTypeDef nvic_init; //Clock für GPIO setzen
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOC, ENABLE ); //Clock für TIM4 setzen
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); //GPIO_PIN konfigurieren GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init( GPIOC, &GPIO_InitStructure ); //GPIO Alternate function verbinden
GPIO_PinAFConfig( GPIOC, GPIO_PinSource9, GPIO_AF_TIM3 ); TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBase_InitStructure.TIM_Period = ;
TIM_TimeBase_InitStructure.TIM_Prescaler = ;
TIM_TimeBaseInit( TIM3, &TIM_TimeBase_InitStructure ); TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OC_InitStructure.TIM_Pulse = ;
TIM_OC4Init( TIM3, &TIM_OC_InitStructure ); TIM_CtrlPWMOutputs( TIM3, ENABLE ); TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Enable );
TIM_ARRPreloadConfig( TIM3, ENABLE ); TIM_CCxCmd( TIM3, TIM_Channel_4, TIM_CCx_Enable );
TIM_Cmd( TIM3, ENABLE ); // DMA
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA1, ENABLE );
TIM_DMACmd( TIM3, TIM_DMA_CC4, ENABLE );
DMA_ITConfig( DMA1_Stream2, DMA_IT_HT, ENABLE );
DMA_ITConfig( DMA1_Stream2, DMA_IT_TC, ENABLE ); start_dma( ); // NVIC for DMA
nvic_init.NVIC_IRQChannel = DMA1_Stream2_IRQn;
nvic_init.NVIC_IRQChannelPreemptionPriority = ;
nvic_init.NVIC_IRQChannelSubPriority = ;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &nvic_init );
} // writes the pwm values of one byte into the array which will be used by the dma
static inline void color2pwm( uint16_t ** const dest, const uint8_t color )
{
uint8_t mask = 0x80; do
{
if ( color & mask )
{
* *dest = ;
}
else
{
* *dest = ;
}
*dest += ;
mask >>= ;
}while ( mask != );
} void Update_Buffer( uint16_t* buffer )
{
struct led *framebufferp;
uint32_t i, j;
uint16_t * bufp; for ( i = ; i < ( PWM_BUFFER_SIZE / ) / ; i++ )
{
if ( incomplete_return )
{
incomplete_return = ;
for ( j = ; j < ; j++ )
{
buffer[ i * + j ] = ;
} }
else
{
if ( frame_pos == FRAMEBUFFER_SIZE )
{
incomplete_return = ;
frame_pos = ; for ( j = ; j < ; j++ )
{
buffer[ i * + j ] = ;
}
}
else
{
framebufferp = &ws2812_framebuffer[ frame_pos++ ];
bufp = buffer + ( i * ); // edit here to change order of colors in "ws2812_framebuffer" (0x00RRGGBB, 0x00GGBBRR, etc)
// the chip needs G R B
color2pwm( &bufp, framebufferp->green ); // green
color2pwm( &bufp, framebufferp->red ); // red
color2pwm( &bufp, framebufferp->blue ); // blue
}
}
}
} void DMA1_Stream2_IRQHandler( void )
{
// Half-Transfer completed
if ( DMA_GetITStatus( DMA1_Stream2, DMA_IT_HTIF2 ) )
{
DMA_ClearITPendingBit( DMA1_Stream2, DMA_IT_HTIF2 );
Update_Buffer( PWM_Buffer );
} // Transfer completed
if ( DMA_GetITStatus( DMA1_Stream2, DMA_IT_TCIF2 ) )
{
DMA_ClearITPendingBit( DMA1_Stream2, DMA_IT_TCIF2 );
Update_Buffer( PWM_Buffer + ( PWM_BUFFER_SIZE / ) );
} }

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. 利用itertools生成密码字典,多线程撞库破解rar压缩文件密码

    脚本功能: 利用itertools生成密码字典(迭代器形式) 多线程并发从密码字典中取出密码进行验证 验证成功后把密码写入文件中保存 #!/usr/bin/env python # -*- codin ...

  2. WIN10文件无法自动刷新问题解决方法

    Window10系统有时候会遇到以下类似的问题 1.文件删除后,图标还在,无法自动刷新屏幕,按F5或右键菜单刷新后才消失 2.文件粘贴后,不显示,刷新后才显示 3.回收站清理后,文件图标仍显示有垃圾 ...

  3. MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇

    Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide 一 MyISAM 1.1 My ...

  4. linux 查看有哪些service

    一.利用进程来查看命令里 ps -aux | grep xxx 是查看某个进程或者服务是否存在.二.利用chkconfig配置工具chkconfig --list 可以列出所有的服务在各个runlev ...

  5. 【Python】测试dpkt解析pcap

    1.前言 本想借助dpkt解析mail.dns.http来辅助分析pcap包进行分析,查阅资料学习却发现并不如使用scapy那么方便. dpkt是一个python模块,可以对简单的数据包创建/解析,以 ...

  6. C++获取文件夹下所有文件名

    查找文件需要一个结构体和几个函数.结构体为struct _finddata_t,函数为_findfirst.findnext和_findclose. struct _finddata_t 这个结构体是 ...

  7. Android实现手机摄像头的自动对焦

    如何实现Android相机的自动对焦,而且是连续自动对焦的.当然直接调用系统相机就不用说了,那个很简单的.下面我们主要来看看如如何自己实现一个相机,并且实现自动连续对焦. 代码如下: public c ...

  8. 证书(Certificate)与描述文件(Provisioning Profiles)

    在使用脚本xcodebuild自动打包的时候,会用到签名证书和描述文件,我在编译的时候搞了好长时间才搞明白,下面介绍如何得到正确配置. 证书:证书是用来给应用程序签名的,只有经过签名的应用程序才能保证 ...

  9. Grafana 短信报警

    一.分析 需求 Grafana支持短信渠道报警 要求 使用开发提供的短信API接口 请求url: http://192.168.1.1:8088/alerting/sendSms?mobile=手机号 ...

  10. 一步一步学习IdentityServer3 (4)

    其实上述例子 很多都很找到 但是在实际生态环境中给例子有很多不一样的地方 比如自定已登录界面怎么做? 怎么访问自己的用户数据库实现登录? 怎么在接口中使用,在接口中又怎么实现与Idr3结合授权? 等等 ...