/****************************************************************************** * @fn perCC1120CC1190EnterIdle * * @brief Enters IDLE from ANY state. Function is used to abstract the * cc1120cc1190RadioTxRx functionality away from the lower-level radio * interface. * * input parameters * * @param none * * output parameters * * @return void */ void perCC1120CC1190EnterIdle(void) { /* wait until chip is ready */ TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); cc1120cc1190RxIdle(); cc1120cc1190RadioTxRx = CC112X_STATE_IDLE; return; }
/****************************************************************************** * @fn perCC115LEnterIdle * * @brief Enters IDLE from ANY state. Function is used to abstract the * cc11xLRadioTxIdle functionality away from the lower-level radio * interface. * * input parameters * * @param none * * output parameters * * @return void */ void perCC115LEnterIdle(void) { /* wait until chip is ready */ TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); cc115LTxIdle(); cc115LRadioTxIdle = CC115L_STATE_IDLE; return; }
/******************************************************************************* * @fn trxSpiCmdStrobe * * @brief Send command strobe to the radio. Returns status byte read * during transfer of command strobe. Validation of provided * is not done. Function assumes chip is ready. * * input parameters * * @param cmd - command strobe * * output parameters * * @return status byte */ rfStatus_t trxSpiCmdStrobe(uint8 cmd) { uint8 rc; TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); TRXEM_SPI_TX(cmd); TRXEM_SPI_WAIT_DONE(); rc = TRXEM_SPI_RX(); TRXEM_SPI_END(); return(rc); }
/******************************************************************************* * @fn trx8BitRegAccess * * @brief This function performs a read or write from/to a 8bit register * address space. The function handles burst and single read/write * as specfied in addrByte. Function assumes that chip is ready. * * input parameters * * @param accessType - Specifies if this is a read or write and if it's * a single or burst access. Bitmask made up of * RADIO_BURST_ACCESS/RADIO_SINGLE_ACCESS/ * RADIO_WRITE_ACCESS/RADIO_READ_ACCESS. * @param addrByte - address byte of register. * @param pData - data array * @param len - Length of array to be read(TX)/written(RX) * * output parameters * * @return chip status */ rfStatus_t trx8BitRegAccess(uint8 accessType, uint8 addrByte, uint8 *pData, uint16 len) { uint8 readValue; /* Pull CS_N low and wait for SO to go low before communication starts */ TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); /* send register address byte */ TRXEM_SPI_TX(accessType|addrByte); TRXEM_SPI_WAIT_DONE(); /* Storing chip status */ readValue = TRXEM_SPI_RX(); trxReadWriteBurstSingle(accessType|addrByte,pData,len); TRXEM_SPI_END(); /* return the status byte value */ return(readValue); }
/****************************************************************************** * @fn trx16BitRegAccess * * @brief This function performs a read or write in the extended adress * space of CC112X. * * input parameters * * @param accessType - Specifies if this is a read or write and if it's * a single or burst access. Bitmask made up of * RADIO_BURST_ACCESS/RADIO_SINGLE_ACCESS/ * RADIO_WRITE_ACCESS/RADIO_READ_ACCESS. * @param extAddr - Extended register space address = 0x2F. * @param regAddr - Register address in the extended address space. * @param *pData - Pointer to data array for communication * @param len - Length of bytes to be read/written from/to radio * * output parameters * * @return rfStatus_t */ rfStatus_t trx16BitRegAccess(uint8 accessType, uint8 extAddr, uint8 regAddr, uint8 *pData, uint8 len) { uint8 readValue; TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); /* send extended address byte with access type bits set */ TRXEM_SPI_TX(accessType|extAddr); TRXEM_SPI_WAIT_DONE(); /* Storing chip status */ readValue = TRXEM_SPI_RX(); TRXEM_SPI_TX(regAddr); TRXEM_SPI_WAIT_DONE(); /* Communicate len number of bytes */ trxReadWriteBurstSingle(accessType|extAddr,pData,len); TRXEM_SPI_END(); /* return the status byte value */ return(readValue); }
/****************************************************************************** * @fn chipDetectRadio() * * @brief This function detects if a chip is present on the EM * socket. SPI initialization must be done before this function * can be called. * Note: Currently able to detect CC1101, CC110L, CC113L, CC115L, CC2500 * * input parameters * * @param pRadioChipType - pointer to radioChipType_t struct * * output parameters * * @return 2 byte chip type */ static uint16 trxChipDetectRadio(radioChipType_t *pRadioChipType) { volatile uint8 id; volatile uint8 ver; volatile uint16 type; // Relies on automatic POR // Pull CSn low and wait for MISO goes low => clock ready TRXEM_SPI_BEGIN(); TRXEM_SPI_WAIT_MISO_LOW(id); // Wait for MISO Low if(id == 0) return CHIP_TYPE_NONE; // Return if failed TRXEM_SPI_TX(CC1101_READ_BURST | CC1101_PARTNUM_ADDR); // [7:6] = READ_BURST, [5:0] = part number address TRXEM_SPI_WAIT_DONE(); TRXEM_SPI_TX(0x00); TRXEM_SPI_WAIT_DONE(); id = TRXEM_SPI_RX(); TRXEM_SPI_TX(CC1101_READ_BURST | CC1101_VERSION_ADDR); // [7:0] = ADDR TRXEM_SPI_WAIT_DONE(); TRXEM_SPI_TX(0x00); TRXEM_SPI_WAIT_DONE(); ver = TRXEM_SPI_RX(); TRXEM_SPI_END(); if(id == 0x00 ) { switch(ver) { case 0x04: type = CHIP_TYPE_CC1101; break; case 0x07: type = CHIP_TYPE_CC110L; break; case 0x08: type = CHIP_TYPE_CC113L; break; case 0x09: type = CHIP_TYPE_CC115L; break; default: type = CHIP_TYPE_NONE; } } else if(id == 0x80 ) { switch(ver) { case 0x03: type = CHIP_TYPE_CC2500; break; default: type = CHIP_TYPE_NONE; } } else { type = CHIP_TYPE_NONE; } // Populating the global radio device struct if specific radio was detected if(type != CHIP_TYPE_NONE) { pRadioChipType->id = id; pRadioChipType->ver = ver; pRadioChipType->deviceName = type; } return type; }
/****************************************************************************** * @fn trxChipDetectCC112x() * * @brief This function detects if a CC112x chip is present in the EM * socket. SPI initialization must be ensured before this function * can be called. * * input parameters * * @param pRadioChipType - pointer to radioChipType_t struct * * output parameters * * @return 2 byte chip type */ static uint16 trxChipDetectCC112x(radioChipType_t *pRadioChipType) { volatile uint8 id; volatile uint8 ver; volatile uint16 type; // Pin reset RF_RESET_N_PORT_SEL &= ~RF_RESET_N_PIN; RF_RESET_N_PORT_DIR |= RF_RESET_N_PIN; RF_RESET_N_PORT_OUT &= ~RF_RESET_N_PIN; // keep reset pin low __delay_cycles(1000000); RF_RESET_N_PORT_OUT |= RF_RESET_N_PIN; // Release reset // Pull CSn low and wait for MISO goes low => clock ready TRXEM_SPI_BEGIN(); TRXEM_SPI_WAIT_MISO_LOW(id); // Wait for MISO Low if(id == 0) return CHIP_TYPE_NONE; // Return if failed TRXEM_SPI_TX(CC1120_READ_BURST | CC1120_EXT_MEM_ACCESS); // [7:6] = READ_BURST, [5:0] = extended memory access address TRXEM_SPI_WAIT_DONE(); TRXEM_SPI_TX(CC1120_PARTNUMBER_ADDR); // [7:0] = Partnumber address TRXEM_SPI_WAIT_DONE(); TRXEM_SPI_TX(0x00); TRXEM_SPI_WAIT_DONE(); id = TRXEM_SPI_RX(); TRXEM_SPI_TX(0x00); TRXEM_SPI_WAIT_DONE(); ver = TRXEM_SPI_RX(); TRXEM_SPI_END(); switch(id) { case 0x40: //CC1121 type = CHIP_TYPE_CC1121; break; case 0x48: // CC1120 type = CHIP_TYPE_CC1120; break; case 0x58: //CC1125 type = CHIP_TYPE_CC1125; break; case 0x5A: //CC1175 type = CHIP_TYPE_CC1175; break; case 0x20://CC1200 type = CHIP_TYPE_CC1200; break; case 0x21://CC1201 type = CHIP_TYPE_CC1201; break; default: type = CHIP_TYPE_NONE; } // Populating the global radio device struct if specific radio was detected if(type != CHIP_TYPE_NONE) { pRadioChipType->id = id; pRadioChipType->ver = ver; pRadioChipType->deviceName = type; } return type; }