BeagleBone Green Wireless SPI only reads least Significant Nibble and spreads in a byte.

I have the SPI working for full duplex, but for a half-duplex device.

The issue is the receive array does not return the correct values.

The O-Scope shows the device is returning the correct values but they are recorded as the least significant nibble…doubled.

If 0x01 is returned I have 0x03 stored in the array. If 0x0A is returned I have 0xCC stored in the array. It’s as if the “read” only works for the final 4 bits and at double the speed. Any data in the high nibble is lost.

Has anyone experienced this before or know of something I can do to have the correct values stored?

This is the code I used.

int fd, i=0; //file handle and loop counter
unsigned char value, null=0x00; //sending only a single char
uint8_t bits = 8, mode = 0; //8-bits per word, SPI mode 3
uint32_t speed = 4000000; //Speed is 4 MHz (Not Really due to clock, but it works)

unsigned char send_buffer[3];
unsigned char receive_buffer[3];

int transfer(int fd, unsigned char send[], unsigned char receive[], int length){

struct spi_ioc_transfer transfer[3]; //the transfer structure
memset(&transfer, 0, sizeof(transfer));

transfer[0].cs_change = 0;
transfer[0].tx_buf = (unsigned long) send; //the buffer for sending data
transfer[0].rx_buf = (unsigned long) receive; //the buffer for receiving data
transfer[0].len = length; //the length of buffer
transfer[0].speed_hz = speed; //the speed in Hz
transfer[0].bits_per_word = bits; //bits per word
transfer[0].delay_usecs = 0; //delay in us
transfer[0].pad = 0; //delay in us
transfer[0].rx_nbits = 8; //delay in us

// send the SPI message (all of the above fields, inc. buffers)
int status = ioctl(fd, SPI_IOC_MESSAGE(1), &transfer);
if (status < 0) {
printf(“SPI: SPI_IOC_MESSAGE Failed:\t%i”, status);
return -1;
}

}

int main(){

// The following calls set up the SPI bus properties
if ((fd = open(SPI_PATH, O_RDWR))<0){
perror(“SPI Error: Can’t open device.”);
return -1;
}
if (ioctl(fd, SPI_IOC_WR_MODE, &mode)==-1){
perror(“SPI: Can’t set SPI mode.”);
return -1;
}
if (ioctl(fd, SPI_IOC_RD_MODE, &mode)==-1){
perror(“SPI: Can’t get SPI mode.”);
return -1;
}
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits)==-1){
perror(“SPI: Can’t set bits per word.”);
return -1;
}
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits)==-1){
perror(“SPI: Can’t get bits per word.”);
return -1;
}
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed)==-1){
perror(“SPI: Can’t set max speed HZ”);
return -1;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed)==-1){
perror(“SPI: Can’t get max speed HZ.”);
return -1;
}

// Check that the properties have been set
printf(“SPI Mode is: %d\n”, mode);
printf(“SPI Bits is: %d\n”, bits);
printf(“SPI Speed is: %d\n”, speed);
printf(“Attempting to right IDLE to CC1101:\n”);

transfer(fd, send_buffer, receive_buffer, 2);

}