Evening,
I've been working on a very simple way for the the TIVA C to use NeoPixels just using a standard GPIO port and just using SysCtlDelay()
To drive the neopixels I need to have have output pulses in the 100s of ns (400 for the lowest pulse).
a bit "1" is 800ns on 450ns off && a bit "0" is 400ns on and 850ns off
The neopixels themselves only run off of 800kHz (which shouldn't be a stretch for a 120MHz board). 8 bits for each colour, 24 per pixel.
The key part is getting down to the 400ns mark for the 'off' pulse (in my code as Pixel_Low function). I have tried timers and other delay methods to no avail.
I have set my clock to 120MHz (I'm fairly sure...) which will give me clock cycles of 8.3ns
Using the SysCltDelay() this should delay the device for a few clock cycles (i'd guess around 3-5?) giving me a delay of around 40ns (a guess really), but not as large as it is currently giving me.
So why wont my output give me anything less than 1.3us? Is my clock not set right? Is SysCtlDelay running off of a different clock? At the moment all I am getting is full brightness on all the pixels, as its not recognising any '0' that i'm sending it
Below is my code, i hope its simple to understand & any help would be appreciated.
Will:)
//Will Yates - NeoPixel_Simple
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
//*****************************************************************************
#define NUM_LED 16 // teststrip: 8 ring: 16 strip: 144
//*****************************************************************************
//***************************************************************************//
//These two functions translate the 24bits for each LED to something that //
//the WS2812b LEDs can understand. The datasheet is useless // // ________ //
// |_____ '1' is a 800ns pulse then low (can be high forever) //
// _____
// |________ '0' is a 400ns pulse (only key pulse lengt ) //
// the only thing that really matters is that the high pulses dont overlap //
//***************************************************************************//
void Pixel_High() // function for sending a high pulse
{
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
SysCtlDelay(6); //this needs to be the equv of 800ns (ish)
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);
SysCtlDelay(2); //length of this doesn't really matter
}
void Pixel_Low() // function for sending the low pulse
{
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
SysCtlDelay(1); //this needs to be less than 400ns
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);
SysCtlDelay(6); //length of this doesnt really matter
}
//*****************************************************************************
//***************************************************************************//
// This function is called to output the data onto the LEDs //
// it calls the translate functions at the top //
//***************************************************************************//
void Pixel_GRB(uint8_t Green_Byte,uint8_t Red_Byte,uint8_t Blue_Byte)
{
uint8_t pixel_bit; // pixel_bit is the individual LED in the array
for(pixel_bit=0;pixel_bit<NUM_LED;pixel_bit++){ //works through every pixel
if((Green_Byte<<pixel_bit) & 0x80) //checks for a 1
Pixel_High(); //goes to function for 1 pulse
else Pixel_Low(); //goes to function for 1 pulse
}
for(pixel_bit=0;pixel_bit<NUM_LED;pixel_bit++){//sends info for the Red_Byte
if((Red_Byte<<pixel_bit) & 0x80)
Pixel_High();
else Pixel_Low();
}
for(pixel_bit=0;pixel_bit<NUM_LED;pixel_bit++){//sends info for the Blue_Byte
if((Blue_Byte<<pixel_bit) & 0x80)
Pixel_High();
else Pixel_Low();
}
}
//*****************************************************************************
int
main(void)
{
SysCtlDelay(10000000);
//Set clock frequency
SysCtlClockFreqSet(SYSCTL_OSC_MAIN
| SYSCTL_USE_PLL
| SYSCTL_CFG_VCO_480
, 120000000); //set clock for 120MHz
//Enable GPIO port
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
{
}
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
//reset pixels
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);
SysCtlDelay(20000);
//write the same value to all the LEDs
int white;
for(white = 0; white<NUM_LED; white++){
Pixel_GRB(100,0,0);
}
//Blink LED so that I know send is finished
while(1)
{
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
SysCtlDelay(3000000);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0);
SysCtlDelay(3000000);
Pixel_GRB(0,0,0); //reset LEDs to black
}
}
Will





