I've connected a si4438 rf controller on RPI3 SPI0(miso,mosi,sclk,ce0, some other gpios etc), and now soft gpio emulated SPI works fine.
But when I changed to hard spi, It doesn't work. BTW, I don't have a scope



I'm sure spi mode should be 0.
thanks for any suggestions. here's my key functions below:
Software emulated read/write, works fine:
Code: Select all
int radio_hal_SpiWriteByte(radioCtrlHandle* handle, uint8_t byteToWrite)
{
unsigned char bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
if (byteToWrite&0x80){
GPIOWrite(handle->pins.RF446x_SDI_PORT, GPIO_PIN_SET);
}
else{
GPIOWrite(handle->pins.RF446x_SDI_PORT, GPIO_PIN_RESET);
}
byteToWrite = (byteToWrite << 1); // shift next bit into MSB..
usleep(1);
GPIOWrite(handle->pins.RF446x_SCLK_PORT, GPIO_PIN_SET);
usleep(1);
GPIOWrite(handle->pins.RF446x_SCLK_PORT, GPIO_PIN_RESET);
usleep(1);
}
return 0;
}
int radio_hal_SpiReadByte(radioCtrlHandle* handle, uint8_t* byteToRead)
{
unsigned char bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
*byteToRead = (*byteToRead << 1); // shift next bit into MSB..
GPIOWrite(handle->pins.RF446x_SCLK_PORT, GPIO_PIN_SET);
usleep(1);
if (GPIORead(handle->pins.RF446x_SDO_PORT) != 0){
*byteToRead |= 0x01;
}
else{
*byteToRead &= ~0x01;
}
GPIOWrite(handle->pins.RF446x_SCLK_PORT, GPIO_PIN_RESET);
usleep(1);
}
return 0;
}
I've tried initialize spi device with SPI_NO_CS flag and control CS manually in hard spi mode,
or without SPI_NO_CS flag and remarked gpio-cs-read-write functions,
but both not working.
Code: Select all
radio_hal_ClearNsel(handle);
radio_hal_SpiWriteByte(handle, 0x44); //read CMD buffer
radio_hal_SpiReadByte(handle, &ctsVal);
radio_hal_SetNsel(handle);
hard spi functions:
Code: Select all
int spiInitialize( spiCtrlHandle* handle,
const char *device,
const uint8_t mode,
const uint8_t bits,
const int32_t speed,
const uint16_t delay)
{
int ret = 0;
/* device */
handle->fd = open(device, O_RDWR);
if (handle->fd < 0)
syslog(LOG_LEVEL_FAIL, "FAIL:SPI:can't open %s\n", device);
/* spi mode */
ret = ioctl(handle->fd, SPI_IOC_WR_MODE, &mode);
if(ret==-1)
syslog(LOG_LEVEL_FAIL, "FAIL:SPI:can't set spi mode\n");
if(ioctl(handle->fd, SPI_IOC_RD_MODE, &mode)<0)
syslog(LOG_LEVEL_WARNING, "WARN:SPI:can't get spi mode\n");
/* bits per word */
ret = ioctl(handle->fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if(ret==-1)
syslog(LOG_LEVEL_FAIL, "FAIL:SPI:can't set bits per word\n");
if(ioctl(handle->fd, SPI_IOC_RD_BITS_PER_WORD, &bits)<0)
syslog(LOG_LEVEL_WARNING, "WARN:SPI:can't get bits per word\n");
/* max speed hz */
ret = ioctl(handle->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if(ret==-1)
syslog(LOG_LEVEL_FAIL, "FAIL:SPI:can't set max speed hz\n");
if(ioctl(handle->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed)<0)
syslog(LOG_LEVEL_WARNING, "WARN:SPI:can't get max speed hz\n");
if(ret==-1) return ret;
handle->bits = bits;
handle->speed = speed;
handle->delay = delay;
return 0;
}
int spiTransfer(spiCtrlHandle* handle, uint8_t* txData, uint8_t *rxBuf, int len)
{
int ret;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)txData,
.rx_buf = (unsigned long)rxBuf,
.len = len,
.delay_usecs = handle->delay,
.speed_hz = handle->speed,
.bits_per_word = handle->bits,
};
ret = ioctl(handle->fd, SPI_IOC_MESSAGE(1), &tr);
return ret;
}
Code: Select all
spiInitialize(hSpi, "/dev/spidev0.0", SPI_MODE_0, 8, 500000, 0);
Code: Select all
radio_hal_SpiWriteByte(uint8_t byteToWrite)
spiTransfer(handle->pins.handle, &byteToWrite, NULL, 1);
radio_hal_SpiReadByte(uint8_t* byteToRead)
spiTransfer(handle->pins.handle, NULL, byteToRead, 1);