nRF52832 SK6812 LEDs displaying incorrect colors

I have a board with the nRF52832 and a board with 12 SK6812 LEDs on it in the shape of a ring.  I have code that sometimes will display the correct color on the ring but other times the colors are off.  I am using nRF Connect SDK 2.6.1

I have functionality so that I can send UART commands into the device to make the LED ring, solid red, solid green, etc.

I am using the SPI method of interacting with the LEDs.

I hooked up the my Saleae Logic analyzer to monitor the data line used for the LEDs.  First is what I saw with the LED ring being all red (correct).

I would expect that the data communication to update the LED would be one either block but it looks like something might be interrupting the operation. 

In this case, it looks like whatever interrupted the led_strip_update_rgb() was short enough that the gap (approximately 25 micro seconds) was not mistaken as the result timing gap required per the operation of the LEDs. The reset code listed on the SK6812 datasheet is listed as 80 uSecs.

Here is the Saleae capture if it would be of any use.

ring red correct.sal

Here is a picture of the LED ring when it should have been all red but instead the first two LEDs were lit green and rest were all red.

Here is a screenshot of a capture from the Saleae Logic analyzer where there was a much larger gap of 747 uSecs.  The LED ring had the first two LEDs as green and the rest of the ring was red.

Again here is the Saleae data if  useful.

ring red incorrect.sal

Here is the datasheet for the SK6812.

2451.SK6812+LED+datasheet+.pdf

I did see the following post, https://devzone.nordicsemi.com/f/nordic-q-a/78819/ncs-zephyr-ws2812-interrupt-activity----turn-off-bluetooth-radio/326153, which describes a similar issue that LEDs they were using were not working when also utilizing Bluetooth.  I have not attempted to the timeslot method for updating the LED ring yet. 

I can't tell with the LED_STRIP functionality if there is a way to change priorities so that the led_strip_update_rgb() can run without being interrupt by other functionality.

Just looking for any advice if others have experienced similar issues.

Parents
  • Hello,

    In the devicetree file can you confirm you are using compatible = "nordic,nrf-spim"; (and not compatible = "nordic,nrf-spi";).

    Kenneth

  • Hello,

    Here is what I have in my .overlay file.

    &arduino_spi { /* MOSI on D11 / P0.23 */
        status = "okay";
        compatible = "nordic,nrf-spim";
        led_strip: ws2812@0 {
            compatible = "worldsemi,ws2812-spi";

            /* SPI */
            reg = <0>; /* ignored, but necessary for SPI bindings */
            spi-max-frequency = <SPI_FREQ>;

            /* WS2812 */
            chain-length = <12>; /* arbitrary; change at will */
            color-mapping = <LED_COLOR_ID_GREEN
                     LED_COLOR_ID_RED
                     LED_COLOR_ID_BLUE>;
            spi-one-frame = <ONE_FRAME>;
            spi-zero-frame = <ZERO_FRAME>;
        };

        // rx-delay-supported;
    };
    &spi2_default {
        group1 {
            psels = <NRF_PSEL(SPIM_MOSI, 0, 8)>,
            <NRF_PSEL(SPIM_MISO, 0, 23)>,
            <NRF_PSEL(SPIM_SCK, 0, 24)>;

        };
    };
    &spi2_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_MOSI, 0, 8)>,
            <NRF_PSEL(SPIM_MISO, 0, 23)>,
              <NRF_PSEL(SPIM_SCK, 0, 24)>;

        };
    };

    Here is what the overlay file looks like

    I experimented with enabling and disabling anomaly-58-workaround and rx-delay-supported but neither seemed to fix the issue.

  • Hi, 

    Can you try set CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=255, I believe it by default is 8.

    Kenneth

  • Hello,

    I did try adding CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=255 but I still see the same behavior where the LEDs are not the correct color. .

    Looking at .config file, I see the following.

    CONFIG_NRFX_SPI=y
    # CONFIG_NRFX_SPI0 is not set
    CONFIG_NRFX_SPI1=y
    CONFIG_NRFX_SPIM=y
    CONFIG_NRFX_SPIM2=y

    CONFIG_HAS_HW_NRF_SPI1=y
    CONFIG_HAS_HW_NRF_SPIM2=y

    # CONFIG_SPI_ASYNC is not set
    # CONFIG_SPI_RTIO is not set
    # CONFIG_SPI_SLAVE is not set
    # CONFIG_SPI_EXTENDED_MODES is not set
    CONFIG_SPI_INIT_PRIORITY=70
    CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE=200
    # CONFIG_SPI_LOG_LEVEL_OFF is not set
    # CONFIG_SPI_LOG_LEVEL_ERR is not set
    # CONFIG_SPI_LOG_LEVEL_WRN is not set
    # CONFIG_SPI_LOG_LEVEL_INF is not set
    # CONFIG_SPI_LOG_LEVEL_DBG is not set
    CONFIG_SPI_LOG_LEVEL_DEFAULT=y
    CONFIG_SPI_LOG_LEVEL=3
    CONFIG_SPI_NRFX=y
    CONFIG_SPI_NRFX_SPI=y
    CONFIG_SPI_NRFX_SPIM=y
    CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58=y
    CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=255
    CONFIG_SPI_NRFX_WAKE_TIMEOUT_US=200

    # CONFIG_LED is not set
    CONFIG_LED_STRIP=y
    # CONFIG_LED_STRIP_LOG_LEVEL_OFF is not set
    # CONFIG_LED_STRIP_LOG_LEVEL_ERR is not set
    # CONFIG_LED_STRIP_LOG_LEVEL_WRN is not set
    # CONFIG_LED_STRIP_LOG_LEVEL_INF is not set
    CONFIG_LED_STRIP_LOG_LEVEL_DBG=y
    # CONFIG_LED_STRIP_LOG_LEVEL_DEFAULT is not set
    CONFIG_LED_STRIP_LOG_LEVEL=4
    CONFIG_LED_STRIP_INIT_PRIORITY=90
    CONFIG_LED_STRIP_RGB_SCRATCH=y
    # CONFIG_LPD880X_STRIP is not set
    CONFIG_WS2812_STRIP=y
    CONFIG_WS2812_STRIP_SPI=y
    # CONFIG_APA102_STRIP is not set
    # CONFIG_TLC5971_STRIP is not set
    # CONFIG_LORA is not set
    # CONFIG_MDIO is not set

    Using UART commands, I attempted to change the LED ring all red, then blue, then green as a demonstration. 

  • Any way you can share a simple project I  an unzip and compilr here? I think somehere(e.g. driver) the data is fragmented, because when using spim with a large enough buffer there is really nothing that can pause that sequence once started. So likely somewhere it’s not written as one transfer, but split into smaller transfers or only partially combined in small transfers.

    Kenneth

Reply
  • Any way you can share a simple project I  an unzip and compilr here? I think somehere(e.g. driver) the data is fragmented, because when using spim with a large enough buffer there is really nothing that can pause that sequence once started. So likely somewhere it’s not written as one transfer, but split into smaller transfers or only partially combined in small transfers.

    Kenneth

Children
No Data
Related