Programming of the DDS-60 (AD9851) frequency synthesizer from AmQRP http://midnightdesignsolutions.com/dds60/index.html I had to use long, floating math in order to get accurate frequency output.
Dependencies: TextLCD mbed ChaNFS
main.cpp
- Committer:
- loopsva
- Date:
- 2012-04-04
- Revision:
- 0:1ed24aaf786d
File content as of revision 0:1ed24aaf786d:
/* Rev Date Changes: ------------------------------------------------------------------------------------------------------------------------------------------ 100 5/06/11 - putting things together, first cut 101 5/10/11 - removed G command from menu - added AD9851 on/off to summary 102 5/11/11 - added file dds60.ini, initializes file if missing - reads dds60.ini at boot up to get frequency values - added ability to store current values in dds60.ini into local memory using new W command 103 5/12/11 - tried a new fix for signal quality problem. wouldn't start above 30MHz, went back to 102 version - most commands now use a single keystroke vs waiting for a CR 104 5/17/11 - removed i/o delays in ad9851.cpp. results in a 40 bit download to ad9851 in 10.4uS - was 1.24mS 105 6/08/11 - added "listdir" function ------------------------------------------------------------------------------------------------------------------------------------------ Known issues: - Signal quality is bad between 200KHz and 30MHz 102 Patch fix in AD9851.cpp, routine void AD9851::FirstAccess() 105 - "listdir" function works, but "listdirSD" function doesn't ------------------------------------------------------------------------------------------------------------------------------------------ */ int revision = 105; // revision of this code #include "mbed.h" #include "SDHCFileSystem.h" #include "adc.h" #include "FATFileSystem.h" //#include "MSCFileSystem.h" #include "TextLCD.h" #include "AD9851.h" //#include "MODSERIAL.h" //#define TX_PIN p13 //p9 p13 or p28 //#define RX_PIN p14 //p10 p14 or p27 #define SAMPLE_RATE 150000 //for A:D converter #define CLS "\033[2J" extern "C" void mbed_reset(); extern "C" void mbed_mac_address(char *); #define DEFAULTHOSTNAME "mbed-c3p1" char *hostname = DEFAULTHOSTNAME; LocalFileSystem local("local"); PwmOut led1(LED1, "led1"); DigitalOut led2(LED2, "led2"); DigitalOut led3(LED3, "led3"); DigitalOut led4(LED4, "led4"); I2C i2c(p9, p10); // sda, scl TextLCD lcdt(p24, /*p25, */p26, p27, p28, p29, p30, TextLCD::LCD16x2); // rs, rw, e, d0, d1, d2, d3 DigitalOut LCDrw(p25, "LCDrw"); // new LCD code no longer requries R/W pin - tie low (J5 on Orange Board" Serial/*MODSERIAL*/ pc(USBTX, USBRX); // Serial USB communications over mbed USB port //MODSERIAL uart(TX_PIN, RX_PIN); SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sclk, cs AD9851 dds60(p16, p17, p15); //clk, sdo, len // Initialise ADC to maximum SAMPLE_RATE and cclk divide set to 1 int gDebug = 1; // display debog level (0 - 3) int OldgDebug = gDebug; // copy of gDebug for updating kb-mbed.ini int DST = 0; // Daylight Saving Time (or as defined in kb-mbed.ini) int OldDST = DST; // Copy of DST for updating kb-mbed.ini int TZone = -8; // Time Zone from UTC (or as defined in kb-mbed.ini) int OldTZone = TZone; // copy for updating kb-mbed.ini int NTPUpdateValue = 86400; // update RTC every 24 hours (or as defined in kb-mbed.ini) int bootDHCP = 1; // boot DHCP(1) of fixed IP(0) (or as defined in kb-mbed.ini) float Press0Ft = 102.4; // altimeter - assumed pressure at sea level float Saved0Ft = Press0Ft; // saved for later comparison if changed by HTTP float OldPress0Ft = Press0Ft; // another copy for updating kb-mbed.ini char mac[6]; // mbed MAC address float Led1Pwm = 0.01; // LED1 brightness bool Led1Up = true; // LED1 auto up-down ADC adc(SAMPLE_RATE, 1); bool use_sd = false; // flag for using SDHC file system bool ZeroMinFlag = false; // alignment to 00:00:00 flag float gWait = 0.005; // Main loop wait timeout float const DISP_SLOW(2.0); // Long wait for LCD display float const DISP_FAST(0.5); // Faster wait for LCD int i2cQty = 16; // number of bytes to get char i2cData[130]; // i2c read buffer data double LclBaseFreq = 1000000.0; // base frequency - if frequency double LclIfFreq = 262000.0; // IF frequency double StepFreq = 1000.0; // increment/decrement step frequency double OldStepFreq = StepFreq; // old copy of increment/decrement step frequency int pcRxQty = 0; // MODSER RX data counter/pointer char pcRxData[20]; // MODSER RX data buffer char inchar = 0; // RX input character const char BS = 0x08; // ascii backspace const char CR = 0x0d; // ascii CR const char LF = 0x0a; // ascii LF const char SP = 0x20; // ascii space const char ESC = 0x1b; // ascii escape const char DP = 0x2e; // ascii decimal point / period const char ticC = 0x0c; // ascii control C bool pcRxLine = false; // CR or LF detected in RX buffer bool pcRxEOB = false; // RX buffer EOB (full) bool pcRxIsNumb = false; // whether or not string is a valid number (including dp) bool ErFlag = false; // error flag bool FirstAccess = false; // very first DDS60 access double pcRxNumb = 0.0; // RX buffer comversion char Fcmd = 0; // post RX processing command decoder unsigned int SerialNum[5] = {58,0,0,0,0}; // mbed serial number data int Tic = 0; // Tic counter to update LCD sequence int Sequence = 0; // LCD step through sequence counter /*----------*/ void disp_i2c() { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("I2CU! Searching\n"); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("for I2C devices"); // pc.printf("\n\n"); pc.printf("I2CU! Searching for I2C devices...\n"); wait(DISP_FAST); int count = 0; for (int address=2; address<256; address+=2) { if (!i2c.write(address, NULL, 0)) { // 0 returned is ok /* A one time write to all detected EEPROM chips for later identification */ /* i2cData[0] = 0; // pointer register (hi) i2cData[1] = 0; // pointer register (lo) i2cData[2] = count+1; // detected i2c device (in sequence 1-128) i2cData[3] = address; // device's i2c address i2cData[4] = count; // device number (0-3) int i = 5; for (i=5; i<(5+5*8); i+=5) { i2cData[i] = 0; // next available write address (highest Hamming nibble) init to 0x0080 i2cData[i+1] = 0; // next available write address, Hamming nibble 2 of 4 i2cData[i+2] = 0x8b; // next available write address, Hamming nibble 3 of 4 i2cData[i+3] = 0; // next available write address, Hamming nibble 4 of 4 i2cData[i+4] = 0; // clear out address pointer flags byte (0x07 = 1 or more of the 4 bytes above is wore out) } for (i=i+5; i<130; i+=1) { //clear out remainder of buffer area i2cData[i] = 255; } */ /****** The following line inititalizes the EEPROMs to the structure above ******/ // (!i2c.write(address, i2cData, 132)); // store device address at location 0 wait(0.005); pc.printf("-I2C device found at address 0x%02X\n", address); for (int clrb=0; clrb<i2cQty; clrb+=1) { //clear out i2c buffer before reading in data i2cData[clrb] = 0; } // If device is a 24fc1025, then set the pointer register if (address>0x9F && address<0xB0) { // do only if accessing EEPROM i2cData[0] = 0; // point to location 0 in EEPROM i2cData[1] = 0; (!i2c.write(address, i2cData, 2)); // set location 0 in EEPROM } // If device is a temperature sensor (adt7410, then reset device and set 16 bit mode /* if (address>0x8F && address<0x91) { // do only if accessing Temp sensor pc.printf("-Initializing ADT7410...\n"); ADT7410Up = true; // set "installed" flag // i2cData[0] = 0x2f; // point to location 0x2f (reset reg) in Temp // (!i2c.write(address, i2cData, 1)); // reset temperature device fever.reset(); wait_ms(1); // fever.setConfig(char 0x82); // i2cData[0] = 0x03; // point to location 0x03 (config reg) in Temp // i2cData[1] = 0x82; // 16 bit mode, 3 faults // (!i2c.write(address, i2cData, 2)); // set config register // wait_ms(1); i2cData[0] = 0x0b; // point to location 0x0b (id register) (!i2c.write(address, i2cData, 1)); // set pointer for before read i2cData[0] = 0x00; // point to location 0 // (!i2c.write(address, i2cData, 1)); // set pointer for before read (!i2c.read(address, i2cData, 1)); // get ID TempId = i2cData[0]; // save ID pc.printf(" id: %02x\n", TempId); } // If device is a MPL115A2, then set the pointer register if (address>0xBF && address<0xC2) { // do only if accessing MPL115 MPL115aUp = true; // set "installed" flag i2cData[0] = 0x12; // start a temp / baro conversion i2cData[1] = 0x01; (!i2c.write(address, i2cData, 2)); // set location 0x12 in MPL115 pc.printf("-Initializing MPL115A2...\n"); wait_ms(6); // need 6mS for conversions i2cData[0] = 0; // point to location 0 in MPL115 i2cData[1] = 0; (!i2c.write(address, i2cData, 1)); // set location 0 in MPL115 } // Read and display first 16 bytes of 'found' device (!i2c.read(address, i2cData, i2cQty)); // get first few bytes from device if (address>0xBF && address<0xC2) { // do only if accessing MPL115 baro.initBaroCoef(); //initializes coeficents - only do once after reset baro.getBaroKPa(); //first real pressure access // baro.getBaroRegs(); //displays all coef registers // baro.getBaroCoef(); //displays all of the coeficent values } */ pc.printf(" "); for (int ptr=0; ptr<i2cQty/2; ptr+=1) { // print them out pc.printf("%02x ",i2cData[ptr]); } pc.printf(" "); for (int ptr=i2cQty/2; ptr<i2cQty; ptr+=1) { // print them out pc.printf("%02x ",i2cData[ptr]); } pc.printf(" "); for (int ptr=0; ptr<i2cQty; ptr+=1) { // print them out if (i2cData[ptr]>32 && i2cData[ptr]<127) { // do ascii if legal character pc.printf("%c",i2cData[ptr]); } else { pc.printf("."); } } pc.printf("\n"); count++; /* if (address>0x8F && address<0x91) { // do only if accessing Temp sensor printf("ADT7410 config: 0x%x\n", fever.getConfig()); // TempC = fever.getTemp(); // TempF = TempC * 9.0 / 5.0 + 32.0; // printf("Temperature %.3fC %.3fF\n", TempC, TempF); } */ } } if (count == 0) pc.printf(" "); pc.printf("I2CU! %d devices found\n", count); lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("I2CU! found...\n"); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("%d devices\n", count); } /* save values in file sensors.csv for later retreval */ /* void storeValues() { time_t cstTime; //need our own time stamp cstTime = time(NULL); //get time stamp cstTime = cstTime + ((TZone + DST) * 3600); //set to local date strftime(timebuf_d, 32, "%m/%d/%y,", localtime(&cstTime)); //format date strftime(timebuf, 32, "%H:%M:%S,", localtime(&cstTime)); //format time if(use_sd == false) { //use local or sd file system? if(ZeroMinFlag == true) { //only do once an hour if local if (gDebug > 1) pc.printf(" Looking for /local/sensors.csv\n"); FILE *fp = fopen("/local/sensors.csv", "r"); if (fp == NULL) { pc.printf("\n***Creating /local/sensors.csv\n"); FILE *fp = fopen("/local/sensors.csv", "w"); if (fp == NULL) { pc.printf("***cannot create /local/sensors.csv !!!\n"); return; //exit with create error } else { fprintf(fp, "date,time,inHg,kPa,deg F,deg C, alt F,kPa @ 0\n"); fclose(fp); } } else { fclose(fp); //close as a read or create file if (gDebug > 1) pc.printf("Saving data in /local/sensors.csv ..."); FILE *fp = fopen("/local/sensors.csv", "a"); //re-open as an append file fputs(timebuf_d, fp); //save date fputs(timebuf, fp); //dave time fprintf(fp, "%2.2f,%3.1f,%3.2f,%2.2f,%5.0f,%3.1f\n", RollAvgPress * kPa_inHg, RollAvgPress, RollAvgTemp * 9.0 / 5.0 + 32.0, RollAvgTemp, RollAltitude / 0.3048, Press0Ft); fclose(fp); if (gDebug > 1) pc.printf(" done\n"); } } } else { // SDHC available to use if (gDebug > 1) pc.printf(" Looking for /sd/sensors.csv\n"); FILE *fp = fopen("/sd/sensors.csv", "r"); if (fp == NULL) { pc.printf("\n***Creating /sd/sensors.csv\n"); FILE *fp = fopen("/sd/sensors.csv", "w"); if (fp == NULL) { pc.printf("***cannot create /sd/sensors.csv !!!\n"); return; //exit with create error } else { fprintf(fp, "date,time,inHg,kPa,deg F,deg C, alt F,kPa @ 0, Zero Hr\n"); fclose(fp); } } else { fclose(fp); //close as a read or create file if (gDebug > 1) pc.printf("Saving data in /sd/sensors.csv ..."); FILE *fp = fopen("/sd/sensors.csv", "a"); //re-open as an append file fputs(timebuf_d, fp); //save date only fputs(timebuf, fp); //save time only fprintf(fp, "%2.2f,%3.1f,%3.2f,%2.2f,%5.0f,%3.1f", RollAvgPress * kPa_inHg, RollAvgPress, RollAvgTemp * 9.0 / 5.0 + 32.0, RollAvgTemp, RollAltitude / 0.3048, Press0Ft); if(ZeroMinFlag == true) { fprintf(fp, ",****\n"); } else { fprintf(fp, "\n"); } fclose(fp); if (gDebug > 1) pc.printf(" done\n"); } } } */ /*----------*/ // print "local" directory void listdir(void) { pc.printf("/local directory:\n"); DIR *d; struct dirent *p; d = opendir("/local"); if (d != NULL) { while ((p = readdir(d)) != NULL) { printf(" - %s\n", p->d_name); } } else { pc.printf("Could not open -local- directory!\n"); } closedir(d); } /*----------*/ // print "sd" directory ***broken!! /* void listdirSD(void) { pc.printf("/sd directory:\n"); DIR *d; struct dirent *p; d = opendir("/sd"); if (d != NULL) { while ((p = readdir(d)) != NULL) { printf(" - %s\n", p->d_name); } } else { printf("Could not open -sd- directory!\n"); } closedir(d); } */ /*----------*/ void getMbedSN() { unsigned int SerialNum[5] = {58,0,0,0,0}; typedef void (*CallMe)(unsigned int[],unsigned int[]); CallMe CallMe_entry=(CallMe)0x1FFF1FF1; CallMe_entry(SerialNum, SerialNum); if (!SerialNum[0]) pc.printf("mbed serial number is: %0.8x %0.8x %0.8x %0.8x\n", SerialNum[1], SerialNum[2], SerialNum[3], SerialNum[4]); else pc.printf("***Unable to retrieve Serial Number from LPC Flash\n"); } /* display MAC address */ void getMbedMAC() { // uint64_t uid = 0; //// char mac[6]; mbed_mac_address(mac); // uid = mac[0] << 40 | mac[1] << 32 | // mac[2] << 24 | mac[3] << 16 | // mac[4] << 8 | mac[5] << 0; pc.printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } /* initialize dds60 configuration file if it doesn't already exist */ void InitIniFile() { FILE *fp = fopen("/local/dds60.ini", "w"); if (fp == NULL) { pc.printf("***Cannot create dds60.ini file!!!\n"); } else { if(gDebug) pc.printf("***Updating/Creating dds60.ini file... \n"); fprintf(fp, "# DDS-60 configuration file\r\n"); fprintf(fp, "\r\n[Freqs]\r\n"); fprintf(fp, "BaseFrequency=%f\r\n",LclBaseFreq); fprintf(fp, "IFFrequency=%f\r\n", LclIfFreq); fprintf(fp, "StepFrequency=%f\r\n", StepFreq); fprintf(fp, "\r\n[Global]\r\n"); fprintf(fp, "Timezone(hrs)=%d\r\n", TZone); fprintf(fp, "DstZone(hrs)=%d\r\n", DST); fprintf(fp, "NTPRefresh(sec)=%d\r\n", NTPUpdateValue); fprintf(fp, "gDebugLevel=%d\r\n", gDebug); fprintf(fp, "\r\n##END\r\n"); fclose(fp); if(gDebug) pc.printf(" done\n"); } OldgDebug = gDebug; OldDST = DST; OldTZone = TZone; OldPress0Ft = Press0Ft; } // Trim whitespace/CRLFs from both ends of a given string // for use with routine below char * str_cleanup(char *in) { char * out = in; // Trim leading spaces and CR/LF while (*out == ' ' || *out == '\t' || *out == '\r' || *out == '\n') out ++; // Trim trailing spaces and CR/LF int len = strlen(out)-1; while (out[len] == ' ' || out[len] == '\t' || out[len] == '\r' || out[len] == '\n') { out[len] = '\0'; len--; } return out; } // Simple ini file parser for SNTP configuration (Case-sensitive!) // This function is intended to be called only before SNTPClientInit(). // Returns: 0 if OK, errno otherwise enum { SECT_NONE, SECT_FREQS, SECT_GLOBAL, }; //int _SNTPClrAddresses(); int SNTPReadIniFile(const char* filename) { if (gDebug > 1) pc.printf("Before: tz:%d dst:%d ntpupd:%d baroZ:%.1f name:%s\n", TZone, DST, NTPUpdateValue, Press0Ft, hostname); FILE *f; char buf[512]; // bool addresses_cleared = false; bool hname = false; f = fopen(filename, "r"); if (!f) return -1; // errno not used? char *buf1, *buf2; int section=SECT_NONE; int line = 0; while (fgets(buf, sizeof(buf)/sizeof(buf[0]), f)) { line++; buf1 = str_cleanup(buf); if (*buf1 == '#' || *buf1 == '\0') continue; // Comment line or empty line - skip if (*buf1 == '[') { // New section if (0 == strncmp(buf1,"[Freqs]", sizeof("[Freqs]")-1)) { section=SECT_FREQS; /* if (!addresses_cleared) { // Clear addresses only once. _SNTPClrAddresses(); addresses_cleared = true; } */ } else if (0 == strncmp(buf1,"[Global]", sizeof("[Global]")-1)) { section=SECT_GLOBAL; } else { section=SECT_NONE; fprintf(stderr, "***File \"%s\", line %d - section \"%s\" is not understood.\r\n", filename, line, buf1); } } else { // Section values switch (section) { case SECT_FREQS: buf2 = strchr(buf1, '='); if (buf2) { *buf2++ = '\0'; // Now buf1 has variable name, buf2 has value buf2 = str_cleanup(buf2); if (0 == strncmp(buf1, "BaseFrequency", sizeof("BaseFrequency")-1)) { LclBaseFreq = strtof(buf2, &buf2); } else if (0 == strncmp(buf1, "IFFrequency", sizeof("IFFrequency")-1)) { LclIfFreq = strtof(buf2, &buf2); } else if (0 == strncmp(buf1, "StepFreq", sizeof("StepFreq")-1)) { StepFreq = strtod(buf2, &buf2); } else { pc.printf("***File \"%s\", line %d - unrecognized variable \"%s\" in section [Freqs]\r\n", filename, line, buf1); } } else { pc.printf("***File \"%s\", line %d - unrecognized statement in section [Freqs]: %s\r\n", filename, line, buf1); } break; case SECT_GLOBAL: buf2 = strchr(buf1, '='); if (buf2) { *buf2++ = '\0'; // Now buf1 has variable name, buf2 has value buf2 = str_cleanup(buf2); if (0 == strncmp(buf1, "Timezone(hrs)", sizeof("Timezone(hrs)")-1)) { TZone = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "NTPRefresh(sec)", sizeof("NTPRefresh(sec)")-1)) { NTPUpdateValue = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "gDebugLevel", sizeof("gDebugLevel")-1)) { gDebug = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "bootDHCP", sizeof("bootDHCP")-1)) { bootDHCP = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "MyName", sizeof("MyName")-1)) { if (hname == false) { hname = true; hostname = buf2; if (gDebug > 1) pc.printf("buf2:%s hn:%s\n", buf2, hostname); } } else if (0 == strncmp(buf1, "PressureSeaLevel", sizeof("PressureSeaLevel")-1)) { Press0Ft = strtof(buf2, &buf2); //} else if (0 == strncmp(buf1, "RtcUtc", sizeof("RtcUtc")-1)) { // gSntpRtcUtc = (bool)strtol(buf2, &buf2, 10); } else if (0 == strncmp(buf1, "DstZone(hrs)", sizeof("DstZone(hrs)")-1)) { DST = strtod(buf2, &buf2); } else { pc.printf("***File \"%s\", line %d - unrecognized variable \"%s\" in section [Global]\r\n", filename, line, buf1); } } else { pc.printf("***File \"%s\", line %d - unrecognized statement in section [Global]: %s\r\n", filename, line, buf1); } break; default: pc.printf("***File \"%s\", line %d - unrecognized statement / no section: %s\r\n", filename, line, buf1); } } } fclose(f); pc.printf("DDS60 configuration read from \"%s\", %d lines.\r\n", filename, line); pc.printf("- gDebug display level: %d\n", gDebug); pc.printf("- Time Zone: %d hours\n", TZone); //pc.printf("- Daylight Saving Time - "); if (DST == 0) { pc.printf("- Standard Time\n"); } else { pc.printf("- Daylight Saving Time\n"); } pc.printf("- NTC update: %d seconds\n", NTPUpdateValue); if (bootDHCP == 1) { pc.printf("- booting HTTP, host name: %s\n", hostname); } else { pc.printf("- booting static IP\n"); } pc.printf("- Base Frequency: %.3f kPa\n", LclBaseFreq); pc.printf("- IF Frequency: %.3f kPa\n", LclIfFreq); pc.printf("- Step Frequency: %.3f kPa\n", StepFreq); // if (gDebug > 1) pc.printf("After: tz:%d dst:%d ntpupd:%d baroZ:%.1f name:%s\n", TZone, DST, NTPUpdateValue, Press0Ft, hostname); OldgDebug = gDebug; OldDST = DST; OldTZone = TZone; OldPress0Ft = Press0Ft; dds60.SetBaseValue(LclBaseFreq); dds60.SetIfValue(LclIfFreq); dds60.CalcNewValue(); OldStepFreq = StepFreq; return 0; } //update LCD based on Sequence count void UpdLCD() { double Fdata = 0.0; int UIdata = 0; char Cdata = 0; if(Sequence == 0) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("DDS-60 %d", revision); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("K Braun"); } if(Sequence == 1) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("(%d) Base Freq:", Sequence); lcdt.locate(0,1); //column(0-15), row(0-1) Fdata = dds60.GetBaseValue(); lcdt.printf(" %.3f", Fdata); } if(Sequence == 2) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("(%d) IF Freq:", Sequence); lcdt.locate(0,1); //column(0-15), row(0-1) Fdata = dds60.GetIfValue(); lcdt.printf(" %.3f", Fdata); } if(Sequence == 3) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("(%d) Step Freq:", Sequence); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf(" %.3f", StepFreq); } if(Sequence == 4) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("(%d) AD9851 data:", Sequence); lcdt.locate(0,1); //column(0-15), row(0-1) UIdata = dds60.GetFD32Value(); Cdata = dds60.GetFortyValue(); lcdt.printf(" 0x%02x%08x\n", Cdata, UIdata); } if(Sequence == 5) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) if(ErFlag == false) { lcdt.printf("DDS-60 %d", revision); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("K Braun"); } else { lcdt.printf("(%d) Entry Error", Sequence); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf(" !!!!!!!!"); } } if(Sequence > 5) { lcdt.cls(); lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("(%d) huh??", Sequence); } } // manu selection menu void mainMenu() { pc.printf("\n**************************************************************************\n"); pc.printf(" MAIN MENU\n"); double Fdata; Fdata = dds60.GetBaseValue(); pc.printf("AD9851 Summary:\nBase Freq: %.3f\n", Fdata); Fdata = dds60.GetIfValue(); pc.printf("IF Freq: %.3f\n", Fdata); pc.printf("Step Freq: %.3f\n", StepFreq); unsigned int UIdata; UIdata = dds60.GetFD32Value(); char Cdata; Cdata = dds60.GetFortyValue(); pc.printf("40 bit wd: 0x%02x%08x\n", Cdata, UIdata); char onoff = Cdata & 0x04; if(onoff == 0) { pc.printf("AD9851 is: -ON-\n\n"); } else { pc.printf("AD9851 is: -OFF-\n\n"); } // pc.printf("----------\n"); pc.printf(" B - Base Frequency Y - IF Frequency S - Step Frequency\n"); pc.printf(" E - Enable DDS-60 X - Disable DDS-60\n"); pc.printf(" U - Update DDS-60 W - Write to Flash\n"); pc.printf(" I - Inc Step Frequency D - Dec Step Frequency\n"); pc.printf(" R - Reboot!!!\n\n"); // pc.printf("\n"); pc.printf("**************************************************************************\n"); pc.printf("Selection: "); } // This function is called when a character goes from the TX buffer // to the Uart THR FIFO register. //void txCallback(MODSERIAL_IRQ_INFO *q) { // led2 = !led2; //} // This function is called when TX buffer goes empty //void txEmpty(MODSERIAL_IRQ_INFO *q) { // led2 = 0; // pc.puts(" testing done...\n"); // lcdt.locate(0,1); //column(0-15), row(0-1) // lcdt.printf(" "); //print -me- on LCD // lcdt.locate(0,1); //column(0-15), row(0-1) // lcdt.printf("done"); //print -me- on LCD //} // This function is called when a character goes into the RX buffer. //void rxCallback(MODSERIAL_IRQ_INFO *q) { // led3 = !led3; // pc.putc(uart.getc()); //} // This function is called when a character goes into the RX buffer. void Rx_interrupt() { //void rxCallbackpc(MODSERIAL_IRQ_INFO *q) { inchar = pc.getc(); // led4 = !led4; if(inchar == BS) { if(!pcRxQty == 0) { pcRxData[pcRxQty] = 0; pcRxQty = pcRxQty -1; } } else if(inchar == CR) { pcRxLine = true; } else if(inchar == LF) { pcRxLine = true; } else { if(pcRxQty < sizeof(pcRxData)) { pcRxData[pcRxQty] = inchar; pcRxQty = pcRxQty++; // pc.putc(inchar); } else { // pc.printf ("pcRxData is full!!\n"); pcRxEOB = true; } } } //clear RxData buffer with all 00's void pcClrLineBuf() { pcRxQty = 0; // MODSER RX data counter/pointer for(int i = 0; i < (sizeof(pcRxData) + 1); i++) {// clear out rx buffer pcRxData[i] = 0; pcRxLine = false; pcRxEOB = false; pcRxIsNumb = false; } } // assemble a test line. if it is a number, turn it into a double int loop = 0; void higherDecode() { double Fdata = 0.0; // unsigned int UIdata; // char Cdata; if(pcRxLine == true) { //data in rx buffer? loop = loop++; if(gDebug) pc.printf("loop: %d\n", loop); if(pcRxQty == 1) { //single alpha char? if((pcRxData[0] == 'b') || (pcRxData[0] == 'B')) { //enter Base frequency Fdata = dds60.GetBaseValue(); pc.printf("\nBASE Frequency: %.3f New: ", Fdata); Fcmd = pcRxData[0] | 0x20; // pcClrLineBuf(); } else if((pcRxData[0] == 'y') || (pcRxData[0] == 'y')) { //enter IF frequency Fdata = dds60.GetIfValue(); pc.printf("\nIF Frequency: %.3f New: ", Fdata); Fcmd = pcRxData[0] | 0x20; } else if((pcRxData[0] == 's') || (pcRxData[0] == 'S')) { //enter step frequency value pc.printf("\nStep Frequency: %.3f New: ", StepFreq); Fcmd = pcRxData[0] | 0x20; } else if((pcRxData[0] == 'r') || (pcRxData[0] == 'R')) { //enable DDS-60 pc.printf("\nREBOOTING...\n"); wait(0.1); mbed_reset(); mainMenu(); } else if(pcRxIsNumb == false) { pc.printf("2-huh???\n"); pcClrLineBuf(); mainMenu(); } } } if((pcRxIsNumb == true) && (Fcmd == 'b')) { // pc.printf("here-b ?\n"); dds60.SetBaseValue(pcRxNumb); // pcClrLineBuf(); Fcmd = 0; mainMenu(); } else if((pcRxIsNumb == true) && (Fcmd == 'y')) { // pc.printf("here-y ?\n"); dds60.SetIfValue(pcRxNumb); pcRxIsNumb = false; Fcmd = 0; mainMenu(); } else if((pcRxIsNumb == true) && (Fcmd == 's')) { // if(gDebug > 1) pc.printf("1-sF: %.3f\n", StepFreq); StepFreq = pcRxNumb; if(StepFreq >= 0.0) { // if(gDebug > 1) pc.printf("2-sF: %.3f\n", StepFreq); pcRxIsNumb = false; } else { StepFreq = OldStepFreq; pc.printf("Step neg number!!!\n"); } Fcmd = 0; mainMenu(); } else if((pcRxIsNumb == true) && (!((Fcmd == 'b') || (Fcmd == 'y') || (Fcmd == 's')))) { Fcmd = 0; pcClrLineBuf(); mainMenu(); } pcClrLineBuf(); } void pcRx() { double Fdata = 0.0; if((pcRxData[0] == ESC) || (pcRxData[0] == ticC)) { //kill? go back to main menu wait_us(100); pc.printf("\nblam!!!\n"); pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'e') || (pcRxData[0] == 'E')) { //enable DDS-60 pc.printf("\nEnabling AD9851...\n"); dds60.AD9851Enable(); pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'x') || (pcRxData[0] == 'X')) { //disable DDS-60 pc.printf("\nDisable AD9851...\n"); dds60.AD9851Disable(); pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'w') || (pcRxData[0] == 'W')) { //save values pc.printf("\nWriting current values to Flash...\n"); LclBaseFreq = dds60.GetBaseValue(); LclIfFreq = dds60.GetIfValue(); InitIniFile(); pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'u') || (pcRxData[0] == 'U')) { //update DDS-60 ErFlag = dds60.CalcNewValue(); if(ErFlag == true) { pc.printf("\nfrequency overflow error(1)!!\n"); } else { pc.printf("\nUpdating AD9851...\n"); LclBaseFreq = dds60.GetBaseValue(); LclIfFreq = dds60.GetIfValue(); } pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'i') || (pcRxData[0] == 'I')) { //increment DDS-60 frequency by step value Fdata = dds60.GetBaseValue(); Fdata = Fdata + StepFreq; dds60.SetBaseValue(Fdata); ErFlag = dds60.CalcNewValue(); if(ErFlag == true) { pc.printf("\nfrequency overflow error(2)!!\n"); } else { pc.printf("\nStepping up freq...\n"); LclBaseFreq = dds60.GetBaseValue(); LclIfFreq = dds60.GetIfValue(); } pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if((pcRxData[0] == 'd') || (pcRxData[0] == 'D')) { //decrement DDS-60 frequency by step value Fdata = dds60.GetBaseValue(); Fdata = Fdata - StepFreq; dds60.SetBaseValue(Fdata); ErFlag = dds60.CalcNewValue(); if(ErFlag == true) { pc.printf("\nfrequency overflow error(3)!!\n"); } else { pc.printf("\nStepping down freq...\n"); LclBaseFreq = dds60.GetBaseValue(); LclIfFreq = dds60.GetIfValue(); } pcClrLineBuf(); pcRxLine = false; pcRxEOB = false; mainMenu(); } else if(pcRxLine == true) { // pcRxLine = false; // pc.printf(" -CR/LF- det count:%d size:%d\n", pcRxQty, sizeof(pcRxData)); if(pcRxQty == 0) { wait_us(100); pc.printf("empty...\n"); pcClrLineBuf(); mainMenu(); } else { bool OneDot = false; pcRxIsNumb = true; for(int x = 0; x < pcRxQty; x++) { char p = pcRxData[x]; if(pcRxIsNumb == true) { if(!((p == DP) || ((p >= '0') && (p <= '9')) || (pcRxData[0] == '-'))) { //-not- 0-9 or DP ? pcRxIsNumb = false; } if((p == DP) && (pcRxQty == 1)) { //DP w/o numbers ? pcRxIsNumb = false; } } if((p == DP) && (OneDot == true) && (pcRxQty > 1)) { //more than one DP? pcRxIsNumb = false; } if(p == DP) { //one or more DP? OneDot = true; } // pc.printf("%c",p); } } if(pcRxIsNumb == true) { pcRxNumb = atof(pcRxData); // pc.printf("valid number: %f\n", pcRxNumb); // pcClrLineBuf(); } higherDecode(); pcClrLineBuf(); // pc.printf("\n"); } else if(pcRxEOB == true) { pcRxEOB = false; pc.printf("RxBuff max'd out!!\n"); } else if(inchar == SP) { // pc.printf(" -SP- det\n"); inchar = 0; } } /*********************************************************************************************/ int main() { pc.baud(921600); //set up USB serial speed i2c.frequency(400000); //set up i2c speed pcRxQty = 0; // MODSER RX data counter/pointer pcClrLineBuf(); // initialize pcRxData lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("DDS-60 %d", revision); //print revision on LCD lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("K Braun"); //print -me- on LCD pc.printf("\n\n"); pc.printf("-------------------------------------------------------------------\n"); pc.printf("DDS-60 Control Routines %d K Braun\n", revision); getMbedSN(); //display mbed's serial number getMbedMAC(); //display mbed's MAC address wait(DISP_SLOW); dds60.SetM6Value('A'); // Check if we can use modify the http name of the mbed FILE *fp = fopen("/local/whoami.ini", "r"); // char *hostname = DEFAULTHOSTNAME; if (fp == NULL) { pc.printf(" No /local/whoami.ini file, defaulting to: %s\n",hostname); } else { char localbuf[64]; hostname = fgets(localbuf, sizeof(localbuf)-1, fp); pc.printf("Found /local/whoami.ini file. my name is: %s\n",hostname); fclose(fp); } FILE *fpi = fopen("/local/dds60.ini", "r"); if (fpi == NULL) { InitIniFile(); pc.printf("***rebooting after file creation...."); wait(2.0); mbed_reset(); } else { pc.printf("Found /local/dds60.ini file...\n"); fclose(fpi); SNTPReadIniFile("/local/dds60.ini"); } if (gDebug) listdir(); //get local file listing // broken!!! if (gDebug) listdirSD(); //get sd file listing // //NOTE: mbed hangs if no SD card installed - need to fix!!!!!! // lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("SD Card Missing!"); //---in case SD drive hangs forever--- /*See if INDEX.HTM can be created on SD micro drive */ if (gDebug > 3) { // char *WriteTest = "This is a Test!!!"; fp = fopen("/sd/INDEX.HTM", "w+"); if (fp == NULL) { pc.printf("***Cannot create INDEX.HTM file\n"); } else { // char localbuf[32]; // localbuf = WriteTest; fprintf(fp, "This is a Test!!!\n"); pc.printf("Creating /sd/INDEX.HTM file\n"); fclose(fp); } } fp = fopen("/sd/index.htm", "r"); if (fp == NULL) { use_sd = false; if (gDebug) pc.printf("***No INDEX.HTM file - using LocalFilesystem for WebServer.\r\n"); } else { use_sd = true; fclose(fp); if (gDebug) pc.printf("Found SD card with INDEX.HTM file - using SD for WebServer.\r\n"); } if ((use_sd == true) && (gDebug > 3)) pc.printf(" "); // to get rid of use_sd "never used" warning disp_i2c(); //display all devies on I2C bus pc.printf("gDebug level: %d\n", gDebug); wait(DISP_SLOW); /* /////////////////////////////////////////////////////////////////////////////// // testing ad9851 routines lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("Testing"); //print Testing on LCD lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("AD9851..."); //print item on LCD wait(DISP_SLOW); double Fdata; Fdata = dds60.GetBaseValue(); pc.printf("----------\nTesting AD9851 routines\nBase Freq: %.3f\n", Fdata); Fdata = dds60.GetIfValue(); pc.printf("IF Freq: %.3f\n", Fdata); unsigned int UIdata; UIdata = dds60.GetFD32Value(); pc.printf("32 SDO: 0x%08x\n", UIdata); char Cdata; Cdata = dds60.GetFortyValue(); pc.printf("5th byte: 0x%02x\n", Cdata); pc.printf("40 bit wd: 0x%02x%08x\n", Cdata, UIdata); dds60.AD9851Enable(); Cdata = dds60.GetFortyValue(); pc.printf("5th byte: 0x%02x\n", Cdata); dds60.AD9851Disable(); Cdata = dds60.GetFortyValue(); pc.printf("5th byte: 0x%02x\n", Cdata); dds60.CalcNewValue(); UIdata = dds60.GetFD32Value(); Cdata = dds60.GetFortyValue(); pc.printf("40 bit wd: 0x%02x%08x\n", Cdata, UIdata); pc.printf("----------\n"); dds60.AD9851Enable(); bool ErFlag; ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 1 error!!\n"); dds60.SetBaseValue(7320000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 2 error!!\n"); dds60.SetIfValue(1620000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 3 error!!\n"); dds60.SetM6Value('0'); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 4 error!!\n"); dds60.SetBaseValue(30320000.0); ErFlag = dds60.CalcNewValue(); if(ErFlag == true) pc.printf(" 5a error!!\n"); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 5 error!!\n"); dds60.SetM6Value('1'); ErFlag = dds60.CalcNewValue(); if(ErFlag == true) pc.printf(" 6a error!!\n"); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 6 error!!\n"); dds60.SetBaseValue(30320000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 7 error!!\n"); dds60.SetM6Value('A'); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 8 error!!\n"); dds60.SetBaseValue(30320000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 9 error!!\n"); dds60.SetBaseValue(180000000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 10 error!!\n"); dds60.SetBaseValue(27000000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 11 error!!\n"); dds60.SetBaseValue(127000000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 12 error!!\n"); dds60.SetBaseValue(10000000.0); dds60.SetIfValue(0.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 13 error!!\n"); dds60.SetBaseValue(123456.789); dds60.SetIfValue(0.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 14 error!!\n"); dds60.SetBaseValue(29545000.0); dds60.SetIfValue(455000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 15 error!!\n"); dds60.SetBaseValue(29544999.999); dds60.SetIfValue(455000.0); dds60.CalcNewValue(); ErFlag = dds60.GetErrFlagValue(); if(ErFlag == true) pc.printf(" 16 error!!\n"); pc.printf("----------\n"); */ /////////////////////////////////////////////////////////////////////////////// // pc.printf("----------\nTesting MOSERIAL routines\n"); // int c = 'A'; // lcdt.cls(); //init the LCD // lcdt.locate(0,0); //column(0-15), row(0-1) // lcdt.printf("Testing"); //print Testing on LCD // lcdt.locate(0,1); //column(0-15), row(0-1) // lcdt.printf("MODSERIAL..."); //print item on LCD // Ensure the baud rate for the PC "USB" serial is much // higher than "uart" baud rate below. // pc.baud(PC_BAUD); // Use a deliberatly slow baud to fill up the TX buffer // uart.baud(1200); // uart.attach(&txCallback, MODSERIAL::TxIrq); // uart.attach(&rxCallback, MODSERIAL::RxIrq); // uart.attach(&txEmpty, MODSERIAL::TxEmpty); // pc.attach(&rxCallbackpc, MODSERIAL::RxIrq); pc.attach(&Rx_interrupt, Serial::RxIrq); // led1 = 1; // Show start of sending with LED1. // for (int loop = 0; loop < 512; loop++) { // uart.printf("%c", c); // c++; // if (c > 'Z') c = 'A'; // } // End program. Flash LED4. Notice how LED 2 and 3 continue // to flash for a short period while the interrupt system // continues to send the characters left in the TX buffer. ErFlag = dds60.CalcNewValue(); //init DDS-60 lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("DDS-60 %d", revision); //print revision on LCD pcClrLineBuf(); mainMenu(); // int loop = 0; Fcmd = 0; Sequence = 0; Tic = 0; while (true) { wait(0.05); if(Led1Up == true) { Led1Pwm = Led1Pwm + 0.005; led1 = Led1Pwm; if(Led1Pwm >= 0.20) { Led1Up = false; } } else { Led1Pwm = Led1Pwm - 0.005; led1 = Led1Pwm; if(Led1Pwm <= 0.01) { Led1Up = true; } } // led1 = !led1; pcRx(); Tic = Tic++; if(Tic >= 40) { Tic = 0; UpdLCD(); //update LCD Values Sequence = Sequence++; if(Sequence >= 6) Sequence = 0; } } }