首页 > 代码库 > 直接访问树莓派的SPI,不通过驱动程序
直接访问树莓派的SPI,不通过驱动程序
pispi.h:
1 #ifndef PI_SPI_H 2 #define PI_SPI_H 3 4 #define SPICLKDIV 32 /* ~8 Mhz */ 5 6 #define SPIBUFSIZE 32 /* SPI buffer size */ 7 #define BUFSIZE (SPIBUFSIZE/4) 8 9 /* Broadcom defines */10 11 #define BCM2835_PERI_BASE 0x2000000012 #define BCM2835_GPIO_BASE (BCM2835_PERI_BASE + 0x200000) /* GPIO controller */13 #define BCM2835_SPI_BASE (BCM2835_PERI_BASE + 0x204000) /* SPI controller */14 15 #define BCM2835_GPFSEL0 *(gpio)16 #define BCM2835_GPFSEL1 *(gpio + 1)17 #define BCM2835_GPFSEL2 *(gpio + 2)18 19 #define BCM2835_SPICS *(spi + 0)20 #define BCM2835_SPIFIFO *(spi + 1)21 #define BCM2835_SPICLK *(spi + 2)22 23 #define SPI_CS_LEN_LONG 0x0200000024 #define SPI_CS_DMA_LEN 0x0100000025 #define SPI_CS_CSPOL2 0x0080000026 #define SPI_CS_CSPOL1 0x0040000027 #define SPI_CS_CSPOL0 0x0020000028 #define SPI_CS_RXF 0x0010000029 #define SPI_CS_RXR 0x0008000030 #define SPI_CS_TXD 0x0004000031 #define SPI_CS_RXD 0x0002000032 #define SPI_CS_DONE 0x0001000033 #define SPI_CS_LEN 0x0000200034 #define SPI_CS_REN 0x0000100035 #define SPI_CS_ADCS 0x0000080036 #define SPI_CS_INTR 0x0000040037 #define SPI_CS_INTD 0x0000020038 #define SPI_CS_DMAEN 0x0000010039 #define SPI_CS_TA 0x0000008040 #define SPI_CS_CSPOL 0x0000004041 #define SPI_CS_CLEAR_RX 0x0000002042 #define SPI_CS_CLEAR_TX 0x0000001043 #define SPI_CS_CPOL 0x0000000844 #define SPI_CS_CPHA 0x0000000445 #define SPI_CS_CS_10 0x0000000246 #define SPI_CS_CS_01 0x0000000147 48 #define BLOCK_SIZE (4*1024)49 50 #endif51
pispi.c
/* Copyright (C) 2015 Zhang Wei * * Read write Raspberry Pi SPI without SPI driver * */#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#include "pispi.h"volatile unsigned *gpio, *spi;volatile unsigned txBuf[BUFSIZE], rxBuf[BUFSIZE+1];static int map_gpio();static void setup_gpio();static void restore_gpio();static void transfer_data();int main(int argc, char *argv[]){ /* put "HELLO, WORLD\n" in txBuf */ txBuf[0] = 0x4C4C4548; //0x48454C4C; "HELL" reversed txBuf[1] = 0x57202C4F; //0x4F2C2057; "O, W" reversed txBuf[2] = 0x444C524F; //0x4F524C44; "ORLD" reversed txBuf[3] = 0x2020200A; //0x0A202020; "\n " reversed map_gpio(); setup_gpio(); transfer_data(); restore_gpio(); munmap((void *)gpio, BLOCK_SIZE); munmap((void *)spi, BLOCK_SIZE); return 0;}int map_gpio() { int fd; fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) printf("can‘t open /dev/mem \n"); /* mmap GPIO */ gpio = mmap( NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, BCM2835_GPIO_BASE); if (gpio == MAP_FAILED) { printf("can‘t map gpio \n"); close(fd); return -1; } /* mmap SPI */ spi = mmap( NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, BCM2835_SPI_BASE); close(fd); if (spi == MAP_FAILED) { printf("can‘t map spi\n"); return -1; } return 0;}void setup_gpio(){ unsigned int x; /* change SPI pins */ x = BCM2835_GPFSEL0; x &= ~(0b111 << (9*3)); x |= 0b111 << (9*3); BCM2835_GPFSEL0 = x; x = BCM2835_GPFSEL1; x &= ~(0b111 << (0*3) | 0b111 << (1*3)); x |= (0b100 << (0*3) | 0b100 << (1*3)); BCM2835_GPFSEL1 = x; /* set up SPI */ BCM2835_SPICLK = SPICLKDIV; BCM2835_SPICS = 0; /* clear FIFOs */ BCM2835_SPICS |= SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX; /* clear done bit */ BCM2835_SPICS |= SPI_CS_DONE;}void restore_gpio() { unsigned int x; /* change SPI pins to inputs*/ x = BCM2835_GPFSEL0; x &= ~(0b111 << (9*3)); BCM2835_GPFSEL0 = x; x = BCM2835_GPFSEL1; x &= ~(0b111 << (0*3) | 0b111 << (1*3)); BCM2835_GPFSEL1 = x;}void transfer_data(){ char *buf; int i; /* acitvate transfer */ BCM2835_SPICS = SPI_CS_TA; /* send txBuf */ buf = (char *)txBuf; for (i=0; i<SPIBUFSIZE; i++) { BCM2835_SPIFIFO = *buf++; } /* wait until transfer is finished */ while (!(BCM2835_SPICS & SPI_CS_DONE)); /* clear done bit */ BCM2835_SPICS = SPI_CS_DONE; /* read buffer */ buf = (char *)rxBuf + 3; /* ignore 1st byte and align data */ for (i=0; i<SPIBUFSIZE; i++) { *buf++ = BCM2835_SPIFIFO; }}
直接访问树莓派的SPI,不通过驱动程序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。