//#include #include #include #include #include #include "stdint.h" //#include #include "Common_Define.h" #include #include #include #include #include "USI_TWI_Slave.h" #define sbi(port,bit) (port |= (1<year%100)) return (char)(p->year%400); else return (char)(p->year%4); } void updateTime(uint8_t amount) { t_time *p = &Time ; FORCE_INDIRECT(p) ; if (++p->second >= 60) //keep track of time, date, month, and year { p->second -= 60 ; if (++p->minute >= 60) { p->minute=0; if (++p->hour >= 24) { p->hour=0; if (++p->date >= 32) { p->month++; p->date=1; } else if (p->date == 31) { if ((p->month==4) || (p->month==6) || (p->month==9) || (p->month==11)) { p->month++; p->date=1; } } else if (p->date==30) { if(p->month==2) { p->month++; p->date=1; } } else if (p->date==29) { if((p->month==2) && (not_leap())) { p->month++; p->date=1; } } if (p->month >= 13) { p->month=1; p->year++; } } } } } ISR(TIMER0_OVF_vect) { TCCR0B = 5 ; // Divide/128 while((ASSR & 0b00011011) != 0x00);/*Wait until TCNT0, OCR0A, TCCR0A and TCCR0B updated*/ updateTime(1) ; } void checkPowerSave() { if ( PINB & 0x05 ) { ActivityFlag = 0 ; return ; // I2C line(s) are high, power is ON } if ( ActivityFlag < 3 ) { return ; } // The AVR toolchain includes a header file, sleep.h, which has functions for setting //sleep mode, disabling BOD, and putting the device into sleep. These functions are //called: //.. set_sleep_mode() – selects which sleep mode to use when the sleep //instruction is executed //.. sleep_enable() – enables sleep modes //.. sleep_bod_disable() – disables BOD while sleeping //.. sleep_cpu() – executes the sleep instruction CLKPR = 0x80 ; // Do inline for quick response CLKPR = 0 ; // Full speed 8.0MHz set_sleep_mode(SLEEP_MODE_PWR_SAVE); TIMSK0 |= (1 << TOIE0) ; disableAdc() ; PRR = 0x3B ; // Power off USI Disable_WatchDogTimer() ; set_clock( 2 ) ; // Slow to 2.0 MHz while ( ( PINB & 0x05 ) == 0 ) // I2C lines are low { sleep_enable(); sleep_bod_disable(); sei(); sleep_cpu(); sleep_disable(); cli() ; wdt_reset() ; } PRR = 0x39 ; // USI re-powered Init_WatchDogTimer() ; USI_TWI_SLAVE_Init(); enableAdc() ; TIMSK0 &= ~(1 << TOIE0) ; USISR = (1<second ; *q++ = p->minute ; *q++ = p->hour ; *q++ = p->date ; *q++ = p->month ; *q++ = p->year ; *q++ = p->year >> 8 ; *q++ = Temperature ; *q++ = T_offset ; *q++ = T_gain ; // *q++ = MCUSR ; if ( ActivityFlag < 255 ) { ActivityFlag += 1 ; } set_clock( 5 ) ; // Slow to 0.25MHz } checkPowerSave() ; if ( ( AdcControl & ADC_RUNNING ) == 0 ) { ADMUX = TEMPERATURE ; // Internal 1.1V REF and ADCx ADCSRA |= (1< 1 ) { // Skip first conversion AdcTotal += ADCW ; } if ( ( AdcControl & ADC_COUNT_MASK ) >= 9 ) { AdcTotal += 4 ; AdcTotal >>= 3 ; { int16_t temp ; temp = AdcTotal ; temp -= 298 ; temp += T_offset ; temp *= T_mult ; temp >>= 8 ; temp += 25 ; Temperature = temp ; } AdcControl = 0 ; AdcTotal = 0 ; // if (AdcTotal < 0x00f6) // { // Temperature=-40; // } // else if (AdcTotal < 0x0144) // { // Temperature=((AdcTotal*78)/65)-40; // } // else // { // Temperature=((((AdcTotal-324)*600)/74)+250)/10; // } } } } } // while // Disable_WatchDogTimer(); // After Reset the WDT state does not change // void (*FuncPtr) (void) = (void (*)(void)) (0x0080); // Set up function pointer to address 0x0080 // FuncPtr (); TCCR0B = 0 ; USICR = 0 ; USISR = 0 ; PRR = 0 ; CLKPR = 0x80 ; // Do inline for quick response CLKPR = 0 ; // Full speed 8.0MHz ((void (*)(void)) (0))() ; } /******************************************************************************/ //Description: // Process the USI TWI start condition. This is called when the TWI master initiates // communication with a USI TWI slave by asserting the TWI start condition. /******************************************************************************/ static void USI_TWI_SLAVE_Process_Start_Condition(void) { // Wait until the "Start Condition" is complete when SCL goes low. If we fail to wait // for SCL to go low we may miscount the number of clocks pulses for the data because // the transition of SCL could be mistaken as one of the data clock pulses. while ((PIN_USI & (1<> 1) == USI_TWI_SlaveAddress) { // Yes. Are we to send or receive data? if((Usi_Data & 0x01) == 0x01) { //USI TWI Slave has to transmit the data byte USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX; Tx_buffer[0] = VERSION ; // Version number Tx_index = 0 ; } else { //USI TWI Slave has to Receive the data byte USI_TWI_SLAVE_Overflow_State = USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX; } // Reset the write state. //.. added the below statement at Command_flag=1 //USI_TWI_SLAVE_Write_State = USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE; // Set SDA for output. PORT_USI |= (1<= 8 ) // Size of time structure+1 { if ( Value == 8 ) { // Set the date and time t_time *p = &Time ; FORCE_INDIRECT(p) ; p->second = DataBuffer[1] ; p->minute = DataBuffer[2] ; p->hour = DataBuffer[3] ; p->date= DataBuffer[4] ; p->month = DataBuffer[5] ; p->year = DataBuffer[6] + ( DataBuffer[7] << 8 ) ; } Value = 9 ; bufferPtr = &DataBuffer[DATA_SIZE-1] ; } } if ( Value > DATA_SIZE ) { Value = DATA_SIZE ; bufferPtr = &DataBuffer[DATA_SIZE-1] ; // Overwrite last byte } } // Set SDA for output. PORT_USI |= (1<second = 5 ; p->minute = 6 ; p->hour = 16 ; p->date= 23 ; p->month = 9 ; p->year = 2012 ; bufferPtr = DataBuffer ; T_offset = boot_signature_byte_get( TSOFFSET ) ; T_gain = boot_signature_byte_get( TSGAIN ) ; T_mult = 32768U / T_gain ; enableAdc() ; for(;;) { USI_TWI_SLAVE_ReadAndProcessPacket() ; } } // Enable ADC void enableAdc() { cbi( PRR, PRADC ) ; // Power the ADC ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // set ADC prescaler to , 8MHz / 64 = 125kHz } // Disable ADC void disableAdc() { ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) ; // set ADC prescaler to , 8MHz / 256 = 30kHz sbi( PRR, PRADC ) ; // Power Down the ADC }