pixel_pi 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/README.md +85 -0
- data/Rakefile +16 -0
- data/examples/strandtest.rb +186 -0
- data/ext/pixel_pi/extconf.rb +18 -0
- data/ext/pixel_pi/leds.c +464 -0
- data/ext/ws2811/LICENSE +24 -0
- data/ext/ws2811/clk.h +60 -0
- data/ext/ws2811/dma.c +192 -0
- data/ext/ws2811/dma.h +146 -0
- data/ext/ws2811/gpio.h +108 -0
- data/ext/ws2811/pwm.c +112 -0
- data/ext/ws2811/pwm.h +122 -0
- data/ext/ws2811/ws2811.c +757 -0
- data/ext/ws2811/ws2811.h +68 -0
- data/lib/pixel_pi/version.rb +3 -0
- data/lib/pixel_pi.rb +2 -0
- data/pixel_pi.gemspec +23 -0
- metadata +77 -0
data/ext/ws2811/dma.c
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
/*
|
2
|
+
* dma.c
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
5
|
+
*
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
9
|
+
* provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
12
|
+
* conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
* provided with the distribution.
|
16
|
+
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
|
17
|
+
* or promote products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
24
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
26
|
+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
|
30
|
+
|
31
|
+
#include <stdint.h>
|
32
|
+
#include <stdio.h>
|
33
|
+
#include <string.h>
|
34
|
+
#include <stdlib.h>
|
35
|
+
#include <unistd.h>
|
36
|
+
|
37
|
+
#include <sys/types.h>
|
38
|
+
#include <sys/stat.h>
|
39
|
+
#include <sys/mman.h>
|
40
|
+
|
41
|
+
#include "dma.h"
|
42
|
+
|
43
|
+
|
44
|
+
// DMA address mapping by DMA number index
|
45
|
+
const static uint32_t dma_addr[] =
|
46
|
+
{
|
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,
|
63
|
+
};
|
64
|
+
|
65
|
+
|
66
|
+
uint32_t dmanum_to_phys(int dmanum)
|
67
|
+
{
|
68
|
+
int array_size = sizeof(dma_addr) / sizeof(dma_addr[0]);
|
69
|
+
|
70
|
+
if (dmanum >= array_size)
|
71
|
+
{
|
72
|
+
return 0;
|
73
|
+
}
|
74
|
+
|
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 = 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
|
+
void *vaddr;
|
137
|
+
int i;
|
138
|
+
|
139
|
+
vaddr = 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, &((uint8_t *)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);
|
165
|
+
dma_cb_t *vaddr;
|
166
|
+
|
167
|
+
if (pages > 1)
|
168
|
+
{
|
169
|
+
return NULL;
|
170
|
+
}
|
171
|
+
|
172
|
+
vaddr = mmap(NULL, pages * PAGE_SIZE,
|
173
|
+
PROT_READ | PROT_WRITE,
|
174
|
+
MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE |
|
175
|
+
MAP_LOCKED, -1, 0);
|
176
|
+
if (vaddr == MAP_FAILED)
|
177
|
+
{
|
178
|
+
perror("dma_desc_alloc() mmap() failed");
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
|
182
|
+
return vaddr;
|
183
|
+
}
|
184
|
+
|
185
|
+
void dma_page_free(void *buffer, const uint32_t size)
|
186
|
+
{
|
187
|
+
uint32_t pages = (size / PAGE_SIZE) + 1;
|
188
|
+
|
189
|
+
munmap(buffer, pages * PAGE_SIZE);
|
190
|
+
}
|
191
|
+
|
192
|
+
|
data/ext/ws2811/dma.h
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
/*
|
2
|
+
* dma.h
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
5
|
+
*
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
9
|
+
* provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
12
|
+
* conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
* provided with the distribution.
|
16
|
+
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
|
17
|
+
* or promote products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
24
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
26
|
+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
|
30
|
+
#ifndef __DMA_H__
|
31
|
+
#define __DMA_H__
|
32
|
+
|
33
|
+
|
34
|
+
/*
|
35
|
+
* DMA Control Block in Main Memory
|
36
|
+
*
|
37
|
+
* Note: Must start at a 256 byte aligned address.
|
38
|
+
* Use corresponding register field definitions.
|
39
|
+
*/
|
40
|
+
typedef struct
|
41
|
+
{
|
42
|
+
uint32_t ti;
|
43
|
+
uint32_t source_ad;
|
44
|
+
uint32_t dest_ad;
|
45
|
+
uint32_t txfr_len;
|
46
|
+
uint32_t stride;
|
47
|
+
uint32_t nextconbk;
|
48
|
+
uint32_t resvd_0x18[2];
|
49
|
+
} __attribute__((packed)) dma_cb_t;
|
50
|
+
|
51
|
+
/*
|
52
|
+
* DMA register set
|
53
|
+
*/
|
54
|
+
typedef struct
|
55
|
+
{
|
56
|
+
uint32_t cs;
|
57
|
+
#define RPI_DMA_CS_RESET (1 << 31)
|
58
|
+
#define RPI_DMA_CS_ABORT (1 << 30)
|
59
|
+
#define RPI_DMA_CS_DISDEBUG (1 << 29)
|
60
|
+
#define RPI_DMA_CS_WAIT_OUTSTANDING_WRITES (1 << 28)
|
61
|
+
#define RPI_DMA_CS_PANIC_PRIORITY(val) ((val & 0xf) << 20)
|
62
|
+
#define RPI_DMA_CS_PRIORITY(val) ((val & 0xf) << 16)
|
63
|
+
#define RPI_DMA_CS_ERROR (1 << 8)
|
64
|
+
#define RPI_DMA_CS_WAITING_OUTSTANDING_WRITES (1 << 6)
|
65
|
+
#define RPI_DMA_CS_DREQ_STOPS_DMA (1 << 5)
|
66
|
+
#define RPI_DMA_CS_PAUSED (1 << 4)
|
67
|
+
#define RPI_DMA_CS_DREQ (1 << 3)
|
68
|
+
#define RPI_DMA_CS_INT (1 << 2)
|
69
|
+
#define RPI_DMA_CS_END (1 << 1)
|
70
|
+
#define RPI_DMA_CS_ACTIVE (1 << 0)
|
71
|
+
uint32_t conblk_ad;
|
72
|
+
uint32_t ti;
|
73
|
+
#define RPI_DMA_TI_NO_WIDE_BURSTS (1 << 26)
|
74
|
+
#define RPI_DMA_TI_WAITS(val) ((val & 0x1f) << 21)
|
75
|
+
#define RPI_DMA_TI_PERMAP(val) ((val & 0x1f) << 16)
|
76
|
+
#define RPI_DMA_TI_BURST_LENGTH(val) ((val & 0xf) << 12)
|
77
|
+
#define RPI_DMA_TI_SRC_IGNORE (1 << 11)
|
78
|
+
#define RPI_DMA_TI_SRC_DREQ (1 << 10)
|
79
|
+
#define RPI_DMA_TI_SRC_WIDTH (1 << 9)
|
80
|
+
#define RPI_DMA_TI_SRC_INC (1 << 8)
|
81
|
+
#define RPI_DMA_TI_DEST_IGNORE (1 << 7)
|
82
|
+
#define RPI_DMA_TI_DEST_DREQ (1 << 6)
|
83
|
+
#define RPI_DMA_TI_DEST_WIDTH (1 << 5)
|
84
|
+
#define RPI_DMA_TI_DEST_INC (1 << 4)
|
85
|
+
#define RPI_DMA_TI_WAIT_RESP (1 << 3)
|
86
|
+
#define RPI_DMA_TI_TDMODE (1 << 1)
|
87
|
+
#define RPI_DMA_TI_INTEN (1 << 0)
|
88
|
+
uint32_t source_ad;
|
89
|
+
uint32_t dest_ad;
|
90
|
+
uint32_t txfr_len;
|
91
|
+
#define RPI_DMA_TXFR_LEN_YLENGTH(val) ((val & 0xffff) << 16)
|
92
|
+
#define RPI_DMA_TXFR_LEN_XLENGTH(val) ((val & 0xffff) << 0)
|
93
|
+
uint32_t stride;
|
94
|
+
#define RPI_DMA_STRIDE_D_STRIDE(val) ((val & 0xffff) << 16)
|
95
|
+
#define RPI_DMA_STRIDE_S_STRIDE(val) ((val & 0xffff) << 0)
|
96
|
+
uint32_t nextconbk;
|
97
|
+
uint32_t debug;
|
98
|
+
} __attribute__((packed)) dma_t;
|
99
|
+
|
100
|
+
|
101
|
+
#define DMA0 (0x20007000) // 0x7e007000
|
102
|
+
#define DMA1 (0x20007100)
|
103
|
+
#define DMA2 (0x20007200)
|
104
|
+
#define DMA3 (0x20007300)
|
105
|
+
#define DMA4 (0x20007400)
|
106
|
+
#define DMA5 (0x20007500)
|
107
|
+
#define DMA6 (0x20007600)
|
108
|
+
#define DMA7 (0x20007700)
|
109
|
+
#define DMA8 (0x20007800)
|
110
|
+
#define DMA9 (0x20007900)
|
111
|
+
#define DMA10 (0x20007a00)
|
112
|
+
#define DMA11 (0x20007b00)
|
113
|
+
#define DMA12 (0x20007c00)
|
114
|
+
#define DMA13 (0x20007d00)
|
115
|
+
#define DMA14 (0x20007e00)
|
116
|
+
#define DMA15 (0x20e05000)
|
117
|
+
|
118
|
+
|
119
|
+
#define PAGE_SIZE (1 << 12)
|
120
|
+
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
121
|
+
#define PAGE_OFFSET(page) (page & (PAGE_SIZE - 1))
|
122
|
+
#define MAX_PAGES (PAGE_SIZE / sizeof(dma_cb_t))
|
123
|
+
|
124
|
+
|
125
|
+
typedef struct dma_page
|
126
|
+
{
|
127
|
+
struct dma_page *next;
|
128
|
+
struct dma_page *prev;
|
129
|
+
void *addr;
|
130
|
+
} dma_page_t;
|
131
|
+
|
132
|
+
|
133
|
+
uint32_t dmanum_to_phys(int dmanum);
|
134
|
+
|
135
|
+
void dma_page_init(dma_page_t *page);
|
136
|
+
dma_page_t *dma_page_add(dma_page_t *head, void *addr);
|
137
|
+
void dma_page_remove(dma_page_t *page);
|
138
|
+
void dma_page_remove_all(dma_page_t *head);
|
139
|
+
dma_page_t *dma_page_next(dma_page_t *head, dma_page_t *page);
|
140
|
+
|
141
|
+
void *dma_alloc(dma_page_t *head, uint32_t size);
|
142
|
+
dma_cb_t *dma_desc_alloc(uint32_t descriptors);
|
143
|
+
void dma_page_free(void *buffer, const uint32_t size);
|
144
|
+
|
145
|
+
|
146
|
+
#endif /* __DMA_H__ */
|
data/ext/ws2811/gpio.h
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
/*
|
2
|
+
* gpio.h
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
5
|
+
*
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
9
|
+
* provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
12
|
+
* conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
* provided with the distribution.
|
16
|
+
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
|
17
|
+
* or promote products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
24
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
26
|
+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
|
30
|
+
#ifndef __GPIO_H__
|
31
|
+
#define __GPIO_H__
|
32
|
+
|
33
|
+
|
34
|
+
typedef struct
|
35
|
+
{
|
36
|
+
uint32_t fsel[6]; // GPIO Function Select
|
37
|
+
uint32_t resvd_0x18;
|
38
|
+
uint32_t set[2]; // GPIO Pin Output Set
|
39
|
+
uint32_t resvd_0x24;
|
40
|
+
uint32_t clr[2]; // GPIO Pin Output Clear
|
41
|
+
uint32_t resvd_0x30;
|
42
|
+
uint32_t lev[2]; // GPIO Pin Level
|
43
|
+
uint32_t resvd_0x3c;
|
44
|
+
uint32_t eds[2]; // GPIO Pin Event Detect Status
|
45
|
+
uint32_t resvd_0x48;
|
46
|
+
uint32_t ren[2]; // GPIO Pin Rising Edge Detect Enable
|
47
|
+
uint32_t resvd_0x54;
|
48
|
+
uint32_t fen[2]; // GPIO Pin Falling Edge Detect Enable
|
49
|
+
uint32_t resvd_0x60;
|
50
|
+
uint32_t hen[2]; // GPIO Pin High Detect Enable
|
51
|
+
uint32_t resvd_0x6c;
|
52
|
+
uint32_t len[2]; // GPIO Pin Low Detect Enable
|
53
|
+
uint32_t resvd_0x78;
|
54
|
+
uint32_t aren[2]; // GPIO Pin Async Rising Edge Detect
|
55
|
+
uint32_t resvd_0x84;
|
56
|
+
uint32_t afen[2]; // GPIO Pin Async Falling Edge Detect
|
57
|
+
uint32_t resvd_0x90;
|
58
|
+
uint32_t pud; // GPIO Pin Pull up/down Enable
|
59
|
+
uint32_t pudclk[2]; // GPIO Pin Pull up/down Enable Clock
|
60
|
+
uint32_t resvd_0xa0[4];
|
61
|
+
uint32_t test;
|
62
|
+
} __attribute__((packed)) gpio_t;
|
63
|
+
|
64
|
+
|
65
|
+
#define GPIO (0x20200000) // 0x7e200000
|
66
|
+
|
67
|
+
|
68
|
+
static inline void gpio_function_set(volatile gpio_t *gpio, uint8_t pin, uint8_t function)
|
69
|
+
{
|
70
|
+
int regnum = pin / 10;
|
71
|
+
int offset = (pin % 10) * 3;
|
72
|
+
uint8_t funcmap[] = { 4, 5, 6, 7, 3, 2 }; // See datasheet for mapping
|
73
|
+
|
74
|
+
if (function > 5)
|
75
|
+
{
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
gpio->fsel[regnum] &= ~(0x7 << offset);
|
80
|
+
gpio->fsel[regnum] |= ((funcmap[function]) << offset);
|
81
|
+
}
|
82
|
+
|
83
|
+
static inline void gpio_level_set(volatile gpio_t *gpio, uint8_t pin, uint8_t level)
|
84
|
+
{
|
85
|
+
int regnum = pin >> 5;
|
86
|
+
int offset = (pin & 0x1f);
|
87
|
+
|
88
|
+
if (level)
|
89
|
+
{
|
90
|
+
gpio->set[regnum] = (1 << offset);
|
91
|
+
}
|
92
|
+
else
|
93
|
+
{
|
94
|
+
gpio->clr[regnum] = (1 << offset);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
static inline void gpio_output_set(volatile gpio_t *gpio, uint8_t pin, uint8_t output)
|
99
|
+
{
|
100
|
+
int regnum = pin / 10;
|
101
|
+
int offset = (pin % 10) * 3;
|
102
|
+
uint8_t function = output ? 1 : 0; // See datasheet for mapping
|
103
|
+
|
104
|
+
gpio->fsel[regnum] &= ~(0x7 << offset);
|
105
|
+
gpio->fsel[regnum] |= ((function & 0x7) << offset);
|
106
|
+
}
|
107
|
+
|
108
|
+
#endif /* __GPIO_H__ */
|
data/ext/ws2811/pwm.c
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
/*
|
2
|
+
* pwm.c
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
5
|
+
*
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
9
|
+
* provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
12
|
+
* conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
* provided with the distribution.
|
16
|
+
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
|
17
|
+
* or promote products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
24
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
26
|
+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
|
30
|
+
|
31
|
+
#include <stdint.h>
|
32
|
+
|
33
|
+
#include "ws2811.h"
|
34
|
+
|
35
|
+
#include "pwm.h"
|
36
|
+
|
37
|
+
|
38
|
+
// Mapping of Pin to alternate function for PWM channel 0
|
39
|
+
const pwm_pin_table_t pwm_pin_chan0[] =
|
40
|
+
{
|
41
|
+
{
|
42
|
+
.pinnum = 12,
|
43
|
+
.altnum = 0,
|
44
|
+
},
|
45
|
+
{
|
46
|
+
.pinnum = 18,
|
47
|
+
.altnum = 5,
|
48
|
+
},
|
49
|
+
{
|
50
|
+
.pinnum = 40,
|
51
|
+
.altnum = 0,
|
52
|
+
},
|
53
|
+
{
|
54
|
+
.pinnum = 52,
|
55
|
+
.altnum = 1,
|
56
|
+
},
|
57
|
+
};
|
58
|
+
|
59
|
+
// Mapping of Pin to alternate function for PWM channel 1
|
60
|
+
const pwm_pin_table_t pwm_pin_chan1[] =
|
61
|
+
{
|
62
|
+
{
|
63
|
+
.pinnum = 13,
|
64
|
+
.altnum = 0,
|
65
|
+
},
|
66
|
+
{
|
67
|
+
.pinnum = 19,
|
68
|
+
.altnum = 5,
|
69
|
+
},
|
70
|
+
{
|
71
|
+
.pinnum = 41,
|
72
|
+
.altnum = 0,
|
73
|
+
},
|
74
|
+
{
|
75
|
+
.pinnum = 45,
|
76
|
+
.altnum = 0,
|
77
|
+
},
|
78
|
+
{
|
79
|
+
.pinnum = 53,
|
80
|
+
.altnum = 1,
|
81
|
+
},
|
82
|
+
};
|
83
|
+
|
84
|
+
const pwm_pin_tables_t pwm_pin_tables[RPI_PWM_CHANNELS] =
|
85
|
+
{
|
86
|
+
{
|
87
|
+
.pins = pwm_pin_chan0,
|
88
|
+
.count = sizeof(pwm_pin_chan0) / sizeof(pwm_pin_chan0[0]),
|
89
|
+
},
|
90
|
+
{
|
91
|
+
.pins = pwm_pin_chan1,
|
92
|
+
.count = sizeof(pwm_pin_chan1) / sizeof(pwm_pin_chan1[0]),
|
93
|
+
},
|
94
|
+
};
|
95
|
+
|
96
|
+
|
97
|
+
int pwm_pin_alt(int chan, int pinnum)
|
98
|
+
{
|
99
|
+
const pwm_pin_tables_t *pintable = &pwm_pin_tables[chan];
|
100
|
+
int i;
|
101
|
+
|
102
|
+
for (i = 0; i < pintable->count; i++)
|
103
|
+
{
|
104
|
+
if (pintable->pins[i].pinnum == pinnum)
|
105
|
+
{
|
106
|
+
return pintable->pins[i].altnum;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
return -1;
|
111
|
+
}
|
112
|
+
|
data/ext/ws2811/pwm.h
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
/*
|
2
|
+
* pwm.h
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
5
|
+
*
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
9
|
+
* provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
12
|
+
* conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
14
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
15
|
+
* provided with the distribution.
|
16
|
+
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
|
17
|
+
* or promote products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
24
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
26
|
+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
|
30
|
+
#ifndef __PWM_H__
|
31
|
+
#define __PWM_H__
|
32
|
+
|
33
|
+
|
34
|
+
/*
|
35
|
+
*
|
36
|
+
* Pin mappint of alternate pin configuration for PWM
|
37
|
+
*
|
38
|
+
* GPIO ALT PWM0 ALT PWM1
|
39
|
+
*
|
40
|
+
* 12 0
|
41
|
+
* 13 0
|
42
|
+
* 18 5
|
43
|
+
* 19 5
|
44
|
+
* 40 0
|
45
|
+
* 41 0
|
46
|
+
* 45 0
|
47
|
+
* 52 1
|
48
|
+
* 53 1
|
49
|
+
*
|
50
|
+
*/
|
51
|
+
|
52
|
+
|
53
|
+
#define RPI_PWM_CHANNELS 2
|
54
|
+
|
55
|
+
|
56
|
+
typedef struct
|
57
|
+
{
|
58
|
+
uint32_t ctl;
|
59
|
+
#define RPI_PWM_CTL_MSEN2 (1 << 15)
|
60
|
+
#define RPI_PWM_CTL_USEF2 (1 << 13)
|
61
|
+
#define RPI_PWM_CTL_POLA2 (1 << 12)
|
62
|
+
#define RPI_PWM_CTL_SBIT2 (1 << 11)
|
63
|
+
#define RPI_PWM_CTL_RPTL2 (1 << 10)
|
64
|
+
#define RPI_PWM_CTL_MODE2 (1 << 9)
|
65
|
+
#define RPI_PWM_CTL_PWEN2 (1 << 8)
|
66
|
+
#define RPI_PWM_CTL_MSEN1 (1 << 7)
|
67
|
+
#define RPI_PWM_CTL_CLRF1 (1 << 6)
|
68
|
+
#define RPI_PWM_CTL_USEF1 (1 << 5)
|
69
|
+
#define RPI_PWM_CTL_POLA1 (1 << 4)
|
70
|
+
#define RPI_PWM_CTL_SBIT1 (1 << 3)
|
71
|
+
#define RPI_PWM_CTL_RPTL1 (1 << 2)
|
72
|
+
#define RPI_PWM_CTL_MODE1 (1 << 1)
|
73
|
+
#define RPI_PWM_CTL_PWEN1 (1 << 0)
|
74
|
+
uint32_t sta;
|
75
|
+
#define RPI_PWM_STA_STA4 (1 << 12)
|
76
|
+
#define RPI_PWM_STA_STA3 (1 << 11)
|
77
|
+
#define RPI_PWM_STA_STA2 (1 << 10)
|
78
|
+
#define RPI_PWM_STA_STA1 (1 << 9)
|
79
|
+
#define RPI_PWM_STA_BERR (1 << 8)
|
80
|
+
#define RPI_PWM_STA_GAP04 (1 << 7)
|
81
|
+
#define RPI_PWM_STA_GAP03 (1 << 6)
|
82
|
+
#define RPI_PWM_STA_GAP02 (1 << 5)
|
83
|
+
#define RPI_PWM_STA_GAP01 (1 << 4)
|
84
|
+
#define RPI_PWM_STA_RERR1 (1 << 3)
|
85
|
+
#define RPI_PWM_STA_WERR1 (1 << 2)
|
86
|
+
#define RPI_PWM_STA_EMPT1 (1 << 1)
|
87
|
+
#define RPI_PWM_STA_FULL1 (1 << 0)
|
88
|
+
uint32_t dmac;
|
89
|
+
#define RPI_PWM_DMAC_ENAB (1 << 31)
|
90
|
+
#define RPI_PWM_DMAC_PANIC(val) ((val & 0xff) << 8)
|
91
|
+
#define RPI_PWM_DMAC_DREQ(val) ((val & 0xff) << 0)
|
92
|
+
uint32_t resvd_0x0c;
|
93
|
+
uint32_t rng1;
|
94
|
+
uint32_t dat1;
|
95
|
+
uint32_t fif1;
|
96
|
+
uint32_t resvd_0x1c;
|
97
|
+
uint32_t rng2;
|
98
|
+
uint32_t dat2;
|
99
|
+
} __attribute__((packed)) pwm_t;
|
100
|
+
|
101
|
+
|
102
|
+
#define PWM (0x2020c000) // 0x7e20c000
|
103
|
+
#define PWM_PERIPH (0x7e20c000)
|
104
|
+
|
105
|
+
|
106
|
+
typedef struct
|
107
|
+
{
|
108
|
+
int pinnum;
|
109
|
+
int altnum;
|
110
|
+
} pwm_pin_table_t;
|
111
|
+
|
112
|
+
typedef struct
|
113
|
+
{
|
114
|
+
const int count;
|
115
|
+
const pwm_pin_table_t *pins;
|
116
|
+
} pwm_pin_tables_t;
|
117
|
+
|
118
|
+
|
119
|
+
int pwm_pin_alt(int chan, int pinnum);
|
120
|
+
|
121
|
+
|
122
|
+
#endif /* __PWM_H__ */
|