Hey TI and RF Community,
I write to request help with a problem that has me truly stumped. I'm developing a mesh network using the CC1010, that sensors the RSSI between nodes. This is then used to infer distance after averaging. The problem I'm facing is that many of the RSSI values read by the ADC are way out of the anticipated range. When I have two nodes beside each other, the RSSI values should be about -55dBm, when the nodes are alternativly transmitting and reciving packets the RSSI values that the nodes output vary by 25dBm. However a node in receive only mode (which prints debug RSSI values) gives values that fall withing 2dBm of the anticipated value. I have concluded that the line of code causing the problem is the carrier sense routine. I'm assuming that calling RFReadRSSIlevel() (used for carrier sense) changes the configeration of the ADC in some way that affects measurements performed by the following RFReceivePacket(). How do I perform a carrier sense that doesn't result in the return of nonscence RSSI values? Thanks in advance! Nathan
So if i comment out this in node 1:
(*) rssi_val_ti2 = halRFReadRSSIlevel2(RSSI_MODE_RUN, &rssi_val_adc2); // RSSI value using standard TI function
Then node 1, never transmits and only receives data from Node 2. In this case all the values are about -59dBm (RAW ADC Val = 17(ish))
However I can't comment out this line on nodes, because for the mesh to work I need the nodes to transmit! But when I put the carrier sense line back in ((*)-above ) then sporadic values will be reported at about -84dBm (RAW ADC value 140(ish)).
Here is the code, less bits that shouldn't make too much difference:
Note: I've modified some of the functions to return the raw ADC value and the RSSI value.
void main(void) {
....
...
while (TRUE) {
ran = rand() % 100 + 10;
result = halRFReceivePacket2(ran, &receivedString[0],
TEST_STRING_LENGTH, &rssi_val_ti, &rssi_val_adc,
CC1010EB_CLKFREQ); //Check for incoming packets for random time for CSMA/CA
if (BROADCAST_PACKET_RECEIVED) { //Check if a broadcast round packet has been received.
processBroadcastPacket(receivedString[0], rssi_val_adc, rssi_val_ti);
}
...
...
if (BROADCAST_MODE && result == 0) {
(*) rssi_val_ti2 = halRFReadRSSIlevel2(RSSI_MODE_RUN, &rssi_val_adc2);
}
if (BROADCAST_MODE && CHANNEL_FREE) { // No carrier detected, safe to Transmit
sendBroadcastPacket(BROADCAST_TYPE);
}
}
} // end of main()
void processBroadcastPacket(byte broadcastByte, byte rssi_val_adc_local,
signed char rssi_val_ti_local) {
...
...
#ifdef DEBUG_3
printf("Debug: RSSI(TI1)=%i\tRSSI(ADC)=%i\n\r",
(signed int) rssi_val_ti_local, rssi_val_adc_local);
#endif
...
...
return;
}
//-------------
signed char halRFReadRSSIlevel2(byte rssi_mode, byte* rssiByteADC) {
byte val = 0;
byte adc_val = 0;
// If RSSI mode = run/continuous
if (rssi_mode == RSSI_MODE_RUN) {
// Configure ADC for RSSI reading
halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25,
CC1010EB_CLKFREQ, 0);
// Turn on ADC
ADC_POWER(TRUE);
// Wait until ADC stabilized
halWait(1, CC1010EB_CLKFREQ);
// Select RSSI input and read sample
ADC_SELECT_INPUT(ADC_INPUT_AD2);
ADC_SAMPLE_SINGLE();
adc_val = ADC_GET_SAMPLE_8BIT(); // Get 8 MSB of sample
// Convert value into dBm
val = -57 - ((adc_val * 49) >> 8);
// Else (RSSI mode = initialisation)
*rssiByteADC = adc_val;
} else {
// Activate RSSI output
FREND |= 0x02;
// Configure ADC for RSSI reading
halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25,
CC1010EB_CLKFREQ, 0);
// Turn on ADC
ADC_POWER(TRUE);
// Wait until ADC stabilized
halWait(200, CC1010EB_CLKFREQ);
}
---------
byte halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength,
signed char* rssiByte, byte* rssiByteADC, word clkFreq) {
byte receivedBytes, pkgLen, crcData, i;
word crcReg;
halConfigTimer23(TIMER3 | TIMER23_NO_INT_TIMER, 1000, clkFreq);
INT_SETFLAG(INUM_TIMER3, INT_CLR);
TIMER3_RUN(TRUE);
RF_SET_PREAMBLE_COUNT(16);
RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE);
MODEM1 = (MODEM1 & 0x03) | 0x24; // Make sure avg filter is free-running + 22 baud settling time
INT_ENABLE(INUM_RF, INT_OFF);
INT_SETFLAG(INUM_RF, INT_CLR);
RF_START_RX();
while (1) {
// Check if 1 ms has passed
if (INT_GETFLAG(INUM_TIMER3)) {
// Clear interrupt flag and decrement timeout value
INT_SETFLAG(INUM_TIMER3, INT_CLR);
if (timeOut && !--timeOut) {
timeOut = 255;
break; // Timeout
}
}
// Check if sync byte received
if (INT_GETFLAG(INUM_RF)) {
EXIF &= ~0x10; // Clear the flag
break;
}
}
receivedBytes = 0;
// Timeout or sync byte received?
if (timeOut != 255) {
// Lock average filter and perform RSSI reading if desired
RF_LOCK_AVERAGE_FILTER(TRUE);
// Get length of package
RF_WAIT_AND_RECEIVE_BYTE( pkgLen );
pkgLen += 2; // Add the two CRC bytes
if (rssiByte) {
*rssiByte = halRFReadRSSIlevel2(RSSI_MODE_RUN, rssiByteADC);
}
// Initialize CRC-16
crcReg = CRC16_INIT;
// Receive as many bytes as packet specifies + 2 crc bytes
while (pkgLen--) {
RF_WAIT_AND_RECEIVE_BYTE( crcData );
// If there is space in the buffer at _packetData_ and we're not
// currently receiving CRC, store the byte
if (pkgLen >= 2 && maxLength) {
*packetData++ = crcData;
receivedBytes++;
maxLength--;
}
// Calculate CRC-16 (CCITT)
for (i = 0; i < 8; i++) {
if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80))
crcReg = (crcReg << 1) ^ CRC16_POLY;
else
crcReg = (crcReg << 1);
crcData <<= 1;
}
}
// Check if CRC is OK
if (crcReg != CRC_OK)
receivedBytes = 0;
}
TIMER3_RUN(FALSE);
RF_SET_PREAMBLE_COUNT(RF_PREDET_OFF);
return receivedBytes;
}
//----------------------------------------------------------------------------