/****************************************************************************** * @fn halTimer32kMcuSleepTicks * * @brief This function uses Timer B to sleep for a specfied number of * ACLK ticks, that is less than 2^15 tics(1s). * Assumes that the only interrupt source is * generated by Timer B. * * NOTE: When called, this function will assign NO ISR to the * TIMERB0_VECTOR interrupt(NULL pointer). When interrupt triggers * it will just wake up the MCU. Conflicts are possible if not * used carefully since other parts of a program might use the * TIMER B. * * input parameters * * @param ticks - Number of ACLK(32768Hz) ticks that the MCU will sleep * * output parameters * * @return void */ void halTimer32kMcuSleepTicks(uint16 ticks) { halTimer32kIntConnect(NULL); halTimer32kInit(ticks); halTimer32kIntEnable(); __low_power_mode_3(); halTimer32kAbort(); }
void main(void) { boardInitialisation(); while(1) { ADCValue = getSoilMoisture(); __low_power_mode_3(); //LPM3, TimerA ISR wake MCU after 8 seconds } }
void main(void) { boardInitialisation(); while(1) { getTemperatureAndHumidity(); __low_power_mode_3(); } }
float getTemperatureLM35(void) { ADC12_B_startConversion( ADC12_B_BASE, ADCSTARTMEMORY, ADC12_B_SINGLECHANNEL ); __low_power_mode_3(); // LPM3, ADC12_B_ISR will force exit //Temperature = (ADCValue*Vref)/ADCResolution; Porting the same equation to IQMath library float temperature = _IQ7toF(_IQ7div(_IQ7mpy(_IQ7(ADCValue), _IQ7(VRef)), _IQ7(ADC))); return temperature; }
void main(void){ configClock(); setupPorts(); setupTimer(); _EINT(); // Not really necessary since CPU is going to LPM3 @ the main TACCTL0 &= ~CCIE; while(1) { __low_power_mode_3(); //enter LPM3 w/GIE } }
/****************************************************************************** * @fn perCC1120CC1190SendPacket * * @brief Sends the contents that pData points to which has the * following structure: * * txArray[0] = length byte * txArray[n] = payload[n] * | n<[sizeOf(RXFIFO)-2], variable packet length is assumed. * * The radio state after completing TX is dependant on the * CC112X_RFEND_CFG0 register setting. For PG10 this register * dictates IDLE after TX. For PG.0 this function must be * re-implemented since the 2way PER test relies on RX after TX. * This function enables SYNC interrupt. This means that * an interrupt will fire when a packet has been sent, i.e sync * signal transitions from high to low. * * The One-Way PER test disables the sync pin interrupt when TX * finishes, while the Two-Way PER test doesn't to enable quick * reception of Slave ACK. * * Note: Assumes chip is ready * * input parameters * * @param *pData - pointer to data array that starts with length byte * and followed by payload. * output parameters * * @return void */ void perCC1120CC1190SendPacket(uint8 *pData) { uint8 len = *pData; /* PG1.0 errate fix: Before entering TX, the frequency word must be altered from that of RX */ /* This means in general that TX from Idle is the only option, not TX from RX */ perCC1120CC1190EnterIdle(); /* Will only try to transmit if the whole packet can fit i RXFIFO * and we're not currently sending a packet. */ if(!(len > (PER_MAX_DATA-2)) && (cc1120cc1190RadioTxRx != CC112X_STATE_TX) ) { cc112xSpiWriteTxFifo(pData,(len+1)); /* Indicate state to the ISR and issue the TX strobe */ trxEnableInt(); /* Enable PA on CC1190 and be sure LNA is off */ //perCC1190HgmEnable(); perCC1120CC1190LnaDisable(); perCC1120CC1190PaEnable(); cc1120cc1190RadioTxRx = CC112X_STATE_TX; trxSpiCmdStrobe(CC112X_STX); /* Wait until packet is sent before doing anything else */ __low_power_mode_3(); /* This function will not return before the complete packet * is sent and the radio is back in IDLE. The MSP will be * be sleeping while the packet is beeing sent unless waken * by button presses. */ while(cc1120cc1190RadioTxRx == CC112X_STATE_TX); if(perSettings.linkTopology == LINK_1_WAY) { /* Back in Idle*/ trxDisableInt(); /* Turn off PA on CC1190 */ perCC1120CC1190PaDisable(); } } return; }
/****************************************************************************** * @fn perCC115LSendPacket * * @brief Sends the contents that pData points to. pData has the * following structure: * * txArray[0] = length byte * txArray[n] = payload[n] * | n<[sizeOf(RXFIFO)-2], variable packet length is assumed. * * The radio state after completing TX is dependant on the * MCSM1 register setting. This function enables SYNC interrupt. * This means that an interrupt will go off when a packet * has been sent, i.e sync signal transitions from high to low. * MSP will be in low power mode until packet has been sent given * that no other interrupts go off. * * The One-Way PER test disables the sync pin interrupt when TX * finishes, while the Two-Way PER test doesn't to enable quick * reception of Slave ACK. * * Note: Assumes chip is ready * * input parameters * * @param *pData - pointer to data array that starts with length byte * and followed by payload. * output parameters * * @return void */ void perCC115LSendPacket(uint8 *pData) { uint8 len = *pData; /* Will only try to transmit if the whole packet can fit i TXFIFO * and we're not currently sending a packet. */ if(!(len > (PER_MAX_DATA-2)) && (cc115LRadioTxIdle != CC115L_STATE_TX) ) { cc11xLSpiWriteTxFifo(pData,(len+1)); /* Indicate state to the ISR and issue the TX strobe */ trxEnableInt(); cc115LRadioTxIdle = CC115L_STATE_TX; trxSpiCmdStrobe(CC115L_STX); /* Wait until packet is sent before doing anything else */ __low_power_mode_3(); while(cc115LRadioTxIdle == CC115L_STATE_TX); if(perSettings.linkTopology == LINK_1_WAY) { /* Back in Idle*/ trxDisableInt(); } } return; }
void main(void) { unsigned char last_but = 0; WDTCTL = WDTPW + WDTHOLD; // Stop WDT TACCR0 = 16384 - 1; // Xtal freq / required clock rate (2Hz) - 1 TACTL = TASSEL_1 + MC_1 + TAIE; // ACLK, contmode, interrupt // Button stuff. Button input serves two functions. // When display is off serves to cancel alarm if sounding and // switch display on. These enables the other, strobed, buttons. P1DIR &= ~BUTTON; // Direction in. P1REN |= BUTTON; // Enable resistor. P1OUT &= ~BUTTON; // Select pull-down. P1IES |= BUTTON; // high->low edge (button release) P1IFG &= ~BUTTON; // IFG cleared P1DIR |= (DIG0|DIG1|DIG2|DIG3|BIT5|BIT6|BIT7); P1OUT &= ~(BIT5|BIT6|BIT7); __enable_interrupt(); incr_clock(digits,1); while(1){ unsigned char *d = digits; if(do_alarm==0x1){ beep(); } if(buttons){ // restart the display on timer if any buttons are pressed disp_show_count = disp_show_ticks; if(do_alarm){ // setting this bit silences the alarm. do_alarm |= 0x2; } } // Try and prevent presses of the alarm-cancel / display-on button // doing other things. if(buttons == 0xff)buttons=0; if(buttons != last_but){ last_but = buttons; continue; } if(disp_show_count){ if(buttons == DIG3){ set_alarm ^= 1; } if(set_alarm) d = alarm; if(buttons == DIG0){ incr_clock(d,1); // fast set } else if(buttons == DIG1){ incr_clock(d,50); // slow set }else{ ; } buttons = 0; show_digits(d); }else{ // turn all digits off P1OUT &= ~(DIG0|DIG1|DIG2|DIG3); buttons = 0; set_alarm = 0; // enable button interrupt. P1IE |= BUTTON; __low_power_mode_3(); } } }
/****************************************************************************** * @fn main * * @brief Main handles all applications attached to the menu system * * input parameters * * output parameters * *@return */ void main( void ) { // Init clocks and I/O bspInit(BSP_SYS_CLK_16MHZ); // Init leds bspLedInit(); // Init Buttons bspKeyInit(BSP_KEY_MODE_POLL); // Initialize SPI interface to LCD (shared with SPI flash) bspIoSpiInit(BSP_FLASH_LCD_SPI, BSP_FLASH_LCD_SPI_SPD); /* Init Buttons */ bspKeyInit(BSP_KEY_MODE_ISR); bspKeyIntEnable(BSP_KEY_ALL); /* Init LCD and issue a welcome */ lcdInit(); lcdClear(); // Instantiate tranceiver RF spi interface to SCLK ~ 4 MHz */ //input clockDivider - SMCLK/clockDivider gives SCLK frequency trxRfSpiInterfaceInit(0x10); /* Welcome Screen Part */ lcdSendBuffer(trxebWelcomeScreen); lcdBufferPrintString(lcdDefaultBuffer,"TEXAS",60,eLcdPage6); lcdBufferPrintString(lcdDefaultBuffer,"INSTRUMENTS",60,eLcdPage7); lcdSendBufferPart(lcdDefaultBuffer, 60,127,eLcdPage6, eLcdPage7); /* MCU will stay in sleep until button is pressed */ __low_power_mode_3(); bspKeyPushed(BSP_KEY_ALL); //Clear screen lcdBufferClear(0); /* Menu Driver */ menu_t *pCurrentMenu = &mainMenu; uint8 menuButtonsPressed; menuDisplay(pCurrentMenu); __low_power_mode_3(); while(1) { menuButtonsPressed = bspKeyPushed(BSP_KEY_ALL); switch(menuButtonsPressed) { case BSP_KEY_LEFT: pCurrentMenu = menuBack(pCurrentMenu); break; case BSP_KEY_RIGHT: pCurrentMenu = menuEnter(pCurrentMenu); break; case BSP_KEY_DOWN: menuDown(pCurrentMenu); break; case BSP_KEY_UP: menuUp(pCurrentMenu); break; default: break; } menuDisplay(pCurrentMenu); /* Enter low power mode while menu driver waits on user input */ __low_power_mode_3(); } }
/*--------------------------------------------------------------------------*/ int main(int argc, char **argv) { /* * Initalize hardware. */ msp430_cpu_init(); clock_init(); uart_init(9600); /* Must come before first printf */ /* xmem_init(); */ PRINTF("iWatch 0.10 build at " __TIME__ " " __DATE__ "\n"); UCSCTL8 &= ~BIT2; /* * Hardware initialization done! */ /* * Initialize Contiki and our processes. */ process_init(); process_start(&etimer_process, NULL); rtimer_init(); ctimer_init(); energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); backlight_init(); battery_init(); SPI_FLASH_Init(); if (system_testing()) { clock_time_t t; backlight_on(200, 0); t = clock_seconds(); // sleep 1 while(clock_seconds() - t <= 3); printf("$$OK BACKLIGHT\n"); t = clock_seconds(); while(clock_seconds() - t <= 3); backlight_on(0, 0); motor_on(200, 0); // sleep 1s t = clock_seconds(); while(clock_seconds() - t <= 3); printf("$$OK MOTOR\n"); t = clock_seconds(); while(clock_seconds() - t <= 3); motor_on(0, 0); #if PRODUCT_W001 I2C_Init(); codec_init(); codec_bypass(1); // sleep 1s t = clock_seconds(); while(clock_seconds() - t <= 3); printf("$$OK MIC\n"); // sleep 1s t = clock_seconds(); while(clock_seconds() - t <= 3); codec_bypass(0); codec_shutdown(); #endif } int reason = CheckUpgrade(); window_init(reason); button_init(); rtc_init(); CFSFontWrapperLoad(); system_init(); // check system status and do factor reset if needed I2C_Init(); //codec_init(); //ant_init(); bluetooth_init(); #ifdef PRODUCT_W004 //bmx_init(); #else mpu6050_init(); #endif // check the button status if (button_snapshot() & (1 << BUTTON_UP)) { clock_time_t t; // delay 1 second // button up is pressed, we will set emerging flag motor_on(200, CLOCK_SECOND * 2); t = clock_seconds(); while(clock_seconds() - t <= 1); if (button_snapshot() & (1 << BUTTON_UP)) system_setemerging(); motor_on(0, 0); } if (!system_retail()) { bluetooth_discoverable(1); } #if PRODUCT_W001 if (system_testing()) ant_init(MODE_HRM); #endif system_restore(); // protocol_init(); // protocol_start(1); process_start(&system_process, NULL); /* * This is the scheduler loop. */ msp430_dco_required = 0; /* check firmware update */ if (reason == 0xff) { printf("Start Upgrade\n"); Upgrade(); // never return if sucessfully upgrade } watchdog_start(); while(1) { int r; do { /* Reset watchdog. */ watchdog_periodic(); r = process_run(); } while(r > 0); /* * Idle processing. */ int s = splhigh(); /* Disable interrupts. */ /* uart1_active is for avoiding LPM3 when still sending or receiving */ if(process_nevents() != 0) { splx(s); /* Re-enable interrupts. */ } else { static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ ENERGEST_OFF(ENERGEST_TYPE_CPU); ENERGEST_ON(ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ energest_type_set(ENERGEST_TYPE_IRQ, irq_energest); watchdog_stop(); if (shutdown_mode) { system_shutdown(1); // never return LPM4; } if (msp430_dco_required) { __low_power_mode_0(); } else { __low_power_mode_3(); } /* We get the current processing time for interrupts that was done during the LPM and store it for next time around. */ __disable_interrupt(); irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); __enable_interrupt(); watchdog_start(); ENERGEST_OFF(ENERGEST_TYPE_LPM); ENERGEST_ON(ENERGEST_TYPE_CPU); } } }
/****************************************************************************** * @fn cc120x_masterStartApp * * @brief * * input parameters * * @param pDummy - pointer to pointer to void. Not used * * output parameters * * @return SNIFF_RETURN_SUCCESS */ uint8 cc120x_masterStartApp(void) { static uint8 marcState; // Set first packet number pkt = 1; // Set up GPIO pins. For debug cc112xSpiWriteReg(CC120X_IOCFG3,&cc120x_gpioConfigMaster[0],4); //Display while configuring radios* lcdBufferClear(0); lcdBufferPrintString(0," RX Sniff Test ",0,eLcdPage0); lcdBufferSetHLine(0,0,LCD_COLS-1,eLcdPage7); lcdBufferPrintString(0," Radio in TX ",0,eLcdPage2); lcdBufferPrintString(0," ",0,eLcdPage3); lcdBufferPrintString(0," Press right button ",0,eLcdPage4); lcdBufferPrintString(0," to send packet ",0,eLcdPage5); lcdBufferPrintString(0," 1 Abort Master Mode ",0,eLcdPage7); lcdBufferSetHLine(0,0,LCD_COLS-1,55); lcdBufferInvertPage(0,0,LCD_COLS,eLcdPage7); lcdSendBuffer(0); // Calibrate radio trxSpiCmdStrobe(CC120X_SCAL); // Wait for calibration to be done (radio back in IDLE state) do { cc120xSpiReadReg(CC120X_MARCSTATE, &marcState, 1); } while (marcState != 0x41); // Put MCU to sleep __low_power_mode_3(); while(1) { if(buttonPressed = bspKeyPushed(BSP_KEY_ALL)) { if(buttonPressed == BSP_KEY_LEFT) { // Left button pressed. Abort function // Put radio in powerdown to save power trxSpiCmdStrobe(CC120X_SPWD); //Insert Carrier Sense threshold warning in Sniff Test Menu drawInfo(); return SNIFF_RETURN_FAILURE; } else if (buttonPressed == BSP_KEY_RIGHT) { //Right button pressed, send packet lcdBufferClear(0); // build packet comArray[0] = PKTLEN; // length field comArray[1] = 0x00; // address field comArray[2] = pkt>>24; // payload comArray[3] = pkt>>16; comArray[4] = pkt>>8; comArray[5] = pkt; // Update LCD lcdBufferPrintString(0," RX Sniff Test ",0,eLcdPage0); lcdBufferSetHLine(0,0,LCD_COLS-1,eLcdPage7); lcdBufferPrintString(0,"Sent Pkt number:",0,eLcdPage3); lcdBufferPrintInt(0,pkt,70,eLcdPage4); lcdBufferPrintString(0," 1 Abort Master Mode ",0,eLcdPage7); lcdBufferSetHLine(0,0,LCD_COLS-1,55); lcdBufferInvertPage(0,0,LCD_COLS,eLcdPage7); lcdSendBuffer(0); // Update packet counter pkt++; // Strobe IDLE and fill TX FIFO trxSpiCmdStrobe(CC120X_SIDLE); // wait for radio to enter IDLE state while((trxSpiCmdStrobe(CC112X_SNOP)& 0xF0) != 0x00); cc112xSpiWriteTxFifo(comArray,PKTLEN+1); // Send packet trxSpiCmdStrobe(CC120X_STX); // Wait for radio to finish sending packet while((trxSpiCmdStrobe(CC120X_SNOP)& 0xF0) != 0x00); // Put radio in powerdown to save power trxSpiCmdStrobe(CC120X_SPWD); //Put MCU to sleep __low_power_mode_3(); } } }