I am unable to interface mcp 3008 with beaglebone green.trying to set communication in mode 0(CPOL =0 CPHA=0),the built in frequency in dts is set to 1Mhz.
things I have tried
1.enable device tree BB-SPI0-MCP3008-00A0.dts
on execution of
ls -al /dev/spidev1.*
I got
crw-rw---- 1 root spi 153, 0 Oct 7 16:40 /dev/spidev1.1
2.on execution of cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pingroups
group: pinmux_bb_spi0_pins pin 84 (PIN84) pin 85 (PIN85) pin 86 (PIN86) pin 87 (PIN87)
My reference code is as follow
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define ARRAY_SIZE(array) sizeof(array) / sizeof(array[0])
static const char *DEVICE = "/dev/spidev1.1";
static uint8_t MODE = SPI_MODE_0;
static uint8_t BITS = 8;
static uint32_t CLOCK = 1000000;
static uint16_t DELAY = 5;
/* * Ensure all settings are correct for the ADC */
static int prepare(int fd)
{
if (ioctl(fd, SPI_IOC_WR_MODE, &MODE) == -1)
{
perror("Can't set MODE"); return -1;
}
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &BITS) == -1)
{
perror("Can't set number of BITS");
return -1;
}
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &CLOCK) == -1)
{
perror("Can't set write CLOCK");
return -1;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &CLOCK) == -1)
{
perror("Can't set read CLOCK"); return -1;
}
return 0;
}
/* * (SGL/DIF = 0, D2=D1=D0=0) */
uint8_t control_bits_differential(uint8_t channel)
{
return (channel & 7) << 4;
}
/* * (SGL/DIF = 1, D2=D1=D0=0) */
uint8_t control_bits(uint8_t channel)
{
return 0x8 | control_bits_differential(channel);
}
/* * Given a prep'd descriptor, and an ADC channel, fetch the * raw ADC
value for the given channel. */
int readadc(int fd, uint8_t channel)
{
uint8_t tx[] = {1, control_bits(channel), 0
};
uint8_t rx[3]={0,0,0};
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = DELAY,
.speed_hz = CLOCK,
.bits_per_word = BITS, };
if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) == 1)
{
perror("IO Error");
abort();
}
return ((rx[1] << 8) & 0x300) | (rx[2] & 0xFF);
}
int main(int argc, char **argv)
{
int fd = open(DEVICE, O_RDWR);
if (fd <= 0)
{
printf("Device %s not found\n", DEVICE);
return -1;
}
if (prepare(fd) == -1)
{ return -1; }
uint8_t i,radc=0;
for(i = 0;i < 8;i++)
{ printf("Channel %d: %d\n", i + 1, readadc(fd, i)); }
close(fd);
return 0;
}
after executing this code I am getting 1023 count for any applied voltage,where I am expecting count 0 for 0 input voltage and so on . Can anybody please help me? can you tell me where I am doing wrong?what are the other things I have to consider while using SPI on beaglebone?any kind of help will be greatly appreciated!
solved it as suggested from other forum it was hardware related thing.I have to put 0.1uf capacitor between vcc and gnd,where analog ground and digital ground were common.