I am being blocked from uploading PDF files, so datasheets are attached as links instead of direct attachments. If I've omitted any useful information, let me know and I'll be happy to include it.
I am trying to communicate with an Si4455 RF transceiver over SPI with an Arduino Uno R3. I have a breakout board for the Si4455, not sure exactly which part # it is but it was purchased here. This chip can only take up 3.6V, so the Arduino is connected through a TXS0108 level shifter.
Si4455 Programming Guide
Si4455 Datasheet
TXS0108 Datasheet
Schematic of my setup:
I am starting simple, just trying to send the simple PART_INFO command so I can be sure everything is working. However, the only response I am getting from the chip is 0xFF, no matter what I do or what commands I send.
Here's my sketch:
#include <SPI.h>
#define SDN 8 // Shutdown pin
#define nSEL 10 // Chip Select (SPI CS)
#define nIRQ 9 // Interrupt pin
#define SCK 13 // SPI Clock
#define MISO 12 // SPI MISO
#define MOSI 11 // SPI MOSI
void setup() {
Serial.begin(115200);
Serial.println("Starting Si4455 SPI Test...");
pinMode(SDN, OUTPUT);
pinMode(nSEL, OUTPUT);
pinMode(nIRQ, INPUT);
pinMode(SCK, OUTPUT);
pinMode(MISO, INPUT);
pinMode(MOSI, OUTPUT);
digitalWrite(nSEL, HIGH); // Ensure SPI is inactive before startup
digitalWrite(SDN, HIGH);
delayMicroseconds(15); // 10microsecond minmum hold time in case SDN was previously high
digitalWrite(SDN, LOW); // Bring Si4455 out of shutdown
delay(6); // Ensure Si4455 fully wakes up (6ms minimum)
SPI.begin();
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(nSEL, LOW);
uint8_t powerUp[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
for(auto i:powerUp){
SPI.transfer(i);
}
digitalWrite(nSEL, HIGH);
wait_for_cts();
// Verify SPI communication with PART_INFO
get_part_info();
}
void loop() {
}
void wait_for_cts() {
uint8_t CTS = 0x00;
unsigned long startTime = millis();
Serial.println("Waiting for CTS byte to be 0xFF...");
while (CTS != 0xFF) {
digitalWrite(nSEL, LOW);
SPI.transfer(0x44); // READ_CMD_BUFF
delayMicroseconds(2);
CTS = SPI.transfer(0xFF);
digitalWrite(nSEL, HIGH);
delay(1);
// if (millis() - startTime > 100) { // Timeout after 10ms
// Serial.println("ERROR: CTS did not become 0xFF!");
// return;
// }
}
Serial.println("Clear to send command.");
}
void get_int_status() {
uint8_t response[8];
digitalWrite(nSEL, LOW);
SPI.transfer(0x20); // GET_INT_STATUS command
SPI.transfer(0x00); // Clear all flags (PH_CLR_PEND, MODEM_CLR_PEND, CHIP_CLR_PEND)
SPI.transfer(0x00);
SPI.transfer(0x00);
digitalWrite(nSEL, HIGH);
delayMicroseconds(5);
wait_for_cts();
digitalWrite(nSEL, LOW);
for (int i = 0; i < 8; i++) {
response[i] = SPI.transfer(0xFF);
delayMicroseconds(2);
}
digitalWrite(nSEL, HIGH);
Serial.println("INT_STATUS Response:");
for (int i = 0; i < 8; i++) {
Serial.print("Byte ");
Serial.print(i + 1);
Serial.print(": 0x");
Serial.println(response[i], HEX);
}
}
void get_part_info() {
uint8_t response[8];
digitalWrite(nSEL, LOW);
delayMicroseconds(2);
SPI.transfer(0x01); // PART_INFO command
digitalWrite(nSEL, HIGH);
delayMicroseconds(5);
wait_for_cts(); // Ensure CTS is high before reading
digitalWrite(nSEL, LOW);
for (int i = 0; i < 8; i++) {
response[i] = SPI.transfer(0x00);
delayMicroseconds(2);
}
digitalWrite(nSEL, HIGH);
Serial.println("PART_INFO Response:");
for (int i = 0; i < 8; i++) {
Serial.print("Byte ");
Serial.print(i + 1);
Serial.print(": 0x");
Serial.println(response[i], HEX);
}
}
The serial ouput:
09:44:12.342 -> Starting Si4455 SPI Test...
09:44:12.386 -> Waiting for CTS byte to be 0xFF...
09:44:12.386 -> Clear to send command.
09:44:12.386 -> Waiting for CTS byte to be 0xFF...
09:44:12.386 -> Clear to send command.
09:44:12.386 -> PART_INFO Response:
09:44:12.386 -> Byte 1: 0xFF
09:44:12.386 -> Byte 2: 0xFF
09:44:12.386 -> Byte 3: 0xFF
09:44:12.386 -> Byte 4: 0xFF
09:44:12.386 -> Byte 5: 0xFF
09:44:12.386 -> Byte 6: 0xFF
09:44:12.386 -> Byte 7: 0xFF
09:44:12.386 -> Byte 8: 0xFF
I've attached some logic analyzer (attached on the Si4455 side of the level shifter) screenshots in case they're helpful, I'm not sure what to make of them though:


