Skip to content

Commit

Permalink
Fix for non-root users & SPI (#257)
Browse files Browse the repository at this point in the history
* Fix for non-root users can use SPI

* use DEFINE'd device strings

also add a note to the readme
  • Loading branch information
PandorasFox authored and jgarff committed Jan 6, 2018
1 parent 81af569 commit d50cc44
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ Do this by adding the following line to /boot/config.txt and reboot.
core_freq=250
```

SPI requires you to be in the `gpio` group if you wish to control your LEDs
withou root.

### Comparison PWM/PCM/SPI

Both PWM and PCM use DMA transfer to output the control signal for the LEDs.
Expand Down
4 changes: 2 additions & 2 deletions mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "mailbox.h"


void *mapmem(uint32_t base, uint32_t size) {
void *mapmem(uint32_t base, uint32_t size, const char *mem_dev) {
uint32_t pagemask = ~0UL ^ (getpagesize() - 1);
uint32_t offsetmask = getpagesize() - 1;
int mem_fd;
void *mem;

mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
mem_fd = open(mem_dev, O_RDWR | O_SYNC);
if (mem_fd < 0) {
perror("Can't open /dev/mem");
return NULL;
Expand Down
5 changes: 4 additions & 1 deletion mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define MAJOR_NUM 100
#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)

#define DEV_MEM "/dev/mem"
#define DEV_GPIOMEM "/dev/gpiomem"

int mbox_open(void);
void mbox_close(int file_desc);

Expand All @@ -38,7 +41,7 @@ unsigned mem_alloc(int file_desc, unsigned size, unsigned align, unsigned flags)
unsigned mem_free(int file_desc, unsigned handle);
unsigned mem_lock(int file_desc, unsigned handle);
unsigned mem_unlock(int file_desc, unsigned handle);
void *mapmem(unsigned base, unsigned size);
void *mapmem(unsigned base, unsigned size, const char *mem_dev);
void *unmapmem(void *addr, unsigned size);

unsigned execute_code(int file_desc, unsigned code, unsigned r0, unsigned r1, unsigned r2, unsigned r3, unsigned r4, unsigned r5);
Expand Down
21 changes: 13 additions & 8 deletions ws2811.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,31 +175,36 @@ static int map_registers(ws2811_t *ws2811)
}
dma_addr += rpi_hw->periph_base;

device->dma = mapmem(dma_addr, sizeof(dma_t));
device->dma = mapmem(dma_addr, sizeof(dma_t), DEV_MEM);
if (!device->dma)
{
return -1;
}

switch (device->driver_mode) {
case PWM:
device->pwm = mapmem(PWM_OFFSET + base, sizeof(pwm_t));
device->pwm = mapmem(PWM_OFFSET + base, sizeof(pwm_t), DEV_MEM);
if (!device->pwm)
{
return -1;
}
break;

case PCM:
device->pcm = mapmem(PCM_OFFSET + base, sizeof(pcm_t));
device->pcm = mapmem(PCM_OFFSET + base, sizeof(pcm_t), DEV_MEM);
if (!device->pcm)
{
return -1;
}
break;
}

device->gpio = mapmem(GPIO_OFFSET + base, sizeof(gpio_t));
/*
* The below call can potentially work with /dev/gpiomem instead.
* However, it used /dev/mem before, so I'm leaving it as such.
*/

device->gpio = mapmem(GPIO_OFFSET + base, sizeof(gpio_t), DEV_MEM);
if (!device->gpio)
{
return -1;
Expand All @@ -213,7 +218,7 @@ static int map_registers(ws2811_t *ws2811)
offset = CM_PCM_OFFSET;
break;
}
device->cm_clk = mapmem(offset + base, sizeof(cm_clk_t));
device->cm_clk = mapmem(offset + base, sizeof(cm_clk_t), DEV_MEM);
if (!device->cm_clk)
{
return -1;
Expand Down Expand Up @@ -786,7 +791,7 @@ static ws2811_return_t spi_init(ws2811_t *ws2811)
device->mbox.handle = -1;

// Set SPI-MOSI pin
device->gpio = mapmem(GPIO_OFFSET + base, sizeof(gpio_t));
device->gpio = mapmem(GPIO_OFFSET + base, sizeof(gpio_t), DEV_GPIOMEM);
if (!device->gpio)
{
return WS2811_ERROR_SPI_SETUP;
Expand All @@ -806,7 +811,7 @@ static ws2811_return_t spi_init(ws2811_t *ws2811)
{
channel->strip_type=WS2811_STRIP_RGB;
}

// Set default uncorrected gamma table
if (!channel->gamma)
{
Expand Down Expand Up @@ -935,7 +940,7 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811)
return WS2811_ERROR_MEM_LOCK;
}

device->mbox.virt_addr = mapmem(BUS_TO_PHYS(device->mbox.bus_addr), device->mbox.size);
device->mbox.virt_addr = mapmem(BUS_TO_PHYS(device->mbox.bus_addr), device->mbox.size, DEV_MEM);
if (!device->mbox.virt_addr)
{
mem_unlock(device->mbox.handle, device->mbox.mem_ref);
Expand Down

0 comments on commit d50cc44

Please sign in to comment.