my DNAxxx program
I am trying to create a DNA board specific program. I created a separate file, dnsSD.c, that will hold mount() and List(), to start with. The main file is DNAxxx.c which is a UI that will call the specific functions, in this case mount(), and List(). So far the project compiles without errors, but when I request List(), nothing happens, the program just hangs. So first you use mountSD to mount() which seems to work, then ll to List() which just hangs.
I would appreciate if somebody would look at this and see what I am doing wrong.
Thanks
Ray
I would appreciate if somebody would look at this and see what I am doing wrong.
Thanks
Ray

Comments
Ray
Recommended reading.
https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxwcm9wZWxsZXJnY2N8Z3g6NWJlNzM0NzBlODZiYzJkMQ&pli=1
Read sections 5 through 7. The simplest way to add SDcard is mentioned in the very last paragraph of section 7.
For example add these to your config file:
Martin offers these pages for DNA.
http://mghdesigns.com/wiki/dna:start
The dna.cfg file seems complicated, but it is just a version that uses the loader's expression parser.
http://mghdesigns.com/wiki/dna:dna.cfg
Ray
# Default SPI config spi-base: 0 sd-driver: sd_driver.dat sdspi-do: {spi-base} + 0 sdspi-clk: {spi-base} + 1 sdspi-di: {spi-base} + 2 sdspi-cs: {spi-base} + 3Ray
Now I am thinking about including some code for using the RTC, not sure how I am going to have it appear in the UI. At the MGH Designs web site they refer you to Roy Eltham's Spin driver for the Seiko RTC, I looked at the code, and I am not sure how that will work for me. Are their any examples of I2C, and how to use it with C? I guess if look at some good examples of, how to use I2C code, maybe I can figure it out. Any ideas will be appreciated.
Ray
Ray
/** * @file testI2C.c * This is the main testI2C program start point. */ #include <stdio.h> #include <propeller.h> #include <unistd.h> #include <i2c.h> #define DeviceID 0b0110_0000 // According to S-35390A RTC Driver Roy Eltham /** * Main program function. */ int main(void) { I2C *bus; waitcnt(CNT + CLKFREQ); if (!(bus = i2cBootOpen())) { printf("error: Can't open boot i2c bus.\n"); return 1; } printf("Got past the bootopen check\n"); return 0; }int DetectAdcChip(I2C *bus, int address) { int retries = I2C_RETRIES; while (--retries >= 0) { if (i2cRead(bus, address, NULL, 0, TRUE) == 0) return 0; } return 1; }testI2C.c:19:19: error: 'I2C_RETRIES' undeclared (first use in this function)
Where is I2C_RETRIES? I guess it is not in <i2c.h>? Slowly, but ...
Ray
/** * @file testI2C.c * This is the main testI2C program start point. */ #include <stdio.h> #include <propeller.h> #include <unistd.h> #include <i2c.h> #define DeviceID 0b01100000 // According to S-35390A RTC Driver Roy Eltham #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif int DetectRtcChip(I2C *bus, int address) { int retries = I2C_RETRIES; while (--retries >= 0) { if (i2cRead(bus, address, NULL, 0, TRUE) == 0) return 0; } return 1; } /** * Main program function. */ int main(void) { int rtcAddr; I2C *bus; waitcnt(CNT + CLKFREQ); if (!(bus = i2cBootOpen())) { printf("error: Can't open boot i2c bus.\n"); return 1; } if (DetectRtcChip(bus, DeviceID) == 0) rtcAddr = DeviceID; else { printf("Error: no RTC chip found\n"); return 1; } printf("Got past the bootopen check\n"); return 0; }Ray
/** * @file testI2C.c * This is the main testI2C program start point. */ #include <stdio.h> #include <propeller.h> #include <unistd.h> #include <i2c.h> #define DeviceID 0b01100000 // According to S-35390A RTC Driver Roy Eltham #define I2C_RETRIES 5 #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif int DetectRtcChip(I2C *bus, int address) { int retries = I2C_RETRIES; while (--retries >= 0) { if (i2cRead(bus, address, NULL, 0, TRUE) == 0) return 0; } return 1; } int RtcIn(I2C *bus, int address, int buffer[7]) { int retries = I2C_RETRIES; i2cRead(bus, address, buffer[0], 0, TRUE); return 0; } int ConvertFromBCD(int value) { int result; result = ((value / 16) * 10) + (value << 16); return (result); } /** * Main program function. */ int main(void) { int rtcAddr; I2C *bus; waitcnt(CNT + CLKFREQ); if (!(bus = i2cBootOpen())) { printf("error: Can't open boot i2c bus.\n"); return 1; } if (DetectRtcChip(bus, DeviceID) == 0) rtcAddr = DeviceID; else { printf("Error: no RTC chip found\n"); return 1; } printf("rtc[0] = %g\n", ConvertFromBCD(RtcIn(bus,rtcAddr,0))); printf("Got to the last of code.\n"); return 0; }Basically, in the UI you have these commands: help, time, date, day, month, year, quit. As mentioned the time command does not work. You have to set the DateTime manually in the program with the rtc1_Setdatetime() command which at the moment contains some irrelevant data. I just wanted to test out the RTC part of the DNA board to see if it really works.
Once the time clock part gets fixed then I will probably incorporate this into the DNAxxx(filetest) program.
Ray
You should call rtc1_Update() somewhere in your while loop such as after gets(buffer). Otherwise the time and date will not change when read by your UI.
Another thing I noticed is that basic_i2c_driver.c relies heavily on the code running slowly. CMM "apparently" works, but LMM does not. By apparently, I mean that it's more or less an accident that it works and a higher clock rate or other performance improvements might make the driver fail.
//Set date time: Month,day,year,DOW,min,seconds
//DOW - 0-Sun,1-Mon,2-tue,3-Wed,4-Thur,5-Fri,6-Sat
rtc1_Setdatetime(9,13,12,5,12,51);
Once I put in the correct Setdatetime() values, the program runs as expected.
For a more ambitious project I was thinking, use the RTC lib, in a thread, and have it update from the hardware RTC. Then of course you have to figure where you would update the hardware RTC from, and of course if someone using a different RTC ...
Now I have to figure out how I will incorporate the RTC program into the DNAxxx(filetest) program.
<edit> I also noticed that if you use printc.c program, it screws the output to the screen. Also, if you check the Simple printf, that also screws up the output to the screen. <edit>
Ray
As for RTC, you could try something like below to use the built-in unix time facilities.
This is obviously not for the DNA board, I use it on my tiny Gamebaby LCD box, and it has a PASM driver that is accessible via GbI2C_rtc_* function calls. I call RTC_init() from the main program at startup.
/** * @file RTC1338.c */ #include <sys/rtc.h> #include <sys/time.h> #include <time.h> #include "GbI2C.h" #include <stdio.h> // RTC year is only 0-99. Unix computing epoc is Jan 1, 1970 #define YEARADJUST 70 static time_t mytime; int RTC_setTime(const struct timeval *tv) { unsigned char ones, tens; struct tm *t = localtime(&tv->tv_sec); mytime = tv->tv_sec; /* printf("%02d:%02d:%02d ",t->tm_hour, t->tm_min, t->tm_sec); printf("%02d-%02d-%04d %d %d\n",t->tm_mon, t->tm_mday, t->tm_year, t->tm_wday, tv->tv_sec); printf("RTC_setTime Seconds = %10d TimeStamp %s\n", mytime, asctime(t)); */ /* * write rtc register fields. */ /* make sure seconds are encoded as BCD */ ones = t->tm_sec & 0xf; tens = (t->tm_sec/10) & 0x7; t->tm_sec = (tens << 4) + ones; /* CH bit is 0 by now. Should be to keep timer going */ GbI2C_rtc_writeReg(GbI2C_RTC_SECOND, t->tm_sec); /* make sure minutes are encoded as BCD */ ones = t->tm_min & 0xf; tens = (t->tm_min/10) & 0x7; t->tm_min = (tens << 4) + ones; GbI2C_rtc_writeReg(GbI2C_RTC_MINUTE, t->tm_min); /* make sure hours are encoded as BCD 24 hour time */ ones = t->tm_hour & 0xf; tens = (t->tm_hour/10) & 0x3; t->tm_hour = (tens << 4) + ones; /* 24 hour bit is 0 by now */ GbI2C_rtc_writeReg(GbI2C_RTC_HOUR, t->tm_hour); /* make sure week days are encoded as BCD */ t->tm_wday &= 0xf; GbI2C_rtc_writeReg(GbI2C_RTC_DAY, t->tm_wday); /* make sure month days are encoded as BCD */ ones = t->tm_mday & 0xf; tens = (t->tm_mday/10) & 0x3; t->tm_mday = (tens << 4) + ones; GbI2C_rtc_writeReg(GbI2C_RTC_DATE, t->tm_mday); /* make sure months are encoded as BCD */ ones = t->tm_mon & 0xf; tens = (t->tm_mon/10) & 0x1; t->tm_mon = (tens << 4) + ones; GbI2C_rtc_writeReg(GbI2C_RTC_MONTH, t->tm_mon+1); /* make sure years are encoded as BCD */ ones = (t->tm_year-YEARADJUST) & 0xf; tens = ((t->tm_year-YEARADJUST)/10); t->tm_year = (tens << 4) + ones; GbI2C_rtc_writeReg(GbI2C_RTC_YEAR, t->tm_year); return 0; } int RTC_getTime(struct timeval *tv) { struct tm t; /* read all rtc registers */ GbI2C_rtc_readRegs(); /* get rtc register fields */ t.tm_sec = GbI2C_rtc_getReg(GbI2C_RTC_SECOND); t.tm_min = GbI2C_rtc_getReg(GbI2C_RTC_MINUTE); t.tm_hour = GbI2C_rtc_getReg(GbI2C_RTC_HOUR); t.tm_wday = GbI2C_rtc_getReg(GbI2C_RTC_DAY); t.tm_mday = GbI2C_rtc_getReg(GbI2C_RTC_DATE); t.tm_mon = GbI2C_rtc_getReg(GbI2C_RTC_MONTH)-1; t.tm_year = GbI2C_rtc_getReg(GbI2C_RTC_YEAR); t.tm_sec = ((t.tm_sec >> 4) & 7)*10 + (t.tm_sec & 0xF); // bcd conversion t.tm_min = ((t.tm_min >> 4) & 7)*10 + (t.tm_min & 0xF); // bcd conversion t.tm_hour = ((t.tm_hour >> 4) & 1)*10 + (t.tm_hour & 0xF); // bcd conversion t.tm_wday = t.tm_wday & 0x7; t.tm_mday = ((t.tm_mday >> 4) & 3)*10 + (t.tm_mday & 0xF); // bcd conversion t.tm_mon = ((t.tm_mon >> 4) & 3)*10 + (t.tm_mon & 0xF); // bcd conversion t.tm_year = (t.tm_year >> 4)*10 + (t.tm_year & 0xF); // bcd conversion t.tm_year = t.tm_year + YEARADJUST; mytime = mktime(&t); tv->tv_sec = mytime; tv->tv_usec = 0; /* printf("%02d:%02d:%02d ",t.tm_hour, t.tm_min, t.tm_sec); printf("%02d-%02d-%04d %d %d\n",t.tm_mon, t.tm_mday, t.tm_year, t.tm_wday, tv->tv_sec); printf("RTC_getTime Seconds = %10d TimeStamp %s\n", mytime, asctime(&t)); */ return 0; } void RTC_init() { int t; /* make sure clock is enabled */ t = GbI2C_rtc_readReg(GbI2C_RTC_SECOND) & ~(0x80); GbI2C_rtc_writeReg(GbI2C_RTC_SECOND, t); /* make sure we are using 24 hour time */ t = GbI2C_rtc_readReg(GbI2C_RTC_HOUR) & ~(0x40); GbI2C_rtc_writeReg(GbI2C_RTC_HOUR, t); _rtc_gettime = RTC_getTime; _rtc_settime = RTC_setTime; }I guess we have to consider what types of programs to use with the spin2cpp program; are programs that use their own i2c going to fail? What are the limtations of the spin2cpp program? Is propGCC team going to provide the drivers to support the different RTC units? If so, when will that occur? Lots of questions to be answered.
I guess I have to rethink porting the dnaRTC program to the DNAxxx(filetest) program. I will try to look at the spin2cpp converted code and see if I can make it work using existing propGCC libs, but I can see a lot of problems that I may not be able to solve. I guess what I really need is a good, full use, I2C program example, to start with. I was using bits and pieces of existing code snippets, with no positive results. Any ides would be appreciated.
Ray
The official devices to be added for propeller-gcc and timing of that is up to Parallax (beyond what we have time add).
I use a COG driver with a C wrapper for time sensitive devices like I2C. Here's my entire GameBaby code collection if you want to see what I've done. There are 5 different devices on the I2C bus handled by one PASM driver.
I'm afraid that's a source code problem that's up to the user to fix.
EDIT: Set DELAY_CYCLES to 255 if you need to run at 100 KHz.
Ray
Ray
If you have a Spinneret board it would be interesting to get your code working on that card. It also has an RTC and SD card socket.
I just burned my EEPROM with the DNA-xxx program, and I noticed the file size, in CMM mode was ~28KB, I also noticed that their is nothing in SimpleIDE to prepare and store a program on the SD card, at least not for the DNA board. I guess MGH Designs has to do some more support work for the DNA board. In the mean time is their a work around? If the DNA-xxx program grows any bigger, bigger than 32KB in CMM, I will have to store it to the SD card because it will not fit on the EEPROM.
@Dave Hein, in the Burrows version of basic_i2c_driver, he added a couple of Methods, devicePresent(), writeLocation(), readLocation(). When I added those too the pasm_i2c_driver, and ran it through the spi2cpp, the resulting code, of pasm_i2c_driver did not work correctly in the C version. Was that just a fluke, or does their have to be something else done to pasm_i2c_driver to make those Methods work?
Is their a C to C++ conversion program, just wondering what DNA-xxx would look like and run like in C++ mode?
<edit> Just a thuoght, is there any way of using filetest and storing the created files to the EEPROM instead of/or the SD card? Then at least you could possibly use the filetest program on the QuickStart board. <edit>
Ray
Ray
void Get_Time() { time_t now; time_t tm_hour; //Get the hour now = time(NULL); printf("%s", asctime(localtime(&now))); tm_hour = time(tm_hour); printf("%s", asctime(localtime(&tm_hour))); //Display the hour }/** * @file softRTC.c * This is the main softRTC program start point. */ #include <stdio.h> #include <propeller.h> #include <time.h> #include <sys/rtc.h> #define BUFFERLEN 10 void Help(); void pause(int sec); void Set_Clock(); int getdst(); int prompttime(char *prompt); void Get_Time(); /** * Main program function. */ int main(void) { uint8_t buffer[40]; waitcnt(CLKFREQ + CNT); printf("This is the softRTC.\n"); Help(); while(1) { printf("> "); gets(buffer); if (!strcmp(buffer, "quit")) break; else if (!strcmp(buffer, "help")) { Help(); } else if (!strcmp(buffer, "setclock")) { Set_Clock(); } else if (!strcmp(buffer, "time")) { Get_Time(); } else { printf("Invalid Command!\n"); } } printf("System Stop!\n"); return 0; } void pause(int secs) { while (secs > 0) { waitcnt(CLKFREQ+CNT); --secs; } } void Help() { printf("Commands are: setclock, time, quit.\n"); } void Set_Clock() { struct timeval tv; struct tm t; t.tm_isdst = getdst(); t.tm_year = prompttime("Year")-1900; t.tm_mon = prompttime("Month")-1; t.tm_mday = prompttime("Day of the month"); t.tm_hour = prompttime("Hour"); t.tm_min = prompttime("Minute"); t.tm_sec = prompttime("Second"); tv.tv_sec = mktime(&t); settimeofday(&tv, 0); } int getdst() { int rc = 0; printf("Use daylight savings time [y/n] ? "); fflush(stdout); rc = (getchar() == 'y') ? 1 : 0; getchar(); return rc; } int prompttime(char *prompt) { int rc = 0; char *endp; char buffer[BUFFERLEN]; do { printf("Enter %s: ",prompt); fflush(stdout); fgets(buffer, BUFFERLEN,stdin); fflush(stdin); rc = strtol(buffer, &endp, 10); if (endp == buffer) { if ('\n' == *endp) { rc = 0; break; } printf("Invalid entry \"%c....\" Please enter a number.\n", *endp); } } while (endp == buffer); return rc; } void Get_Time() { time_t now; time_t tm_hour; now = time(NULL); printf("%s", asctime(localtime(&now))); tm_hour = time(tm_hour); printf("%s", asctime(localtime(&tm_hour))); }Generic time.h page that shows functions, etc...
http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
Describes formatting parameters for strftime.
http://pubs.opengroup.org/onlinepubs/7908799/xsh/strftime.html
Here's some code from my LCD project.
// using these headers #include <stdio.h> #include <sys/rtc.h> #include <sys/time.h> #include <time.h> void showTime() { char timebuff[16]; time_t now = 0; // now as zero says get current time now = time(&now); // get number of seconds since Jan 1, 1970 // "now" has time LCD_setTextXY(1,1); LCD_dec(now); // Show abbreviated "month day, year" strftime(timebuff,16,"%b %d,%Y",localtime(&now)); LCD_printXY(timebuff,1,2); // %T is replaced by the time (%H:%M:%S). strftime(timebuff,16,"%T",localtime(&now)); LCD_printXY(timebuff,14,2); }