void RF_init() { TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE //TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set IDLE TI_CC_SPIWriteReg (TI_CCxxx0_PATABLE,paTable[0]); // init at max powerlevel // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CCxxxx TI_CC_SW_PxREN |= TI_CC_SW1; // Enable Pull up resistor TI_CC_SW_PxOUT |= TI_CC_SW1; // Enable pull up resistor TI_CC_SW_PxIES |= TI_CC_SW1; // Int on falling edge TI_CC_SW_PxIFG &= ~(TI_CC_SW1); // Clr flags TI_CC_SW_PxIE |= TI_CC_SW1; // Activate interrupt enables TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU }
void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CCxxxx TI_CC_SW_PxREN |= TI_CC_SW1+TI_CC_SW2; // Enable pull-up resistor TI_CC_SW_PxOUT |= TI_CC_SW1+TI_CC_SW2; // Enable pull-up resistor TI_CC_SW_PxIES = TI_CC_SW1+TI_CC_SW2; // Int on falling edge TI_CC_SW_PxIFG &= ~(TI_CC_SW1+TI_CC_SW2); // Clr flags TI_CC_SW_PxIE = TI_CC_SW1+TI_CC_SW2; // Activate interrupt enables TI_CC_LED_PxOUT &= ~(TI_CC_LED1 + TI_CC_LED2); // Outputs = 0 TI_CC_LED_PxDIR |= TI_CC_LED1 + TI_CC_LED2;// LED Direction to Outputs TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU __bis_SR_register(LPM3_bits + GIE); // Enter LPM3, enable interrupts }
int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer //P2REN |= BIT3; // enable pull up resistor on p2.3 //P2OUT |= BIT3; // This does not seem to be working as expected. // Initialize radio and SPI TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE // Enable interrupts from radio module TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet // Enable radio TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // configure packet // -------------------------------------------- txBuffer[0] = MSGLEN-1; // Packet length txBuffer[1] = 0x01; // Packet address - If this is 0xFF, it's an ack and not data. // Begin data // -------------------------------------------- txBuffer[2] = VALID_LEVEL; // default flag is valid. This is set on request from other module. txBuffer[3] = 0x30; txBuffer[4] = 0x31; txBuffer[5] = 0x34; txBuffer[6] = 0x35; txBuffer[7] = 0x36; txBuffer[8] = 0x37; txBuffer[9] = 0x38; txBuffer[10] = 0x39; // the rest of this data is used as filler. // ------ // End Data txBuffer[11] = 0x00; // terimate // -------------------------------------------- _BIS_SR(GIE); // turn on interrupts. Initialization must be complete by this point while(1) { if(water_level_request) { // Ideally, P2.3 should be pulled high. This is causing strange behavior // on the pin that should be investigated. // Check the status of P2.3 and set the r txBuffer[WATER_DATA_TX_INDEX] = (P2IN & BIT3) ? 0 : VALID_LEVEL;// turn on the pump if the water level is valid. RFSendPacket(txBuffer, MSGLEN); // Send water level data back to controller __delay_cycles(450000); // delay a few cycles. Note that this means requests that take place during // a pump cycle will be ignored completely. water_level_request = 0; // clear requested data flag } } }
void RadioInit(void) { TI_CC_SPISetup(); // Initialize SPI port del PIC TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx IoWait(200); WriteRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE ModeRecepcio(); // Capturo l'adreça local i l'adreça del control remot des de l'eeprom. EEGetShortMAC(LocalAddress); #ifdef _DEPURANT_RADIO RemoteAddress[0] = AdressaRemotaFalsa[0]; RemoteAddress[1] = AdressaRemotaFalsa[1]; RemoteAddress[2] = AdressaRemotaFalsa[2]; #else EERead(EE_MAC_REMOT,RemoteAddress, RF_LEN_ADDRESS); // Versió 0.2 if ((RemoteAddress[0] == 0xFF) && (RemoteAddress[1] == 0xff)) ModeLite = 1; else ModeLite = 0; #endif }
void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT // 5ms delay to compensate for time to startup between MSP430 and CC1100/2500 __delay_cycles(5000); TI_CC_SPISetup(); // Initialize SPI port DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P2SEL = 0; // Sets P2.6 & P2.7 as GPIO TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CCxxxx COM_Init(); TI_CC_SW_PxREN = TI_CC_SW1; // Enable Pull up resistor TI_CC_SW_PxOUT = TI_CC_SW1; // Enable pull up resistor TI_CC_SW_PxIES = TI_CC_SW1; // Int on falling edge TI_CC_SW_PxIFG &= ~(TI_CC_SW1); // Clr flags TI_CC_SW_PxIE = TI_CC_SW1; // Activate interrupt enables TI_CC_LED_PxOUT &= ~(TI_CC_LED1 + TI_CC_LED2); // Outputs = 0 TI_CC_LED_PxDIR |= TI_CC_LED1 + TI_CC_LED2;// LED Direction to Outputs TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU __bis_SR_register(LPM0_bits + GIE); // Enter LPM3, enable interrupts }
int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer P2DIR |= BIT3 | BIT4; // output to BLDC and LED P2OUT &= ~BIT3; // make sure pump is off P2OUT &= ~BIT4; //make sure LED is off // Port 1 pushbutton config P1REN |= TI_CC_SW1; // enable pullup/down on switch1 P1OUT |= TI_CC_SW1; // configure PUR as pull down (active low) P1IES |= TI_CC_SW1; // interrupt on falling edge P1IFG = 0; // clear all interurpt flags P1IE = TI_CC_SW1; // enable interrupts on pushbutton // Initialize radio and SPI - This code is derived from TI radio drivers TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE // Enable interrupts from radio module P2IES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) P2IFG &= ~TI_CC_GDO0_PIN; // Clear flag P2IE |= TI_CC_GDO0_PIN; // Enable int on end of packet // Enable radio TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // configure packet // -------------------------------------------- txBuffer[0] = MSGLEN-1; // Packet length -- this will get trimmed off. txBuffer[1] = 0x01; // Packet address - If this is 0xFF, it's an ack and not data. // Begin data // -------------------------------------------- txBuffer[2] = OPERATE_SENSOR; // flag for other node to know that it needs to read switch state. txBuffer[3] = 0x30; // Filler data to be used later on txBuffer[4] = 0x31; txBuffer[5] = 0x34; txBuffer[6] = 0x35; txBuffer[7] = 0x36; txBuffer[8] = 0x37; txBuffer[9] = 0x38; txBuffer[10] = 0x39; // the rest of this data isn't used in ths project // Extra data could be used in the event that more controller nodes are added // ------ // End Data txBuffer[11] = 0x00; // terimate // -------------------------------------------- _BIS_SR(GIE); // turn on interrupts. Initialization is now complete. while(1) { if(buttonPressed) { // buttonPressed is a user interrupt flag P1IE &= ~TI_CC_SW1; // disable user interrupts to avoid conflicting pump cycles if (WaterLevelValid()) { // WaterLevelValid() will retrieve water level status from the other node P2OUT |= BIT3; // turn on pump __delay_cycles(1000000); // delay for a second while pump runs P2OUT &= ~BIT3; // turn off pump P2OUT &= ~BIT4; // turn off LED } buttonPressed = 0; // clear flag P1IE = TI_CC_SW1; // Enable user interrupts (accept a new pump cycle) } } }
//This function configures the SPI interface //to the CC1101, resets the device and //sets the scanning parameters //GETS: Pointer to the scan parameters //and the pointer to the structure //where the Rssi values will be stored //RETURNS: NULL if something went wrong //or pointer to the SCAN_CONFIG structure //with the parameters actually used by the function SCAN_CONFIG * configScanner(SCAN_CONFIG * pconfigParameters, BYTE * rssiArray) { BYTE reg; //Store the array pointer, if it's NULL report failure if(rssiArray==NULL) return NULL; rssiTable = rssiArray; //Configure the SPI interface TI_CC_SPISetup(); //Reset the CC1101 TI_CC_PowerupResetCCxxxx(); //If pconfigParameters is NULL, use defaults if(pconfigParameters==NULL){ pconfigParameters=&scanParameters; scanParameters.startFreqMhz=MIN_FREQ; scanParameters.startFreqKhz=0; scanParameters.stopFreqMhz=MAX_FREQ; //scanParameters.stopFreqMhz=820; scanParameters.stopFreqKhz=0; scanParameters.freqResolution=DEFAULT_RESOLUTION; scanParameters.modFormat=TI_CCxxx0_MDMCFG2_MODFORMAT_ASK; scanParameters.rssiWait=AVG_WAIT_WITH_AGC; scanParameters.activateAGC=TRUE; } /**Start parsing parameters**/ //Parsing startFreq if (pconfigParameters->startFreqMhz < MIN_FREQ || pconfigParameters->startFreqMhz > MAX_FREQ) { //Use default value: MIN_FREQ scanParameters.startFreqMhz = MIN_FREQ; scanParameters.startFreqKhz = 0; } else { scanParameters.startFreqMhz = pconfigParameters->startFreqMhz; if (pconfigParameters->startFreqKhz>= 1000 || pconfigParameters->startFreqMhz==MAX_FREQ) { //Use default value: 0 scanParameters.startFreqKhz = 0; } else{ scanParameters.startFreqKhz = pconfigParameters->startFreqKhz; } } //Parsing stopFreq if (pconfigParameters->stopFreqMhz < MIN_FREQ || pconfigParameters->stopFreqMhz > MAX_FREQ) { //Use default value: MAX_FREQ scanParameters.stopFreqMhz = MAX_FREQ; scanParameters.stopFreqKhz = 0; } else { scanParameters.stopFreqMhz = pconfigParameters->stopFreqMhz; if (pconfigParameters->stopFreqKhz>= 1000 || pconfigParameters->stopFreqMhz==MAX_FREQ) { //Use default value: 0 scanParameters.stopFreqKhz = 0; } else{ scanParameters.stopFreqKhz = pconfigParameters->stopFreqKhz; } } //Check if the range limits make sense if (scanParameters.startFreqMhz > scanParameters.stopFreqMhz) return NULL; if (scanParameters.startFreqMhz == scanParameters.stopFreqMhz && scanParameters.startFreqKhz > scanParameters.stopFreqKhz) return NULL; if (scanParameters.startFreqMhz == MAX_FREQ && scanParameters.startFreqKhz > 0) return NULL; //Parsing filterBandwidth if(pconfigParameters->freqResolution<filterBandwidthList[0][0] || pconfigParameters->freqResolution>filterBandwidthList[3][3]) scanParameters.freqResolution=DEFAULT_RESOLUTION; //Find the valid filter value closest to the one requested UINT16 diff, tempDiff; BYTE i, j, row, column; for (i = 0; i < sizeof(filterBandwidthList); i++) { for (j = 0; j < sizeof(*filterBandwidthList); j++) { if(filterBandwidthList[i][j] > pconfigParameters->freqResolution) tempDiff=filterBandwidthList[i][j] - pconfigParameters->freqResolution; else tempDiff=pconfigParameters->freqResolution - filterBandwidthList[i][j]; if (i == 0 && j==0) diff = tempDiff; if (tempDiff <= diff) { diff = tempDiff; row = i; column = j; } if (diff == 0) break; } if (diff == 0) break; } scanParameters.freqResolution = filterBandwidthList[row][column]; //Set the channel filter bandwidth reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG4); reg &= ~(TI_CCxxx0_MDMCFG4_CHANBW_E + TI_CCxxx0_MDMCFG4_CHANBW_M); reg |= (chanBwE[row][column] << 4) + (chanBwM[row][column] << 6); TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, reg); //Initialize the variables related to the frequency registers REG2:REG1:REG0 //Formula: f_carrier=(f_xosc/2^16)*FREQ[23:0] //TODO: To optimize, consider using Horner division code from SLAA329 //Link: http://www.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=slaa329&docCategoryId=1&familyId=4 freqRegsBase=(((UINT32)scanParameters.startFreqMhz)<<16)/fXoscMhz; freqRegsBase+=(((UINT32)scanParameters.startFreqKhz)<<16)/(fXoscMhz*1000); freqRegsStep=(((UINT32)scanParameters.freqResolution)<<16)/(fXoscMhz*1000); //Set the channel spacing // reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG1); // reg &= ~TI_CCxxx0_MDMCFG1_CHANSPC_E_MASK; // reg |= chanSpcE[row][column]; // TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1, reg); // TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0, chanSpcM[row][column]); //Set the number of channels per Mhz //Parsing the modulation format //If it's a wrong or invalid value, use the first valid modulation format if (pconfigParameters->modFormat < sizeof(validModFormats) && validModFormats[pconfigParameters->modFormat]) scanParameters.modFormat = pconfigParameters->modFormat; else { for (i = 0; i < sizeof(validModFormats) && !validModFormats[i]; i++) ; scanParameters.modFormat = i; } //Set the modulation for the current scan reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG2); reg &= ~TI_CCxxx0_MDMCFG2_MODFORMAT_MASK; reg |= modFormatMDMCFG2[scanParameters.modFormat]; TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2, reg); //Parse AGC options //If the AGC is disabled, we manually set //all the gain stages, otherwise we ignore //those fields if(pconfigParameters->activateAGC){ scanParameters.activateAGC = TRUE; //Parse rssiWait if(pconfigParameters->rssiWait<MIN_WAIT_WITH_AGC || pconfigParameters->rssiWait>MAX_WAIT_WITH_AGC){ //Use default: AVG_WAIT_WITHOUT_AGC scanParameters.rssiWait=AVG_WAIT_WITH_AGC; } else{ scanParameters.rssiWait=pconfigParameters->rssiWait; } } else{ scanParameters.activateAGC = FALSE; //Freeze the AGC reg = TI_CC_SPIReadReg(TI_CCxxx0_AGCCTRL0); reg &= ~TI_CCxxx0_AGCCTRL0_AGCFREEZE_MASK; reg |= TI_CCxxx0_AGCCTRL0_AGCFREEZE_ALL; TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, reg); //Parse static gain options if (pconfigParameters->agcLnaGain < LNA_MIN_GAIN && pconfigParameters->agcLnaGain > LNA_MAX_GAIN) scanParameters.agcLnaGain = pconfigParameters->agcLnaGain; else scanParameters.agcLnaGain = LNA_MAX_GAIN; if (pconfigParameters->agcLna2Gain > LNA2_MIN_GAIN && pconfigParameters->agcLna2Gain < LNA2_MAX_GAIN) scanParameters.agcLna2Gain = pconfigParameters->agcLna2Gain; else scanParameters.agcLna2Gain = LNA2_MAX_GAIN; if (pconfigParameters->agcDvgaGain > DVGA_MIN_GAIN && pconfigParameters->agcDvgaGain < DVGA_MAX_GAIN) scanParameters.agcDvgaGain = pconfigParameters->agcDvgaGain; else scanParameters.agcDvgaGain = DVGA_MAX_GAIN; //Set static gain value reg = scanParameters.agcDvgaGain | (scanParameters.agcLna2Gain << 3) | (scanParameters.agcLna2Gain << 6); TI_CC_SPIWriteReg(TI_CCxxx0_AGCTEST, reg); //Parse rssiWait if(pconfigParameters->rssiWait<MIN_WAIT_WITHOUT_AGC || pconfigParameters->rssiWait>MAX_WAIT_WITHOUT_AGC){ //Use default: AVG_WAIT_WITH_AGC scanParameters.rssiWait=AVG_WAIT_WITH_AGC; } else{ scanParameters.rssiWait=pconfigParameters->rssiWait; } } /**Finished parsing parameters**/ //Everything OK, return pointer to the parameter structure return &scanParameters; }