/***************************************************************/ /* DS32X35an.c */ /***************************************************************/ #include /* Prototypes for I/O functions */ #include /* Register declarations for DS5000 */ /***************************** Defines **************************/ /************************* bit definitions *********************/ #define ACK 0 #define NACK 1 #define ADDRTC 0xd0 /* base address of TCXO */ #define ADDRAM 0xa0 /* base address of FRAM */ sbit scl = P0^0; /* I2C pin definitions */ sbit sda = P0^1; sbit wp = P0^3; /* WP input */ sbit sqwint = P3^3; /* SQW/INTb output to INT1 on 8051 */ /*********************** function prototypes *******************/ void start(); void stop(); uchar writebytei2c(uchar d); uchar readbytei2c(int); void readbytetcxo(); void writebytetcxo(); void initialize_tcxo(); void rd_temp(); void disp_regs(uchar); void fill_ram(uchar); void wr_ram(uchar); void ver_ram(uchar); void rd_ram(); /************************* Global Variables ***************************/ uchar ram = 7, sec, min, hr, dy, dt, mn, yr; /**************************** functions ******************************/ void start() /* ----------------------------------------------- */ { sda = 1; scl = 1; scl = 1; scl = 1; /* Initiate start condition */ sda = 0; } void stop() /* ----------------------------------------------- */ { sda = 0; sda = 0; sda = 0; sda = 0; /* Initiate stop condition */ scl = 1; scl = 1; sda = 1; } uchar writebytei2c(uchar d) /* ----------------------------- */ { uchar i; scl = 0; for (i = 0; i < 8; i++) { sda = (d & 0x80); scl = 1; d = d << 1; scl = 0; } sda = 1; /* Release the sda line */ scl = 1; i = sda; scl = 0; return i; } uchar readbytei2c(int b) /* ----------------------------------- */ { uchar i, d; sda = 1; /* Let go of sda line */ scl = 0; for (i = 0; i < 8; i++) /* read the msb first */ { scl = 1; d = d << 1; d = d | sda; scl = 0; } sda = b; /* low for ack, high for nack */ scl = 1; scl = 0; sda = 1; /* Release the sda line */ return d; } void writebytetcxo() /* ----------------------------------------------- */ { uchar Add, Data; printf("\nAddress: "); /* Get Address */ scanf("%bx", &Add); printf("Data: "); scanf("%bx", &Data); /* and data */ start(); writebytei2c(ADDRTC); writebytei2c(Add); writebytei2c(Data); stop(); } void readbytetcxo() /* ----------------------------------------------- */ { uchar Add; printf("\nADDRESS: "); /* Get Address */ scanf("%bx", &Add); start(); writebytei2c(ADDRTC); writebytei2c(Add); start(); writebytei2c(ADDRTC | 1); printf("%2bx", readbytei2c(NACK) ); stop(); } void initialize_tcxo() /* ----------------------------------------- */ /* Note: NO error checking is done on the user entries! */ { printf("\nEnter the year (0-99): "); scanf("%bx", &yr); printf("Enter the month (1-12): "); scanf("%bx", &mn); printf("Enter the date (1-31): "); scanf("%bx", &dt); printf("Enter the day (1-7): "); scanf("%bx", &dy); printf("Enter the hour (1-23): "); scanf("%bx", &hr); /* hr = hr & 0x3f; /* force clock to 24 hour mode */ printf("Enter the minute (0-59): "); scanf("%bx", &min); printf("Enter the second (0-59): "); scanf("%bx", &sec); start(); writebytei2c(ADDRTC); /* write slave address, write tcxo */ writebytei2c(0x00); /* write register address, 1st clock register */ writebytei2c(sec); writebytei2c(min); writebytei2c(hr); writebytei2c(dy); writebytei2c(dt); writebytei2c(mn); writebytei2c(yr); writebytei2c(0x10); /* enable sqw, 1hz output */ stop(); } void rd_temp() /* -------- display temperature -------- */ { int itemp; float ftemp; while(!RI) { start(); writebytei2c(ADDRTC); writebytei2c(0x0e); /* address of control register */ start(); writebytei2c(ADDRTC + 1); /* send the device address for read */ itemp = readbytei2c(NACK); /* get the control register value */ start(); writebytei2c(ADDRTC); writebytei2c(0x0e); /* address of control register */ writebytei2c(itemp | 0x20); /* force temperature conversion */ stop(); do { start(); writebytei2c(ADDRTC); writebytei2c(0x0e); /* address of control register */ start(); writebytei2c(ADDRTC + 1); /* send the device address for read */ itemp = readbytei2c(NACK); /* get the control register value */ stop(); } while(itemp & 0x20); /* wait until CNVT bit goes inactive */ start(); writebytei2c(ADDRTC); writebytei2c(0x11); /* address of temperature MSB */ start(); writebytei2c(ADDRTC + 1); /* send the device address for read */ itemp = ( (int) readbytei2c(ACK) << 5 ); itemp += ( readbytei2c(NACK) >> 3); stop(); if(itemp & 0x1000) itemp += 0xe000; /* if sign bit set, make 16 bit 2's comp */ ftemp = 0.03125 * (float) itemp; /* convert to degrees C */ /* ftemp = ftemp * 9 / 5 + 32; /* skip this if you don't want degrees F */ printf("\n%5.2f", ftemp); } RI = 0; } void disp_regs(uchar prv_sec) /* ------ display date/time, once if entry code=0xfe ------ */ { uchar Sec, Min, Hrs, Dte, Mon, Day, Yr, mil, pm, cn; printf("\n Yr Mn Dt Dy Hr:Mn:Sc"); while(!RI) /* Read & Display Clock Registers */ { start(); writebytei2c(ADDRTC); writebytei2c(0); start(); writebytei2c(ADDRTC | 1); Sec = readbytei2c(ACK); Min = readbytei2c(ACK); Hrs = readbytei2c(ACK); Day = readbytei2c(ACK); Dte = readbytei2c(ACK); Mon = readbytei2c(ACK); Yr = readbytei2c(NACK); stop(); if(Hrs & 0x40) mil = 0; else mil = 1; if(Sec != prv_sec) /* display every time seconds change */ { if(mil) { printf("\nDUT %02bx/%02bx/%02bx %02bx", Yr, Mon, Dte, Day); printf(" %02bx:%02bx:%02bx", Hrs, Min, Sec); } else { if(Hrs & 0x20) pm = 'A'; else pm = 'P'; Hrs &= 0x1f; /* strip mode and am/pm bits */ printf("\nDUT %02bx/%02bx/%02bx %02bx", Yr, (Mon & 0x1f), Dte, Day); printf(" %02bx:%02bx:%02bx %cM %1bx", Hrs, Min, Sec, pm, cn); } } if(prv_sec == 0xfe) return; prv_sec = Sec; } RI = 0; /* Swallow keypress to exit loop */ } void fill_ram(uchar val) /* -------- fill RAM with with user data -------- */ { uchar j, k; for(k = 0; k <= ram; k++) { start(); if(ram & 0x10) /* if 64k bits */ { writebytei2c(ADDRAM); /* slave address+ write bit */ writebytei2c(k); /* write upper 5 bits of address */ writebytei2c(0); /* and set lower 8 bits to 1st add */ } else /* if 16k bits */ { writebytei2c(ADDRAM + (k << 1)); /* write slv add + pg sel */ writebytei2c(0); /* and set lower 8 bits to 1st add */ } j = 0; while(1) { writebytei2c(val); if(j == 0xff) break; /* wait until we finish with all 256 locations */ j++; } stop(); } } void wr_ram(uchar inv) /* -------- fill RAM with incrementing data -------- */ { uchar j, k, dat = 0; for(k = 0; k <= ram; k++) { start(); if(ram & 0x10) /* if 64k bits */ { writebytei2c(ADDRAM); /* slave address+ write bit */ writebytei2c(k); /* write upper 5 bits of address */ writebytei2c(0); /* and set lower 8 bits to 1st add */ } else /* if 16k bits */ { writebytei2c(ADDRAM + (k << 1)); /* write slv add + pg sel */ writebytei2c(0); /* and set lower 8 bits to 1st add */ } j = 0; while(1) { if(inv) writebytei2c((dat ^ 0xff)); else writebytei2c(dat); dat++; if(j == 0xff) break; /* wait until we finish with all 256 locations */ j++; } dat++; /* shift the data once per 'page' */ stop(); } } void ver_ram(uchar inv) /* -------- verify FRAM with incrementing data -------- */ { uchar j, k, dat = 0, val; for(k = 0; k <= ram; k++) { start(); writebytei2c(ADDRAM); /* slave address+ write bit */ if(ram & 0x10) /* if 64k bits */ writebytei2c(k); /* write upper 5 bits of address */ writebytei2c(0); /* write word address, 1st FRAM location */ start(); if(ram & 0x10) /* if 64k bits */ writebytei2c(ADDRAM + 1); else /* if 16k bits */ writebytei2c(ADDRAM + (k << 1) + 1); /* write slv add + page + rd bit */ j = 0; while(1) { if(inv) { val = readbytei2c(ACK); if(val != (dat ^ 0xff) ) { printf("\nAdd: %02bx%02bx", k, j); printf(" Expected: %02bx read: %02bx", (dat ^ 0xff), val); break; } } else { val = readbytei2c(ACK); if(val != dat) { printf("\nAdd: %02bx%02bx", k, j); printf(" Expected: %02bx read: %02bx", dat, val); break; } } dat++; if(j == 0xff) break; /* wait until we finish with all 256 locations */ j++; } readbytei2c(NACK); /* terminate read */ dat++; /* shift the data once per 'page' */ stop(); } } void rd_ram() /* ----- read and display the FRAM ----- */ { uchar j, k; for(k = 0; k <= ram; k++) { start(); writebytei2c(ADDRAM); /* slave address+ write bit */ if(ram & 0x10) /* if 64k bits */ writebytei2c(k); /* write upper 5 bits of address */ writebytei2c(0); /* write word address, 1st FRAM location */ start(); if(ram & 0x10) /* if 64k bits */ writebytei2c(ADDRAM + 1); else /* if 16k bits */ writebytei2c(ADDRAM + (k << 1) + 1); /* write slv add + page + rd bit */ j = 0; while(1) { if(!(j % 16)) printf("\n%02bx%02bx ", k, j); printf("%02bX ", readbytei2c(ACK) ); if(j == 0xff) break; /* wait until we finish with all 256 locations */ j++; } readbytei2c(NACK); /* dummy read to NACK the last read byte */ stop(); } } main (void) /* ----------------------------------------------------- */ { uchar M, M1; sqwint = 1; /* set port bits to read */ wp = 0; /* turn off write protect for FRAM */ while (1) { printf("\nDS32X35-"); if(ram == 7) printf("16"); else printf("64"); printf(" build %s\n", __DATE__); printf("CI Init RTC CR Read Clock\n"); printf("BR Byte Read BW Byte Write\n"); printf("RC RAM Check RW RAM Write inc\n"); printf("RR RAM Read RV RAM Verify inc\n"); printf("S Show Temp\n"); printf("Enter Menu Selection:"); M = _getkey(); switch(M) { case 'B': case 'b': printf("\nRead or Write: "); M1 = _getkey(); switch(M1) { case 'R': case 'r': readbytetcxo(); break; case 'W': case 'w': writebytetcxo(); break; } break; case 'C': case 'c': printf("\rEnter Clock Routine to run:C"); M1 = _getkey(); switch(M1) { case 'I': case 'i': initialize_tcxo(); break; case 'R': case 'r': disp_regs(0x99); break; } break; case 'P': case 'p': wp ^= 1; break; case 'R': case 'r': printf("\r2)2K, 8)8K, F)ill RAM R)ead RAM W)rite RAM: R"); M1 = _getkey(); switch(M1) { case '2': ram = 7; break; /* 2,048-byte FRAM size */ case '8': ram = 0x1f; break; /* 8,192-byte FRAM size */ case 'C': case 'c': wr_ram(0); ver_ram(0); wr_ram(1); ver_ram(1); break; case 'F': case 'f': printf("\nEnter fill value (hex): "); scanf("%bx", &M1); fill_ram(M1); break; case 'R': case 'r': rd_ram(); break; case 'V': ver_ram(1); break; case 'v': ver_ram(0); break; case 'W': wr_ram(1); break; case 'w': wr_ram(0); break; } break; case 'S': case 's': rd_temp(); break; } } }