EihiS

August 27, 2013

A simple SPI schematic, using MCP23S17 I/O expander

Filed under: Raspberry 3.14 — Tags: , , , , , , , , , , — admin @ 12:37 pm

Once SPI enabled in Raspbian, here is a simple test wiring, using microchip’s MCP23S17  I/O spi/I2C expander.
The chip is powered by the Pi’s 3.3V supply.
Explanation about the wiring is not really needed, as the schematic is pretty straightsimple.

A dip switches section is used to configure the mcp23s17’s SPI adress if needed (3bit) and another dip is used to have a hard-reset button if things are going bad.

One can test the circuit by using, or example, PORTB as output, and wiring leds+ a 220Ohm resistor to the ground, to get a visual feedback of the PORT’s output state.Thats what i did..

Now, after a carefull read of the MCP chip datasheet, one can properly program the registers of the chip to use it.
for our test purposes, i’ll state that we use PORTB as output.

Compile on the Pi that code
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <linux/types.h>
#include <linux/spi/spidev.h>

#include <sys/ioctl.h>
const unsigned char init_mcp_mode[]={ 0×40,0×0a,0×20 }; // no auto-inc, et bank=0
const unsigned char init_mcp_trisb[]={ 0×40,0×01,0×00 }; // as output
int main(int argc, char *argv[])
{
int fd_spi;
unsigned char to_send[4];

int value;
unsigned char byte;

unsigned int speed = 250000;

if (argc != 3) {
fprintf(stderr, "usage: %s <spi-port> <spi-speed>n", argv[0]);
exit(EXIT_FAILURE);
}
fd_spi = open(argv[1], O_RDWR);
if (fd_spi < 0) {
perror(argv[1]);
exit(EXIT_FAILURE);
}

if (sscanf(argv[2], “%d”, & speed) != 1) {
fprintf(stderr, “Wrong value for speed: %sn”, argv[2]);
exit(EXIT_FAILURE);
}
if (ioctl(fd_spi, SPI_IOC_WR_MAX_SPEED_HZ, & speed) != 0) {
perror(”ioctl”);
exit(EXIT_FAILURE);
}
// setup mcp
printf(”Setup:\n”);
printf(”Mode …[%d]\n”,write(fd_spi,&init_mcp_mode,3 ));
printf(”TrisB…[%d]\n”,write(fd_spi,&init_mcp_trisb,3));
//

byte=0;
while(1)  // forever loop, byte increments
{
byte ++;
to_send[0]=0×40;
to_send[1]=0×15; // reg=latB
to_send[2]=byte;
to_send[3]=0; // unused
if (write(fd_spi, &to_send, 3) != 3) {
perror(”write DATA”);
exit(EXIT_FAILURE);
}
usleep(25000); // 26ms sleep
}
close(fd_spi);
return EXIT_SUCCESS;
}

Run the file :

$ ./mcp_roller /dev/spidev0.0 400000

If you have connected leds+resistors to the PORTB of the mcp23s17, you should see it binary couting, visually.

Briefly, as for the code, mcp is first initialized with bank=0, no auto-increment feature, by the sequence :
0×40 = 01000000 == 0100 (fixed) + 000 (chip addr) + 0 (=write). (nb : the code example does not use the SPI chip addressing feature )
0×0A = register 0Ah == IOCON register addr
0×20 = 0b00100000 == bank0, SEQOP = OFF

then , code sets up Direction of port B :
0×40,0×01,0×00 : register 01h , all outputs (00h)

then , the program loops in sending portB latch register (15h) values, from 0 to FFh.
Writing to the latch of Port B is : 0×40,0×15,value.

Large parts of this code comes from : http://www.blaess.fr/christophe/2012/11/02/spi-sur-raspberry-pi-1/

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

314159265358979323846264338327950288
419716939937510582097494459230781640
628620899862803482534211706798214808

cat{ } { post_459 } { } 2009-2015 EIhIS Powered by WordPress