Help with using I2C EEPROM Functions with Catalina C
AndreP
Posts: 5
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:
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:
Below is my modified version of the "test_spi.c" example source code:
Thanks in advance for anything help that can be provided!
AndreP
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
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:
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:
Ross.
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
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.
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.
The datasheet for the P1 says this...
...I'd be surprised if your XTAL was running at 40MHz. It's more likely running at 40/3MHz