Shop OBEX P1 Docs P2 Docs Learn Events
Help with using I2C EEPROM Functions with Catalina C — Parallax Forums

Help with using I2C EEPROM Functions with Catalina C

AndrePAndreP Posts: 5
edited 2013-01-08 02:19 in Propeller 1
Hello,


My overall goal is to have my Propeller talk to the HMC6352 digital compass with the I2C plugin, however I am having problems getting the example code provided in the Catalina demo folder to work properly. Before using the digital compass, I am first trying to get the "test_spi.c" Catalina C program to function with the 24LC256 EEPROM on I/Os that are not 28 for SCL and 29 for SDA. With an adjustment (for some reason I have set the clock speed in 0x00000000 in order to get certain functions to work properly), I am able to get the "test_spi.c" to work without changing the SCL from 28, but no other pin appears to work. My physical setup is custom and is similar to that shown on page 17 of the "Web-PropellerManual-v1.2", though The 24LC256 that I am performing the testing with is connected to pins 3 and 4 (SCL and SDA, respectively) of my Propeller. Both pins have pull-up resistors.


I am fairly certain my issue has something to do with the fact that I have to set the clock speed in order to get certain functions working and the following quote found in the beginning of the "catalina_spi.h" include file:

The pins used for the boot EEPROM I2C bus (at least on Parallax's Demo Board) do not have a pullup on SCL. This requires that SCL be driven both high and low. If the bus used is on pins 28 and 29, SCL is actively driven at all times.


I don't know when and how the SCL should "be driven both how and low", but adding the pull-up resistor on the SCL at least causes the SCL to go high and low whenever the Propeller tries to talk to the EEPROM, as I have seen with my oscilloscope (though, this action might be wrong seeing as the data sheet of the EEPROM only calls for a pull-up on the SDA). What I haven't really done was change the plugin's configurations using the command codes found in "catalina_spi.h". Not sure hot to even use them (spi_setControl?), and I have read through the comments in "catalina_spi.h" and the section on plugin requests from pages 50 to 52 of the "Catalina - a free C compiler..." manual.


Below is my CUSTOM_def.inc file I have changed:
' For the 40MHz Clock
CLOCKMODE = XTAL2                 ' (QuickStart)
XTALFREQ  = 40_000_000           ' (QuickStart)
CLOCKFREQ = 40_000_000          ' (QuickStart) Nominal clock frequency
                                ' (required by some drivers)


Below is my modified version of the "test_spi.c" example source code:
#include <Propeller.h>
#include <catalina_spi.h>
#include <catalina_plugin.h>
#include <stdio.h>
#include "BitManipulation.h"    // contains the 
#define Pin_LED0 0
#define Pin_PUSHBUTTON 1
#define Pin_SCL 3
#define Pin_SDA 4 // the SDA pin must be the pin after the SCL order


// Test program definitions
#define BUFFER_SIZE 256
#define BUFFER2_SIZE 32
#define SCL_PIN Pin_SCL


[HR][/HR]


int main()
{
    int i;
    int addr;
    int sect;
    unsigned int control;
    request_t *rqst;


    char buffer[BUFFER_SIZE];
    char buffer2[BUFFER2_SIZE];


    Clock_setFREQUENCY();


    printf("SPI/I2C Test Program!\n\n");
    print_plugin_names();


    printf("\nEnter BOOT Address\n(or -1 to skip EEPROM boot):");
    addr = get_int();


    if (addr >= 0) {


        pause("\nPress a key to boot from EEPROM ...");


        // read the first BUFFER_SIZE bytes of EEPROM 
        printf("\n\nBooting ...\n\n");
        spi_bootEEPROM(EEPROM_ADDR(SCL_PIN, addr));
        // if we get here we failed to boot!
        printf("\n\n... failed!\n\n");
    }
   
    control = spi_getControl(0);
    printf("\nHere is the control: %u\n", control);
    control = spi_getControl(1);
    printf("\nHere is the control: %u\n", control);
    control = spi_getControl(2);
    printf("\nHere is the control: %u\n", control);
    control = spi_getControl(3);
    printf("\nHere is the control: %u\n", control);
    rqst = REQUEST_BLOCK(_locate_plugin(LMM_SPI));
    printf("\nrequest: %x\tcontrol: %x\n", rqst->request, rqst->response);


    printf("\nEnter EEPROM Address\n(or -1 to skip EEPROM read/write test):");
    addr = get_int();
    if (Pin_SCL == 3)
    {addr |= 0xA0 << 24;}
    printf("\naddr: %x", addr);


    while (TRUE) {
        pause("\n Press to check for EEPROM presence ... ");
        if (spi_checkPresence(EEPROM_ADDR(SCL_PIN, addr)))
        {printf("EEPROM is present\n");}
        else
        {printf("EEPROM is not present\n");}


        pause("\nPress a key to read EEPROM ...");


        // read the first BUFFER_SIZE bytes of EEPROM 
        printf("\n\nReading ...\n\n");
        spi_readEEPROM(EEPROM_ADDR(SCL_PIN, addr), buffer, BUFFER_SIZE);


        pause("\nattempting to boot from EEPROM ...");
        spi_setControl(0, ioBootCmd);
        printf("\nrequest: %x\tcontrol: %x\n", rqst->request, rqst->response);


        // display them
        dump_buffer(buffer, BUFFER_SIZE);


        pause("\nPress a key to write EEPROM ...");


        // initialize the buffer to a set of known values
        for (i = 0; i < BUFFER2_SIZE; i++) {
            buffer2[i] = 0xFF;
        }


        // write the first BUFFER_SIZE bytes of EEPROM
        printf("\n\nWriting ...\n\n");
        spi_writeEEPROM(EEPROM_ADDR(SCL_PIN, addr), buffer2, BUFFER2_SIZE);
        printf("\nrequest: %x\tcontrol: %x\n", rqst->request, rqst->response);


        // wait for the write to complete !IMPORTANT!
        spi_writeWait(EEPROM_ADDR(SCL_PIN, addr));




        // re-initialize the buffer
        for (i = 0; i < BUFFER_SIZE; i++) {
            buffer[i] = 0;
        }


        // read the first BUFFER_SIZE bytes of EEPROM
        //pause("Before we continue, let's pause\n\n");
        printf("Reading ...\n\n");
        spi_readEEPROM(EEPROM_ADDR(SCL_PIN, addr), buffer, BUFFER_SIZE);
        printf("\nrequest: %x\tcontrol: %x\n", rqst->request, rqst->response);


        // display them
        dump_buffer(buffer, BUFFER_SIZE);
    }


    // alert user the main program has finished
    Led_flash_programEND(Pin_LED0);
    printf("\nfinish");


    // prevent the propeller from rebooting
    while (TRUE) continue;


    return 0;
}

Thanks in advance for anything help that can be provided!
AndreP

Comments

  • RossHRossH Posts: 5,462
    edited 2013-01-06 18:36
    AndreP wrote: »
    Thanks in advance for anything help that can be provided!
    AndreP

    Hi AndreP,

    Catalina's sd/spi plugin is a direct steal of Mike Green's original - I think he would be best placed to go into details of how to drive an EEPROM on pins other than 28&29 - I've never tried it, since all my boards use those pins.

    As to the clock settings, you need to use the correct clock mode and PLL multiplier combination - the values will vary depending on your actual crystal frequency. My understanding is that you should not specify a 40Mhz crystal with clock mode XTAL2 - this is out of Propeller's frequency ranges (see the table on page 29 of v1.2 of the Propeller Manual)

    Most people use have a 5Mhz crystal. so if you want a 40Mhz propeller clock with one of these crystals your PLL multiplier should be 8x, so your Custom_DEF.inc file would look something like this:
    ' For a 40MHz Clock:
    CLOCKMODE = XTAL2 + PLL8X
    XTALFREQ  = 5_000_000
    CLOCKFREQ = 40_000_000          ' Nominal clock frequency 
                                    ' (required by some drivers)
    

    If you really do have a 40Mhz crystal and you want a 40Mhz propeller clock, I think your clock mode should be XTAL3 and your PLL multiplier should be 1x, so your Custom_DEF.inc file would look something like:
    ' For a 40MHz Clock:
    CLOCKMODE = XTAL3 + PLL1X
    XTALFREQ  = 40_000_000
    CLOCKFREQ = 40_000_000          ' Nominal clock frequency 
                                    ' (required by some drivers)
    

    Ross.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-01-06 19:21
    I presume you really do mean test_i2c and not test_spi ?
  • AndrePAndreP Posts: 5
    edited 2013-01-08 00:24
    @RossH:

    I actually am using a 40MHz crystal with my propeller, so thanks for the correction with the CLOCKMODE setting. What about the fact that I have to manually change the frequency in order to get my Propeller to function properly? Originally, I was using a 5MHz crystal with the PLL16X multiplier (i.e. the default settings). Even under the normal conditions, I still have to set the frequency within my source code.

    And, well done with the C compiler!

    @Cluso99:

    Nope. That's the name of the source file that contains the code used to test both the i2c (specifically for the eeprom) and the spi (specifically for SD cards).

    AndreP
  • RossHRossH Posts: 5,462
    edited 2013-01-08 00:37
    AndreP wrote: »
    I actually am using a 40MHz crystal with my propeller, so thanks for the correction with the CLOCKMODE setting. What about the fact that I have to manually change the frequency in order to get my Propeller to function properly? Originally, I was using a 5MHz crystal with the PLL16X multiplier (i.e. the default settings). Even under the normal conditions, I still have to set the frequency within my source code.

    And, well done with the C compiler!
    AndreP

    Thanks, AndreP!

    When you set the clockmode to 0x00000000 you are effectively just setting it to RCFAST - i.e. around 12Mhz. In this mode you are not actually using the external crystal at all. If your program works at that speed but fails at a higher speed, then it may indicate your circuit has a hardware/timing problem.

    If possible, try switching back to using a 5Mh crystal clock but set clockmode XTAL1 + PLL1X (5Mhz), then XTAL1 + PLL2X (10Mhz) etc. Your program should work at these lower speeds, but may fail at a higher speed (i.e. PLL4X or PLL8X). But at least that would tell you something!

    Ross.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-01-08 02:16
    The Prop cannot (or rather should not) be used with an external xtal >~15MHz IIRC. In fact I found that ~14.3MHz seems to be the limit on the QFP while 15MHz seems to be the limit on the DIP40 package. This was to overclock, but I understand that the limitation is actually the PLL circuitry. This is because in xtal mode, it is first multiplied by 16 before being divided back down
    to give the resulting xtal factor.
    You can however input a clock at 40MHz or even 80MHz provided you set for external clocking and not xtal mode - I understand this bypasses the PLL.
  • Brian FairchildBrian Fairchild Posts: 549
    edited 2013-01-08 02:19
    AndreP wrote: »
    I actually am using a 40MHz crystal with my propeller,...

    The datasheet for the P1 says this...
    This graph shows the current consumption of the crystal driver over a range of crystal frequencies and crystal settings, all data points above 25 MHz were obtained by using a resonator since the driver does not perform 3rd harmonic overtone driving required for crystals over 25 MHz.

    ...I'd be surprised if your XTAL was running at 40MHz. It's more likely running at 40/3MHz
Sign In or Register to comment.