Shop OBEX P1 Docs P2 Docs Learn Events
XMMC and i2c — Parallax Forums

XMMC and i2c

blindstarblindstar Posts: 12
edited 2012-10-30 10:47 in Propeller 1
I am having a good time playing with the Propeller GCC beta. I’ve been trying to make use of the XMMC memory model. I am using a C3 board and SimpleIDE 0-8-5 for OSX.

The cog_c_toggle demo works if I set the SimpleIDE memory model to XMMC and the board type C3-SDXMMC or C3F-SDXMMC. However if I take a working C program (compiled for LMM) that is reading a DS1307 RTC using the i2c buss and compile it using the same parameters it hangs on the “i2c_open();” Should the i2c functions work in XMMC?

Thanks.

Mark

Comments

  • ersmithersmith Posts: 6,054
    edited 2012-10-28 15:36
    blindstar wrote: »
    I am having a good time playing with the Propeller GCC beta. I’ve been trying to make use of the XMMC memory model. I am using a C3 board and SimpleIDE 0-8-5 for OSX.

    The cog_c_toggle demo works if I set the SimpleIDE memory model to XMMC and the board type C3-SDXMMC or C3F-SDXMMC. However if I take a working C program (compiled for LMM) that is reading a DS1307 RTC using the i2c buss and compile it using the same parameters it hangs on the “i2c_open();” Should the i2c functions work in XMMC?

    If you're using the SD to store XMMC memory then the XMM driver will be accessing the i2c bus. This is could be a problem. I'm not familiar enough with the internal workings of the XMM drivers and i2c code to be able to say whether there is any way to make the combination work.

    Will your code fit in hub memory in CMM mode?

    Eric
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-28 19:35
    blindstar wrote: »
    I am having a good time playing with the Propeller GCC beta. I’ve been trying to make use of the XMMC memory model. I am using a C3 board and SimpleIDE 0-8-5 for OSX.

    The cog_c_toggle demo works if I set the SimpleIDE memory model to XMMC and the board type C3-SDXMMC or C3F-SDXMMC. However if I take a working C program (compiled for LMM) that is reading a DS1307 RTC using the i2c buss and compile it using the same parameters it hangs on the “i2c_open();” Should the i2c functions work in XMMC?

    Thanks.

    Mark
    Could you post your code?

    When you say you're using i2c_open, do you mean i2cOpen? I'm not familiar with i2c_open.

    Thanks,
    David
  • blindstarblindstar Posts: 12
    edited 2012-10-28 20:54
    I cobbled the following code from various examples. It seems to work until I try it under XMMC. I havent touched C in a long time so I'm probably doing something stupid.

    Thanks for your help.
    /**
     * @file t2.c
     * Test inteface to DS1307 RTC
     * This is the main t2 program start point.
     */
      
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <time.h>
    #include "DS1307.h"
    #include <propeller.h>
    
    
    /* interface routines to hook DS1307 into system time routines */    
    void gettime(struct timeval *);
    void settime(struct timeval *);  
    
    
    int main(void)
    {    
        time_t tim;                    
        int i;
       printf("start test program\n");  
    /* set globals to point to my time routines */    
         _rtc_gettime = gettime;
         _rtc_settime = settime;
         printf("system globals reasigned to DS1307 access routines\n");
    /* start clock */
        startRTC();
        printf("RTC started\n");           
    /* read the time */    
        for (;;)
       {       
            tim=time(NULL);
            struct tm *now=localtime(&tim);
            printf("Date is %d/%02d/%02d   ",now->tm_mon+1, now->tm_mday,now->tm_year+1900);
            printf("Time is %02d:%02d    ", now->tm_hour, now->tm_min);
            printf("Seconds since ... %d\n",mktime(now));    
            usleep(200000);       
        }
        return;
    }
    
    //////////////////////////////////////////////////////////////////////////////// 
    ///                               DS1307.C                                   /// 
    ///                     Driver for Real Time Clock                           /// 
    ///                                                                          ///  
    ////////////////////////////////////////////////////////////////////////////////  
    #include "DS1307.h"
    #include <stdio.h>
    #include <propeller.h>
    #include <string.h>
    #include <sys/rtc.h>
    
    
    char bin2bcd(char binary_value); 
    char bcd2bin(char bcd_value);
    
    
    /* i2c buss stuff */
        I2C *bus;
        uint8_t  buffer[DS1307_DATE_TIME_BYTE_COUNT];
        
    /* DS1307 stuff */
        struct tm td; 
        struct timeval tv;
         
    /*start up DS1307*/
    void 
    startRTC()
    {
        printf("before i2c_open\n");
        bus = i2c_open();
        printf("%i returned form i2c_open\n",bus);
        return;
    }
    
    
    /* read the ds1307 data registers */
    void 
    RTCread(I2C *bus, uint8_t *bptr)
    { 
        /* select the data registers */
        if (i2cWrite(bus, DS1307_I2C_WRITE_ADDR, 0, 1, TRUE) != 0)
            printf("Write failed\n");        
        usleep(2000000);   
        /* read the data registers */
        if (i2cRead(bus, DS1307_I2C_READ_ADDR, &bptr[0], DS1307_DATE_TIME_BYTE_COUNT, TRUE) != 0)
            printf("Read failed\n");    
        return;
    }
    /* over ride sysem default for reading the time, load tm structure structure */
    void
    gettime(struct timeval *tv)
    {
        /* select the data registers */
        if (i2cWrite(bus, DS1307_I2C_WRITE_ADDR, 0, 1, TRUE) != 0)
            printf("Write failed\n");        
        usleep(2000000);   
        /* read the data registers */
        if (i2cRead(bus, DS1307_I2C_READ_ADDR, &buffer[0], DS1307_DATE_TIME_BYTE_COUNT, TRUE) != 0)
            printf("Read failed\n");  
        td.tm_sec = bcd2bin(buffer[DS1307_SECONDS_REG]);
        td.tm_min = bcd2bin(buffer[DS1307_MINUTES_REG]);
        td.tm_hour = bcd2bin(buffer[DS1307_HOURS_REG]);
        td.tm_wday = bcd2bin(buffer[DS1307_DAY_OF_WEEK_REG]);
        td.tm_mday = bcd2bin(buffer[DS1307_DATE_REG]);
        td.tm_mon = bcd2bin(buffer[DS1307_MONTH_REG])-1;
        td.tm_year = bcd2bin(buffer[DS1307_YEAR_REG])+ 100;           
        tv->tv_sec = mktime(&td);    
        return;
    }
    
    
    /* try and open the i2c buss */
    I2C * 
    i2c_open(void)
    {
        I2C *bus;    
        /* open i2c buss */
        printf("about to call i2c_open\n");
        if (!(bus = (I2C *)i2cBootOpen()))         
            printf("error: can't boot open i2c bus\n");
        else 
            printf("i2c buss opened\n"); 
        return bus;
    }
    
    
    /* sleep */
    void 
    sleep(seconds)
    {
         int time,i;
         time = CNT;
         for (i=0;i<seconds;i++)
         {
            time += CLKFREQ;
            waitcnt(time);
         }
         return;
    } 
    
    
    /* convert binary to binary coded decimal */
    char 
    bin2bcd(char binary_value) 
    { 
      char temp; 
      char retval; 
      temp = binary_value; 
      retval = 0; 
      while(1) 
      { 
    /* Get the tens digit by doing multiple subtraction */
    /* of 10 from the binary value                      */ 
        if(temp >= 10) 
        { 
          temp -= 10; 
          retval += 0x10; 
        } 
        else // Get the ones digit by adding the remainder. 
        { 
          retval += temp; 
          break; 
        } 
      } 
      return(retval); 
    } 
    /* conver binary coded decimal to binary */
    /* Input range - 00 to 99                */
    char 
    bcd2bin(char bcd_value) 
    { 
      char temp; 
      temp = bcd_value; 
    /* Shifting upper digit right by 1 is same as multiplying by 8 */
      temp >>= 1; 
    /* Isolate the bits for the upper digit */
      temp &= 0x78; 
    /* Now return: (Tens * 8) + (Tens * 2) + Ones */
      return(temp + (temp >> 2) + (bcd_value & 0x0f)); 
    } 
    /* not implemented */
    void
    settime(struct timeval *tv)
    {
        tv->tv_sec = 0;
        tv->tv_usec = 0;
        return;
    }
    
    
    // ds1307.h -- This is the include file that goes with ds1307.c 
    
    
    #include <i2c.h>
    #include <sys/rtc.h>
    
    
    // i2c addresses 
    #define DS1307_I2C_WRITE_ADDR 0xd0 
    #define DS1307_I2C_READ_ADDR  0xd1 
    
    
    // DS1307 register offsets 
    #define DS1307_SECONDS_REG  0 
    #define DS1307_MINUTES_REG  1 
    #define DS1307_HOURS_REG    2 
    #define DS1307_DAY_OF_WEEK_REG 3 
    #define DS1307_DATE_REG     4 
    #define DS1307_MONTH_REG    5 
    #define DS1307_YEAR_REG     6 
    #define DS1307_CONTROL_REG  7 
    
    
    
    
    #define DS1307_DATE_TIME_BYTE_COUNT 7 // Includes bytes 0-6 
    
    
    #define DS1307_NVRAM_START_ADDR 8 
    
    
    // We disable the SQWV output, because it uses 
    // a lot of battery current when it's enabled. 
    // Disable it by setting Out = Open Collector. 
    
    
    #define DS1307_CONTROL_REG_INIT_VALUE 0x80 
    
    
    // 32.768 KHz output 
    //#define DS1307_CONTROL_REG_INIT_VALUE 0x13 
    
    
    #define TRUE    1
    #define FALSE    0
    
    
    /*DS1307 fuctions */
    //void RTCread(I2C *, uint8_t *);
    I2C * i2c_open(void);
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2012-10-29 10:11
    blindstar wrote: »
    I cobbled the following code from various examples. It seems to work until I try it under XMMC. ...

    The problem with XMMC running from EEPROM is that it uses I2C for fetching code. This can result in a conflict with other devices that use I2C.

    One way around this problem is to prepend all of the I2C functions with: HUBTEXT

    I.E:

    HUBTEXT void RTCread(I2C *bus, uint8_t *bptr)
    {
    ...
    }

    HUBTEXT will cause any such function to live in HUB RAM so that the I2C bus is not used for fetching code while the I2C is being accessed.

    The functions RTCread, i2cRead, i2cWrite, and maybe gettime are all candidates for being HUBTEXT.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-29 12:19
    blindstar wrote: »
    I am having a good time playing with the Propeller GCC beta. I’ve been trying to make use of the XMMC memory model. I am using a C3 board and SimpleIDE 0-8-5 for OSX.

    The cog_c_toggle demo works if I set the SimpleIDE memory model to XMMC and the board type C3-SDXMMC or C3F-SDXMMC. However if I take a working C program (compiled for LMM) that is reading a DS1307 RTC using the i2c buss and compile it using the same parameters it hangs on the “i2c_open();” Should the i2c functions work in XMMC?

    Thanks.

    Mark
    I think I'm confused about the problem here. Maybe I'm just not familiar with the SimpleIDE board configuration settings but "C3F" should place code in the SPI flash chip which shouldn't interfere at all with the i2c driver. I don't know how C3F-SDXMMC differs from just C3F. The only reason the cache driver would interfere with your i2c ADC code is if you use the EEPROM flash driver.
  • blindstarblindstar Posts: 12
    edited 2012-10-29 13:04
    when you say you're using i2c_open, do you mean i2copen? I'm not familiar with i2c_open.

    The call that is failing is i2cBootOpen, the i2c_open is my wrapper - sorry.
    One way around this problem is to prepend all of the I2C functions with: HUBTEXT
    This does not seem to change the behavior. I'm wondering if I should open an i2c bus on different pins? I have been using 28/29 with i2CBootOpen.

    Thanks for the comments.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-29 13:26
    blindstar wrote: »
    The call that is failing is i2cBootOpen, the i2c_open is my wrapper - sorry.
    This does not seem to change the behavior. I'm wondering if I should open an i2c bus on different pins? I have been using 28/29 with i2CBootOpen.

    Thanks for the comments.
    You might try using i2cOpen instead of i2cBootOpen using the same pins 28/29. The i2cBootOpen driver actively drives the SCL line for Propeller boards that don't have a pull-up resistor on SCL but it seems all recent Parallax boards and I believe the C3 have that resistor so the standard I2C driver will probably work. I would try this myself but I don't have that RTC chip you're using.
  • jazzedjazzed Posts: 11,803
    edited 2012-10-29 15:22
    Hmm. Not sure how i got the idea that xmmc was being run from eeprom.
  • blindstarblindstar Posts: 12
    edited 2012-10-30 10:07
    David Betz wrote: »
    You might try using i2cOpen instead of i2cBootOpen using the same pins 28/29. The i2cBootOpen driver actively drives the SCL line for Propeller boards that don't have a pull-up resistor on SCL but it seems all recent Parallax boards and I believe the C3 have that resistor so the standard I2C driver will probably work. I would try this myself but I don't have that RTC chip you're using.

    Below is a very simple attempt to open the i2c buss on pins 28/29. I got rid of all the DS1307 stuff. All it does is a i2cOpen. It works fine complied with LMM, but it never returns from the i2cOpen if I use XMMC. I get the same result using i2cBootOpen.

    What should the last parameter of the i2cOpen be? I found an example that used 400000 so that is what I tried. Is there something that I should be reading to get more background?
    #include <stdio.h>
    #include <i2c.h>
    
    /* i2c buss stuff */
        I2C *bus;
        I2C_COGDRIVER cdriver;
        
    void 
    openbus()
    {
        I2C_COGDRIVER *CD;
        CD = &cdriver;
        printf("before i2copen\n");   
    /* open i2c buss */
        if(!(bus = (I2C *)i2cOpen(CD, 28, 29, 400000)))         
            printf("error: can't open i2c bus\n");
        else 
            printf("i2c buss opened\n"); 
        return;
    }    
       
    int main(void)
    {    
        printf("start XMMC test program\n");  
    /* open i2c buss */
        openbus();          
        return;
    }
    
    Thanks for trying to help me out.

    mark
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-30 10:47
    blindstar wrote: »
    What should the last parameter of the i2cOpen be? I found an example that used 400000 so that is what I tried. Is there something that I should be reading to get more background?
    It's supposed to be the speed of the bus. So 400000 would be 400 khz. The driver attempts to pace the data to match that speed.
Sign In or Register to comment.