CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

WS2812B SPI

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bschriek



Joined: 18 Dec 2007
Posts: 76

View user's profile Send private message Send e-mail

WS2812B SPI
PostPosted: Tue Dec 04, 2018 1:45 pm     Reply with quote

I have modified and simplified the code to control a WS2812B RGB ledstrip.
I started with the Microchip AN1890 application and many hours later it works fine!
For me it's important to understand the code rather than an optimized code.
But now I have a question concerning the SPI function.
My idea was to replace all original SPI actions by the latest spi_xfer funtion.
But there are still some piece of old codes I can't replace.

1) Is this right code before CS goes high?
Code:
dummy=spi_xfer(SRAM, 0x00);   // Ensure the second transfer has completed.
SRAM_CS_PIN = 1;              // Disable the external SRAM

2) want to get rid of !SSP1IF because the spi_xfer doesn't need this (I think)
Code:

{
 while (!SSP1IF);     // Wait until transmission is complete
 SSP1IF = 0;
 c = SSP1BUF;         // receive byte from SRAM
 SSP1BUF = c;         // transmit byte to LEDs
 --count;
}

Just your suggestions concerning the SPI code.
Enjoy the WS2812B ledstrip code for Dummies like myself.


Last edited by bschriek on Tue Dec 04, 2018 1:52 pm; edited 2 times in total
bschriek



Joined: 18 Dec 2007
Posts: 76

View user's profile Send private message Send e-mail

PostPosted: Tue Dec 04, 2018 1:47 pm     Reply with quote

Code:

// PCW compiler 5.078
// WS2812B led strip
// Microchip AN1890 logic cell settings and schematic.
#include <16F1509.H>
#Fuses INTRC_IO,ECL,ECM,ECH,NOWDT,PUT,NOMCLR,NOPROTECT,NOBROWNOUT,NOCLKOUT,IESO,FCMEN,NOLVP
#use delay(clock=16000000)
#use spi(Master, MODE=0, SPI1, STREAM = SRAM)

void BufferToLEDs(int16 address, int16 count);

#define LEDS_IN_STRING 10                    // Number of LEDs that you are driving
#define WRITE_CMD 0x02
#define READ_CMD  0x03

int8   c,j, dummy;
int16  index;

#include <Config.c>

void main(void)
      {
      setup_oscillator(OSC_16MHZ);
      setup_comparator(NC_NC_NC_NC);
      setup_dac(DAC_OFF);
      setup_adc_ports(No_analogs|VSS_VDD);   //
      setup_vref(VREF_OFF | VREF_COMP_DAC_OFF | TEMPERATURE_INDICATOR_DISABLED);
      //setup_adc(ADC_CLOCK_DIV_2);
      //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);                               // 16.000.000/4/64
      PORT_a_PULLUPS(00000000);              // (1=enabled)
      //PORT_b_PULLUPS(00000000);            // (1=enabled)
      PORT_c_PULLUPS(00000000);              // (1=enabled)
      //DISABLE_INTERRUPTS(PERIPH);          //
      //DISABLE_INTERRUPTS(GLOBAL);

      SET_TRIS_A(0b11001011);                // RA5, RA4, RA2 are outputs.
      SET_TRIS_B(0b00111111);                // RB7, RB6, als are outputs.
      SET_TRIS_C(0b01001011);                // RC7, RC4, RC2 are outputs.     // RC5 = PWM1 output

      output_high(pin_C2);                   // LED, optional
      delay_ms(100);
      output_low(pin_C2);                    // LED, optional
      delay_ms(100);

      output_low(Pin_A4);                    // P-MOSFET to switch-on 5V power to WS2812B ledstrip

      SRAM_CS_PIN  = 1;                      // Disable the external SRAM
///////////////////////////// WS2811_Init /////////////////////////////////////
      CLC2GLS0 = 0x20;                       //0b0010 0000;     
      CLC2GLS1 = 0x00;                       //0b0000 0000;
      CLC2GLS2 = 0x00;                       //0b0000 0000;
      CLC2GLS3 = 0x00;                       //0b0000 0000;
      CLC2SEL0 = 0x00;                       //0b0000 0000;
      CLC2SEL1 = 0x06;                       //0b0000 0110;
      CLC2POL =  0x0E;                       //0b0000 1110; 
      CLC2CON =  0x82;                       //0b1000 0010;
// Register values as copied from CLC Designer Tool. PWM1 comes through CLC2
      CLC4GLS0  = 0x02;
      CLC4GLS1  = 0xA4;
      CLC4GLS2  = 0x00;
      CLC4GLS3  = 0x90;
      CLC4SEL0  = 0x54;
      CLC4SEL1  = 0x05;
      CLC4POL   = 0x0A;
      CLC4CON   = 0xC5;
//                     
      setup_timer_2(T2_DIV_BY_1, 2, 1);                           // pwm duty van 0 tot 11, 6=50%   12=100%          // 16.000.000/4/1/2 = ????
      setup_pwm1(PWM_ENABLED | PWM_ACTIVE_HIGH | PWM_OUTPUT);     // TP = 750nSec en Th = 375nSec bij d=6 (50% duty cycle)
      set_pwm1_duty (6);                                          // 2TP = 1.5µSec en Th = 375nSec bij d=6
      SETUP_SPI(SPI_MASTER|SPI_SCK_IDLE_HIGH|SPI_CLK_T2|SPI_SS_DISABLED|SPI_XMIT_L_TO_H); //
////////////////////////////// FillSRAMBuffer /////////////////////////////////
      CLC4CONbitsLC4EN = 0;                          // SRAM Mode
      SRAM_CS_PIN = 0;                               // Enable the external SRAM
      spi_xfer(SRAM, WRITE_CMD, 8);                  // send write command 0x02
      spi_xfer(SRAM, 0, 16);                         // send address 0x00      16bit because of 512 SRAM
      for   (j = 0; j < 10; ++j)                     // SRAM pos 0x00 to 0x09
            {
            spi_xfer(SRAM,0x030303,24);              // send RGB
            }
      for   (j = 0; j < 2; ++j)                      // SRAM pos 0c09 to 0x0B
            {
            spi_xfer(SRAM,0x0F0000,24);              // send RGB  Green 
            }
      for   (j = 0; j < 2; ++j)                      // SRAM pos
            {
            spi_xfer(SRAM,0x000F00,24);              // send RGB  Red
            }
      for   (j = 0; j < 2; ++j)                      // SRAM pos
            {
            spi_xfer(SRAM,0x00000F,24);              // send RGB  Blue
            }
      for   (j = 0; j < 250; ++j)                    // SRAM pos  (in case of long led strip)
            {
            spi_xfer(SRAM,0x0F0F0F,24);              // send RGB 
            }
      dummy=spi_xfer(SRAM, 0x00);                    // Ensure the second transfer has completed, before raising CS     
      SRAM_CS_PIN = 1;                               // Disable the external SRAM
///////////////////////////////// MAIN LOOP ///////////////////////////////////
      while (1)
            {
            for  (index = 0; index < 51 ; index += 3)           //  0 to 16 (17 steps) is the amount of different steps before it starts all over again.
                 {                                              //  Index (0 to 48) is the amount of different steps before it starts all over again.
                 BufferToLEDs(index, LEDS_IN_STRING * 3);
                 delay_ms(1000); 
                 output_toggle(pin_A2);                         // LED, alive sign
                 }
            }
      }
//--------------------------- SRAMtoLED ---------------------------------------
/*    Receives a byte from the SRAM via SPI at the same time that a byte is being transmitted to the LEDs.
      The received byte is immediately transmitted. This results in a 1-byte lag between the SRAM and the LEDs.
      Make sure you send a dummy byte to allow reception of the first SRAM byte before enabling transmission to the LEDs

      Special Note:  Because this uses the interrupt flag bit as an indication of when the transmission is complete,
      the SSP1IF flag MUST be set by software before the first time this function is called.

      Also, if any modes are changed (SPI mode, etc) after this function is called, the byte being transmitted must be
      allowed to complete before invoking any mode changes, otherwise, the byte may be lost. */
//------------------------------- BufferToLEDs --------------------------------
void  BufferToLEDs(int16 address, int16 count)
      {
      CLC4CONbitsLC4EN = 0;                          // SRAM Mode

      SRAM_CS_PIN = 0;                               // Enable the external SRAM
      spi_xfer(SRAM, READ_CMD, 8);                   // send read command
      spi_xfer(SRAM,address,16);                     // send SRAM address byte 
      spi_xfer(SRAM,0x00,8);                         // send 1 byte to solve 1-byte lag between SRAM and LEDS
         
      CLC4CONbitsLC4EN = 1;                          // LedMode
     
      while  (count > 0)
             {
             while (!SSP1IF);                        // Wait until transmission is complete, then bit becomes "0".
             SSP1IF = 0;
             c = SSP1BUF;                            // receive byte from SRAM
             SSP1BUF = c;                            // transmit byte to LEDs
//-----------------------------------
//             dummy=spi_xfer(SRAM, 8);              // Replace by this code but it doesn't work.
//             spi_xfer(SRAM, dummy, 8);             // Replace by this code but it doesn't work.
//-----------------------------------
             --count;
             }
      dummy=spi_xfer(SRAM, 0x00);                    // Ensure the second transfer has completed, before raising CS
      SRAM_CS_PIN = 1;                               // Disable the external SRAM
      }
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group