// *********************************************************** // Project: Logger5 RTC, pressure/temp sensor/data buffer // Uses RS232 Output (rather than USB) // Author: Dr. Simon Schrödle // // Started: 09.04.2016 // *********************************************************** #define F_CPU 16000000UL // 16 MHz #define BAUD 38400UL #define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1) #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) #if ((BAUD_ERROR<970) || (BAUD_ERROR>1030)) #error Systematischer Fehler der Baudrate grösser 3% und damit zu hoch! #endif #include #include #include #include #include #include #include #include "usbdrv/usbdrv.h" #include #include "i2csoft.c" #include "bmp085.c" #include "rtc.c" #define USB_INFOMSG 0 #define USB_RTIC 60 #define USB_RTIC1 61 //current reading debug #define USB_RDPK 64 //read last datapack #define USB_BMP085GETR 70 #define USB_BMP085INIT 71 #define USB_BMP085GETT 72 #define USB_BMP085GETP 73 #define USB_GTIME 80 #define USB_TSET1 81 #define USB_TSET2 82 #define USB_TSET3 83 #define USB_TSET 84 //set time based on values transfered by tset1...tset3 void wait_10k(void) { /*wait 10 k cycles*/ uint16_t counter; counter=10000; do { } while (--counter); } void wait_100(void) { /*wait 100 cycles*/ uint16_t counter; counter=100; do { } while (--counter); } static uint8_t upc; // USART initialisieren void uart_init(void) { // Baudrate einstellen (Normaler Modus) UBRRH = (uint8_t) (UBRR_BAUD>>8); UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff); // Aktivieren von receiver und transmitter UCSRB = (1<bRequest) { // custom command is in the bRequest field case USB_TSET1: timesetd.hour = rq->wValue.bytes[1]; timesetd.minute = rq->wValue.bytes[0]; return 0; case USB_TSET2: timesetd.second = rq->wValue.bytes[1]; timesetd.date = rq->wValue.bytes[0]; return 0; case USB_TSET3: timesetd.month = rq->wValue.bytes[1]; timesetd.year = rq->wValue.bytes[0]; return 0; case USB_TSET: set_date_time(timesetd); return 0; case USB_BMP085GETR: i2c_start(); i2c_writebyte(0xEE); i2c_writebyte(0xAA); i2c_start(); i2c_writebyte(0xEF); usbd_val[0]=i2c_readbyte(1); //ack usbd_val[1]=i2c_readbyte(0); //nack i2c_stop(); usbMsgPtr = (uint16_t) ((uint8_t*)usbd_val); return sizeof(usbd_val); case USB_BMP085INIT: bmp085_init(); usbd_val[0]=0x40; usbd_val[1]=0x41; usbMsgPtr = (uint16_t) ((uint8_t*)usbd_val); return sizeof(usbd_val); case USB_BMP085GETT: tempr=bmp085_gettemperature(); tempr=tempr*10; tempi=(int)tempr; usbd_val[0]=(tempi>>8)&0x00ff; usbd_val[1]=tempi&0x00ff; usbMsgPtr = (uint16_t) ((uint8_t*)usbd_val); return sizeof(usbd_val); case USB_BMP085GETP: tempp=bmp085_getpressure(); usbd_val2[0]=(tempp>>24)&0x000000ff; usbd_val2[1]=(tempp>>16)&0x000000ff; usbd_val2[2]=(tempp>>8)&0x000000ff; usbd_val2[3]=tempp&0x000000ff; usbMsgPtr = (uint16_t) ((uint8_t*)usbd_val2); return sizeof(usbd_val2); case USB_GTIME: timestamp=get_date_time(); usbd_val3[0]=timestamp.hour; usbd_val3[1]=timestamp.minute; usbd_val3[2]=timestamp.second; usbd_val3[3]=timestamp.date; usbd_val3[4]=timestamp.month; usbd_val3[5]=timestamp.year; usbMsgPtr = (uint16_t) ((uint8_t*)usbd_val3); return sizeof(usbd_val3); case USB_RTIC: // TIC4 data if (lastmeas[15]=='U') { lastmeas[15]='R'; //message has been read first time } else {lastmeas[0]='R';} //repeated read usbMsgPtr =(uint16_t) ((uint8_t*) lastmeas); return sizeof(lastmeas); case USB_RDPK: // data package transmit if (usbd_datapack[27]=='U') { usbd_datapack[27]='R'; //message has been read first time } else {usbd_datapack[0]='R';} //repeated read - RIC instead of TIC start usbMsgPtr =(uint16_t) ((uint8_t*) usbd_datapack); return sizeof(usbd_datapack); case USB_RTIC1: // TIC4 data current data debug usbMsgPtr =(uint16_t) ((uint8_t*) ucurrent); return sizeof(ucurrent); case USB_INFOMSG: // send data to PC usbMsgPtr =(uint16_t) ((uint8_t*) replyBuf); return sizeof(replyBuf); } return 0; // should not get here } void u_sendhandler(void) { uint8_t i; if (usbd_datapack[27]=='U') { usbd_datapack[27]='R'; //message has been read first time for (i=0;i<29;i++) { while ( !( UCSRA & (1<>8)&0x00ff; usbd_datapack[4]=tempi&0x00ff; tempp=bmp085_getpressure(); //will check temperature again, but don't mind usbd_datapack[5]=(tempp>>24)&0x000000ff; usbd_datapack[6]=(tempp>>16)&0x000000ff; usbd_datapack[7]=(tempp>>8)&0x000000ff; usbd_datapack[8]=tempp&0x000000ff; usbd_datapack[23]=0xff; //reserved usbd_datapack[24]=0xff; //reserved datapcnt++; usbd_datapack[25]=(datapcnt>>8)&0x00ff; usbd_datapack[26]=datapcnt&0x00ff; usbd_datapack[27]='U'; //unread data pack usbd_datapack[28]='E'; //end of pack lastmeas[14]='S'; //timestamp info processed } } int main(void) { uint8_t i; uart_init(); i2c_init(); bmp085_init(); rtc_init(); timestamp=get_date_time(); DDRD&=~0x08; //PD3 as input - S1 switch PORTD|=0x08; //pull up on if (!(PIND&0x08)) //connect via USB - if key S1 pressed at startup! { wdt_enable(WDTO_1S); // enable 1s watchdog timer usbInit(); usbDeviceDisconnect(); // enforce re-enumeration for(i = 0; i<250; i++) { // wait 500 ms wdt_reset(); // keep the watchdog happy _delay_ms(2); } usbDeviceConnect(); sei(); // Enable interrupts after re-enumeration do { wdt_reset(); // keep the watchdog happy usbPoll(); u_receivehandler(); stamp_handler(); } while(1); } sei(); // Enable interrupts after re-enumeration do { u_receivehandler(); stamp_handler(); u_sendhandler(); } while (1); return 0; }