Skip to content

Commit 13e6958

Browse files
author
Tom
committed
update for Raspberry Pi 2 and 3
update to make the code work with Raspberry Pi 2 & 3, also added some new functions.
1 parent 9476dab commit 13e6958

25 files changed

+2114
-757
lines changed

BCM2835-ARM-Peripherals.pdf

1.42 MB
Binary file not shown.

README.md

+82-24
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ On the raspberry you open a terminal window and type following commands:
1010
* make
1111
* sudo chmod +x ws2812svr
1212

13+
On newer Raspbian (Jessie) operating system the audio output is activated by default, you need to disable this:
14+
You can do this by blacklisting the sound module:
15+
sudo nano /etc/modprobe.d/snd-blacklist.conf
16+
17+
*blacklist snd_bcm2835
18+
19+
also in /boot/config.txt you comment out the audio=on parameter:
20+
```
21+
# Enable audio (loads snd_bcm2835)
22+
#dtparam=audio=on
23+
```
24+
1325
#Testing
1426
Connect your LEDs to the PWM output of the Raspberry Pi and start the program:
1527

@@ -18,7 +30,8 @@ Connect your LEDs to the PWM output of the Raspberry Pi and start the program:
1830
Now first initialize the driver code from jgarff by typing 'setup'.
1931
On the following line you must **replace 10** by the number of leds you have attached!.
2032

21-
* setup channel_1_count=10
33+
* setup 1,10
34+
* init
2235

2336
Now you can type commands to change the color of the leds.
2437
For example make them all red:
@@ -27,25 +40,35 @@ For example make them all red:
2740
* render
2841

2942
#Supported commands
30-
Here is a list of commands you can type or send to the program. All commands have optional comma seperated parameters. The parameters must be in the correct order except for the 'setup' command.
43+
Here is a list of commands you can type or send to the program. All commands have optional comma seperated parameters. The parameters must be in the correct order!
3144

3245
* Setup command must be called everytime the program is started:
3346
```
3447
setup
35-
channel_1_count=1, #number of leds on channel 1
36-
freq=800000, #frequency used to talk to the leds
37-
dma=5, #dma channel
38-
channels=1, #number of led strings / PWM outputs / channels used
39-
channel_1_gpio=18, #GPIO number of channel 1
40-
channel_1_invert=0, #Invert the output of channnel 1 (in case you are using an 3.3V->5V level shifter)
41-
channel_1_brightness=255, #default brightness of the leds (can be changed with brightness command)
42-
channel_2_count=0, #number of leds in channel 2
43-
channel_2_gpio=0, #GPIO number for channel 2
44-
channel_2_invert=0, #invert the output of channel 2
45-
channel_2_brightness=255 #brightness for channel 2
46-
47-
Example:
48-
setup channel_1_count=10
48+
setup
49+
<channel>, #channel number
50+
<led_count>, #number of leds in channel
51+
<led_type>, #type of led (3 color or 4 color) default 0
52+
<invert>, #invert output, default 0
53+
<global_brightness>, #global brightness level for channel (0-255), default 255
54+
<gpionum> #GPIO output number, 18 for PWM0 = pin 12, 24 for PWM1 = pin 35, default 18
55+
56+
Possible LED types:
57+
0 WS2811_STRIP_RGB
58+
1 WS2811_STRIP_RBG
59+
2 WS2811_STRIP_GRB
60+
3 WS2811_STRIP_GBR
61+
4 WS2811_STRIP_BRG
62+
5 WS2811_STRIP_BGR
63+
6 SK6812_STRIP_RGBW
64+
7 SK6812_STRIP_RBGW
65+
8 SK6812_STRIP_GRBW
66+
9 SK6812_STRIP_GBRW
67+
10 SK6812_STRIP_BRGW
68+
11 SK6812_STRIP_BGRW
69+
70+
Example:
71+
setup 1,10,0
4972
```
5073

5174
* Render command sends the internal buffer to all leds
@@ -81,21 +104,56 @@ fill
81104
<RRGGBB>, #color to fill (default FF0000)
82105
<start>, #at which led should we start (default is 0)
83106
<len> #number of leds to fill with the given color after start (default all leds)
84-
```
85-
86-
* brightness command changes the brightness of the leds without affecting the color value
87-
```
88-
brightness
89-
<channel>, #channel to change brightness (default 1)
90-
<brightness> #brightness 0-255 (default 255)
107+
<OR,AND,XOR,NOT,=> #bitwise operator to execute on OLD and NEW color, default = copies new color to output
91108
```
92109

93110
* delay command waits for number of milliseconds
94111
```
95112
delay
96113
<milliseconds> #enter number of milliseconds to wait
97114
```
98-
115+
116+
*brightness command changes the brightness of a single or multiple leds without changing the actual color value
117+
```
118+
brightness
119+
<channel>, #channel number to change brightness (default 1)
120+
<brightness>, #brightness to set (0-255, default 255)
121+
<start>, #start at this led number (default 0)
122+
<len> #number of leds to change starting at start (default led count of channel)
123+
```
124+
125+
*fade command changes the brightness over time
126+
```
127+
fade
128+
<channel>, #channel to fade
129+
<start_brightness>, #start brightness (default 0)
130+
<end_brightness>, #end brightness (default 255)
131+
<delay ms>, #delay in ms
132+
<step>, #step to increase / decrease brightness every delay untill end_brightness is reached
133+
<start_led>, #start led
134+
<len> #number of leds to change starting at start (default is channel count)
135+
```
136+
137+
*gradient command makes a smooth change of color or brightness level in a channel
138+
```
139+
gradient
140+
<channel>, #channel number to change
141+
<RGBWL>, #which color component to change, R = red, G = green, B = blue, W = white and L = brightness level
142+
<start_level>, #start at color level (0-255) default is 0
143+
<end_level>, #end at color level (0-255) default is 255
144+
<start_led>, #start at led number (default is 0)
145+
<len> #number of leds to change (default is channel count)
146+
```
147+
148+
*random command can create a random color
149+
```
150+
random
151+
<channel>, #channel number to change
152+
<start>, #start at this led
153+
<len>, #number of leds to fill with a random color, default is channel count
154+
<RGBWL> #color to use in random can be R = red, G = green, B = blue, W = White, L = brightness also combination is possible like RGBW or RL
155+
```
156+
99157
#Special keywords
100158
You can add `do ... loop` to repeat commands when using a file or TCP connection.
101159

clk.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ typedef struct {
5151
#define CM_PWM_DIV_PASSWD (0x5a << 24)
5252
#define CM_PWM_DIV_DIVI(val) ((val & 0xfff) << 12)
5353
#define CM_PWM_DIV_DIVF(val) ((val & 0xfff) << 0)
54-
} __attribute__ ((packed)) cm_pwm_t;
54+
} __attribute__((packed, aligned(4))) cm_pwm_t;
5555

5656

57-
#define CM_PWM (0x201010a0) // 0x7e1010a0
57+
#define CM_PWM_OFFSET (0x001010a0)
5858

5959

6060
#endif /* __CLK_H__ */

dma.c

+20-129
Original file line numberDiff line numberDiff line change
@@ -42,146 +42,37 @@
4242

4343

4444
// DMA address mapping by DMA number index
45-
const static uint32_t dma_addr[] =
45+
static const uint32_t dma_offset[] =
4646
{
47-
DMA0,
48-
DMA1,
49-
DMA2,
50-
DMA3,
51-
DMA4,
52-
DMA5,
53-
DMA6,
54-
DMA7,
55-
DMA8,
56-
DMA9,
57-
DMA10,
58-
DMA11,
59-
DMA12,
60-
DMA13,
61-
DMA14,
62-
DMA15,
47+
DMA0_OFFSET,
48+
DMA1_OFFSET,
49+
DMA2_OFFSET,
50+
DMA3_OFFSET,
51+
DMA4_OFFSET,
52+
DMA5_OFFSET,
53+
DMA6_OFFSET,
54+
DMA7_OFFSET,
55+
DMA8_OFFSET,
56+
DMA9_OFFSET,
57+
DMA10_OFFSET,
58+
DMA11_OFFSET,
59+
DMA12_OFFSET,
60+
DMA13_OFFSET,
61+
DMA14_OFFSET,
62+
DMA15_OFFSET,
6363
};
6464

6565

66-
uint32_t dmanum_to_phys(int dmanum)
66+
uint32_t dmanum_to_offset(int dmanum)
6767
{
68-
int array_size = sizeof(dma_addr) / sizeof(dma_addr[0]);
68+
int array_size = sizeof(dma_offset) / sizeof(dma_offset[0]);
6969

7070
if (dmanum >= array_size)
7171
{
7272
return 0;
7373
}
7474

75-
return dma_addr[dmanum];
76-
}
77-
78-
79-
dma_page_t *dma_page_add(dma_page_t *head, void *addr)
80-
{
81-
dma_page_t *page = (dma_page_t *)malloc(sizeof(dma_page_t));
82-
83-
if (!page)
84-
{
85-
return NULL;
86-
}
87-
88-
page->next = head;
89-
page->prev = head->prev;
90-
91-
head->prev->next = page;
92-
head->prev = page;
93-
94-
page->addr = addr;
95-
96-
return page;
97-
}
98-
99-
void dma_page_remove(dma_page_t *page)
100-
{
101-
page->prev->next = page->next;
102-
page->next->prev = page->prev;
103-
104-
free(page);
105-
}
106-
107-
void dma_page_remove_all(dma_page_t *head)
108-
{
109-
while (head->next != head)
110-
{
111-
dma_page_remove(head->next);
112-
}
113-
}
114-
115-
dma_page_t *dma_page_next(dma_page_t *head, dma_page_t *page)
116-
{
117-
if (page->next != head)
118-
{
119-
return page->next;
120-
}
121-
122-
return NULL;
123-
}
124-
125-
void dma_page_init(dma_page_t *page)
126-
{
127-
memset(page, 0, sizeof(*page));
128-
129-
page->next = page;
130-
page->prev = page;
131-
}
132-
133-
void *dma_alloc(dma_page_t *head, uint32_t size)
134-
{
135-
uint32_t pages = (size / PAGE_SIZE) + 1;
136-
uint8_t *vaddr;
137-
int i;
138-
139-
vaddr = (uint8_t *) mmap(NULL, pages * PAGE_SIZE,
140-
PROT_READ | PROT_WRITE,
141-
MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE |
142-
MAP_LOCKED, -1, 0);
143-
if (vaddr == MAP_FAILED)
144-
{
145-
perror("dma_alloc() mmap() failed");
146-
return NULL;
147-
}
148-
149-
for (i = 0; i < pages; i++)
150-
{
151-
if (!dma_page_add(head, &vaddr[PAGE_SIZE * i]))
152-
{
153-
dma_page_remove_all(head);
154-
munmap(vaddr, pages * PAGE_SIZE);
155-
return NULL;
156-
}
157-
}
158-
159-
return vaddr;
160-
}
161-
162-
dma_cb_t *dma_desc_alloc(uint32_t descriptors)
163-
{
164-
uint32_t pages = ((descriptors * sizeof(dma_cb_t)) / PAGE_SIZE) + 1;
165-
dma_cb_t *vaddr;
166-
167-
vaddr = (dma_cb_t *) mmap(NULL, pages * PAGE_SIZE,
168-
PROT_READ | PROT_WRITE,
169-
MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE |
170-
MAP_LOCKED, -1, 0);
171-
if (vaddr == MAP_FAILED)
172-
{
173-
perror("dma_desc_alloc() mmap() failed");
174-
return NULL;
175-
}
176-
177-
return vaddr;
178-
}
179-
180-
void dma_page_free(void *buffer, const uint32_t size)
181-
{
182-
uint32_t pages = (size / PAGE_SIZE) + 1;
183-
184-
munmap(buffer, pages * PAGE_SIZE);
75+
return dma_offset[dmanum];
18576
}
18677

18778

0 commit comments

Comments
 (0)