I/O разширител за
RASPBERRY PI
Въпреки, че Raspberry-то има доста входно изходни линии много често те се оказват недостатъчни.
Един бърз и лесен начин за добавяне на входно изходни линии е използването на I/O разширителя на Microchip MCP23S17.
Комуникацията с този чип се осъществява по I2C (MCP23017) или SPI (MCP23S17) шина.
За щастие в линукс кърнела има драйвер и за двата вида комуникация.
Ако искаме да използваме SPI шина трябва да направим следното:
1. Променя се файла "arch/arm/mach-bcm2708/bcm2708.c" от сорсовете на кърнела. Като частта
#ifdef CONFIG_SPI
static struct spi_board_info bcm2708_spi_devices[] = {
{
.modalias = "spidev",
.max_speed_hz = 500000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
}, {
.modalias = "spidev",
.max_speed_hz = 500000,
.bus_num = 0,
.chip_select = 1,
.mode = SPI_MODE_0,
}
};
#endif
придобива следният вид:
#ifdef CONFIG_SPI
#include <linux/spi/mcp23s08.h>
static const struct mcp23s08_platform_data mcp23017_data = {
.chip[0] = {
.is_present = true,
.pullups = 0x00ff,
},
.base = 0x37,
};
static struct spi_board_info bcm2708_spi_devices[] = {
{
.modalias = "spidev",
.max_speed_hz = 500000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
}, {
.modalias = "mcp23s17",
.max_speed_hz = 8000000,
.bus_num = 0,
.chip_select = 1,
.platform_data = &mcp23017_data,
.mode = SPI_MODE_0,
}
};
#endif
В случая MCP23S17 чипа е свързан към CS1 на SPI шината.
2. Кърнела се прекомпилира по подобие на инструкциите описани тук
3. Във файла /etc/modprobe.d/raspi-blacklist.conf се коментира реда blacklist spi-bcm2708
4. След рестарт при успешно зареждане на модулите се появява следната директория /sys/class/gpio/gpiochip55
Простичък тест на работоспособноста на разширителя може да се направи, като се изпълнят следните команди
echo 55 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio55/direction
cat /sys/class/gpio/gpio55/value
Последната команда показва състоянието на входа GPA0 на MCP23S17
Ако искаме да изпоззваме GPA0 като изход
echo 55 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio55/direction
echo 1 > /sys/class/gpio/gpio55/value
или
echo 0 > /sys/class/gpio/gpio55/value
Простичка програмка за, която сменя състоянието на GPA0 през 250ms:
/*
* 23s17.c
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <sys/time.h>
#include <stdio.h>
int main(int argc, char **argv) {
int i=0;
FILE *fd;
struct pollfd pfd;
char buf[128];
fd = fopen ("/sys/class/gpio/export", "wb" );
fprintf(fd,"55");
fflush(fd);
fclose(fd);
fd = fopen ("/sys/class/gpio/gpio55/direction", "wb" );
fprintf(fd,"out");
fflush(fd);
fclose(fd);
pfd.fd = open("/sys/class/gpio/gpio55/value", O_RDWR );
while (1){
if (i==1){
buf[0]='0';
write(pfd.fd, buf, 1);
i=0;
}else{
buf[0]='1';
write(pfd.fd, buf, 1);
i=1;
}
usleep(250000);
}
return 0;
}
компилира се по следният начин gcc 23s17.c -o 23s17
и се стартира посредством ./23с17
Коментари:
Нов коментар