Hello All,
I just started to use BBB a couple days. My goal is trying to test the connection between the BBB and the Arduino over SPI.
I did some research on the internet and and borrow some of the code just to see if the result is the same as I expect.
- I make sure the SPI pins of the BBB is working by using the spidev_test.c and the result as below:
sedf
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
0xF0, 0x0D,
2) So, I tried to send to the Arduino some bytes and expected that the Arduino would show the result on the Serial Monitor. However, the Aruino seems not to get the correct the message.
I'm not sure the voltage difference between Arduino and BBB has anything to do with this.
Please see the code for the BBB and The BBB below:
Arduino: I looked at Nick Gammon blog and started to follow his example to make Arduino as slave
//this code is written by by Nick Gammon
#include <SPI.h>
char buf [100];
volatile byte pos;
volatile boolean process_it;
void setup (void)
{
Serial.begin (9600); // debugging
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = 0;
// now turn on interrupts
SPI.attachInterrupt();
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
char c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < sizeof buf)
{
buf [pos++] = c;
Serial.println(buf[pos],HEX);
// example: newline means time to process buffer
if (c == 0x04)
process_it = 1;
} // end of room available
} // end of interrupt routine SPI_STC_vect
// main loop - wait for flag set in interrupt routine
void loop (void)
{
if (process_it == 1)
{
buf [pos] = 0;
Serial.println("SPI");
Serial.println (buf);
pos = 0;
process_it = 0;
} // end of flag set
} // end of loop
and BBB:
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
//define some constant variables
#define PATH "/dev/spidev2.0"
static uint16_t delay =0;
static uint32_t speed = 100000;
static uint8_t bits = 8;
static uint8_t mode = 0;
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void write_data(int fd){
int ret;
char tx[]= {0x08,0x01,0x04};
char rx[ARRAY_SIZE(tx)] = {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 = speed,
.bits_per_word = bits,
};
ret = ioctl(fd,SPI_IOC_MESSAGE(1),&tr);
if (ret<0){
perror("SPI_IOC_MESSAGE");
}
}
int main(void) {
int ret,fd;
fd = open(PATH,O_RDWR);
if (fd<0){
perror("Bad fd open - check PATH");}
//setup SPI mode
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if(ret<0){
perror("SPI_IOC_WR_MODE");}
ret = ioctl(fd,SPI_IOC_RD_MODE,&mode);
if(ret<0){
perror("SPI_IOC_RD_MODE");}
ret = ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&bits);
if(ret<0){
perror("SPI_IOC_WR_BITS_PER_WORD");}
ret = ioctl(fd,SPI_IOC_RD_BITS_PER_WORD,&bits);
if(ret<0){
perror("SPI_IOC_RD_BITS_PER_WORD");}
ret = ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&speed);
if(ret<0){
perror("SPI_IOC_WR_MAX_SPEED_HZ");}
ret = ioctl(fd,SPI_IOC_RD_MAX_SPEED_HZ,&speed);
if(ret<0){
perror("SPI_IOC_RD_MAX_SPEED_HZ");}
write_data(fd); // send data
usleep(100*1000);
close(fd);
return 0;
}
Any comment/suggestion/answer would help. If I write anything wrong, please feel free to point it out.
Also, this is first time I ask question online and join a forum.
Thank you.
Khoa