element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Enchanted Objects
  • Challenges & Projects
  • Design Challenges
  • Enchanted Objects
  • More
  • Cancel
Enchanted Objects
Blog Use WS2812B on the SAMA5D4 Xplained
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: crjeder
  • Date Created: 9 Jun 2015 5:54 AM Date Created
  • Views 1309 views
  • Likes 3 likes
  • Comments 5 comments
  • sama5
  • sama5d4
  • atmel_sama
  • smart_key_hooks
  • asf
  • enchanted_objects
  • ws2812b
  • xplained
Related
Recommended

Use WS2812B on the SAMA5D4 Xplained

crjeder
crjeder
9 Jun 2015

More Details on the WS2812B

 

The mysterious signal from my previous post was for a WS2812B LED. It was shown in Fairy Dust has arrived!. It is a RGB LED with integrated controller. The LEDs can be easily chained together:

 

image

If you are really crazy you can build something like this with those:

 

IMG_7806.jpg

With an estimated power draw of 3 KW image and 10.000 WS2812 LEDs this is really insane.

 

But back to the lab:

Besides of the power supply the LEDs use only a single pin for data transfer. The data is transmitted bit-wise by the "mysterious signall" with 8 bit per RGB but in GRB order (for whatever reason). After the last LED a reset signal is sent to start all over again. This is shown in the graph from the datasheet:

 

image

mcb1 pointed me to a link which gives valuable insight into the timing constraints of the protocol. Bottom line: The timing does not matter much as long as you can make sure that around the middle of the period the DIN line has the correct signal applied. No fancy assembly code needed and no high clock frequencies.

 

PWM Implementation of the WS2812B Protocol

 

The Basic flow is straight forward:

image

 

PWM on the SAMA5D4 Xplained

 

There are several options to programm the board. Those I evaluated are (form highest abstraction to lowest):

 

  • Linux driver and API
  • Atmel Software Framework (ASF)
  • Low level GPL API by Atmel

 

The Linux driver does not support any kind of signaling the end of the period. More capable and less abstract is ASF but AFAIK SAMA5 series is not (yet) supported. So back to the ground level and (allmost) manually programm the registers using the GPL API. The following part of the C-code is heavily commented with information from (mainly) the datasheet. It is not yet ready and definitely not tested. But as it has taken me so long to find all this information it is time to publish it anyway:

 

/****
* PWM Initialization
* ------------------
*
* Before using the PWM macrocell, the programmer must first enable the
* peripheral clock in the Power Management Controller (PMC).
  ****/
    PMC_EnablePeripheral(ID_PWM);
    /* Disable to configure the first PWM channel */
    PWMC_DisableChannel(PWM, EXAMPLE_PWM_CHANNEL_INDEX0);

/****
* Before enabling the channels, they must be configured by the software
* application as described below: (p 1466)
* - Unlock User Interface by writing the WPCMD field in the PWM_WPCR.
****/
    PWM.PWM_WPCR |= PWM_WPCR_WPCMD;
/****
* - Configuration of the clock generator (DIVA, PREA, DIVB, PREB in the
*   PWM_CLK register if required).
****/
    mode = PWM_CLK_PREA() | (PWM_CLK_DIVA()); // require 2.4 MHz
    PWMC_ConfigureClocks(PWM, mode);
/****
* - Selection of the clock for each channel (CPRE field in PWM_CMRx)
****/
    mode = 0; // Begin configuring the CPRE register
    mode |= PWM_CMR_CPRE(PWM_CMR_CPRE_CLKA);
/****
* - Configuration of the waveform alignment for each channel
*   (CALG field in PWM_CMRx)
****/
    mode |= !PWM_CMR_CALG; // left alligned
/****
* - Selection of the counter event selection (if CALG = 1) for each
*   channel (CES field in PWM_CMRx)
****/
    mode |= !PWM_CMR_CES; // Don't care since CALG = 0
/****
* - Configuration of the output waveform polarity for each channel
*   (CPOL bit in PWM_CMRx)
  ****/
    mode |= PWM_CMR_CPOL;
    PWM.PWM_CH_NUM[0].PWM_CMR = mode; // Write CMR register
/****
* - Configuration of the period for each channel (CPRD in the
*   PWM_CPRDx register). Writing in PWM_CPRDx register is possible
*   while the channel is disabled. After validation of the channel, the
*   user must use PWM_CPRDUPDx register to update PWM_CPRDx as
*   explained below.
*   Source Clock Selection Criteria (p 1467):
* -- The event number written in the Period Register gives the PWM
*    accuracy. The Duty-Cycle quantum cannot be lower than 1/CPRDx
*    value. The higher the value of PWM_CPRDx, the greater the
*    PWM accuracy.
  ****/
    PWM.PWM_CH_NUM[0].PWM_CPRD |= PWM_CPRD_CPRD(3); // Period length
/****
* - Configuration of the duty-cycle for each channel (CDTY in the
*   PWM_CDTYx register). Writing in PWM_CDTYx register is possible
*   while the channel is disabled. After validation of the channel, the
*   user must use PWM_CDTYUPDx register to update PWM_CDTYx as
*   explained below.
  ****/
    PWM.PWM_CH_NUM[0].PWM_CDTY |= PWM_CDTY_CDTY(0);
/****
* - Configuration of the dead-time generator for each channel (DTH and
*   DTL in PWM_DTx) if enabled (DTE bit in the PWM_CMRx). Writing in
*   the PWM_DTx register is possible while the channel is disabled.
*   After validation of the channel, the user must use PWM_DTUPDx
*   register to update PWM_DTx
  ****/
/****
* - Selection of the synchronous channels (SYNCx in the PWM_SCM
*   register)
  ****/
    PWM.PWM_SCM |= PWM_SCM_SYNC0;
/****
* - Selection of the moment when the WRDY flag and the corresponding
*   DMA transfer request are set (PTRM and PTRCS in the PWM_SCM
*   register)
*
*      PTRM = 0 => DMA transfer request and WRDY are set to ‘1’ as soon as
*   the update period is elapsed
  ****/
    PWM.PWM_SCM |= PWM_SCM_PTRM;
/****
* - Configuration of the update mode (UPDM in PWM_SCM register)
  ****/
    PWM.PWM_SCM |= PPWM_SCM_UPDM_MODE1;
/****
* - Configuration of the update period (UPR in PWM_SCUP register)
*   if needed
  ****/
    PWM.PWM_SCUP = PWM_SCUP_UPR(0); // UPR = 0 -> update every period
/****
* - Configuration of the comparisons (PWM_CMPVx and PWM_CMPMx)
  ****/
    //PWM.PWM_CH_NUM[0] =
/****
* - Configuration of the event lines (PWM_ELMRx)
  ****/
    PWM.PWM_ELMR |= PWM.PWM_ELMR_CSEL0;
/****
* - Configuration of the fault inputs polarity (FPOL in PWM_FMR)
  ****/
    // Unused
/****
* - Configuration of the fault protection (FMOD and FFIL in PWM_FMR,
*   PWM_FPV and PWM_FPE1)
  ****/
    // Unused
/****
* - Enable of the Interrupts (writing CHIDx and FCHIDx in PWM_IER1, and
*   writing WRDYE, ENDTXE,TXBUFE, UNRE, CMPMx and CMPUx in PWM_IER2)
  ****/
    PWM.PWM_IER1 |= PWM_IER1_CHID0;
    PWM.PWM_IER2 |= PWM_IER2_WRDY;
    //PWMC_EnableChannelIt(*PWM, 0); //PWM_IER1 (same?)
/****
* - Enable of the PWM channels (writing CHIDx in the PWM_ENA register)
****/
    PWMC_EnableChannel(PWM, EXAMPLE_PWM_CHANNEL_INDEX0);

 

This is only the setup part, I have still to find out how to calculate the clock frequency / how to programm prescaler and divider to produce a 2.4 MHz PWM signal.

For the beginning I will poll the WRDY signal to find the end of the period an update the CDTY (duty) register manually. For better (multi-tasking) performance I want to update CDTY in the PWM_IrqHandler (interupt handler).

  • Sign in to reply

Top Comments

  • Workshopshed
    Workshopshed over 10 years ago +2
    Ah yes, the scheduling is not very friendly, seems to be a mixture of European and American date formats.
  • iayanpahwa
    iayanpahwa over 10 years ago +1
    Interesting blog! Thanks for sharing
  • clem57
    clem57 over 10 years ago +1
    Great after yesterday's mystery blog. I will have to try this one. Thanks, Clem
  • clem57
    clem57 over 10 years ago

    Great after yesterday's mystery blog. I will have to try this one.

    Thanks,

    Clem

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • crjeder
    crjeder over 10 years ago in reply to iayanpahwa

    Thank You!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • iayanpahwa
    iayanpahwa over 10 years ago

    Interesting blog! Thanks for sharing

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Workshopshed
    Workshopshed over 10 years ago

    Ah yes, the scheduling is not very friendly, seems to be a mixture of European and American date formats.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • crjeder
    crjeder over 10 years ago

    I wanted this blog post to be automatically published yesterday at 22:30 but that did not work. More practice needed...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube