Shop OBEX P1 Docs P2 Docs Learn Events
Need Help reading form EEPROM — Parallax Forums

Need Help reading form EEPROM

Ryan RaffertyRyan Rafferty Posts: 13
edited 2010-07-20 13:47 in Propeller 1
Let me start by saying that I am VERY new to Propeller and Spin. I am having a problem and I have searched the forums to no avail.

I have a spin application running on my Propeller that is launching 6 cogs to each do the same thing, only with different pins.

Here is a bit of my code that I will explain.
OBJ
  BS2 : "BS2_Functions"
  ser : "TRXEngineModified"

PUB Main
  cognew(StartScan(1),@cogSpace1)
  cognew(StartScan(2),@cogSpace2)
  cognew(StartScan(3),@cogSpace3)
  cognew(StartScan(4),@cogSpace4)
  cognew(StartScan(5),@cogSpace5)
  cognew(StartScan(6),@cogSpace6)
 
PUB StartScan(chan) | rbyte, txPin, rxPin, i, sAdd, eAdd
  txPin := (rxPin := (chan * 2) - 2) + 1                         'set the transmit and receive pins based on the channel we are monitoring
  repeat
    rbyte := ser.receiveCharacter(19200, rxPin)             'This section is working fine...FROM HERE...
    pause(200)
    if rbyte == 77
      ser.transmitString(string("M?:009A",13,10,13,10), 19200, txPin)
    elseif rbyte == 65
      ser.transmitString(string("WR:",13,10),19200, txPin)
    elseif rbyte == 76                                                   'This section is working fine...TO HERE
      eAdd := (sAdd := (chan - 1) * 150) + 130               'Set the beginning and ending address to read from the EEPROM
      repeat i from sAdd to eAdd
        ser.transmitCharacter(BS2.Read_HighMem(i, 1), 19200, txPin)   'This is the part I am having a problem with.  See EXPLANATION BELOW
      sAdd~
      eAdd~
      i~
      
    rbyte~





EXPLANATION
So, if I run this app, it works great. No problem at all as long as I only request data from 1 of the cogs. As soon as I request data from a second cog (Does not even have to be simultaneously) it does not read the EEPROM correctly. I reboot the Propeller and it works fine again, until I try to have another cog read from the EEPROM.

Can someone point me in the right direction. Keep in mind I have no experience with Spin. I have this project running flawlessly on 6 Basic Stamp 2e chips, but I want to consolidate to a single Propeller running 6 cogs.

BTW, if I omit reading from the EEPROM to get the next character, and instead use a predetermined character, the program runs without a hitch. However, I need to be able to pull this data from the EEPROM and send it out a pin via serial communicaitons.

Another possibility would be to read it once on bootup and store the data in a variable, but it is 129 bytes of data per channel and I don't know how to go about that.

Thanks in advance for any help you can give me.

Ryan

Comments

  • Gerry KeelyGerry Keely Posts: 75
    edited 2010-07-18 11:27
    Hi

    I'm not a spin expert but you appear to be trying to access the one eeprom from six cogs(??).

    If so this·can be a problem··as all cogs would be trying to access the eeprom simultaneoulsy and also·input/output pins are OR'ed together. If one cog leaves a pin in a high state it cannot be set low by another( ie 1 or 0 =1).

    Regards

    Gerry
  • Mike GreenMike Green Posts: 23,101
    edited 2010-07-18 14:38
    Gerry is right. You're trying to read from the EEPROM potentially simultaneously from 6 different cogs and there's only one EEPROM, only one I2C bus.

    Your idea of reading the table from EEPROM into a variable (or set of variables) is a good idea. You could easily have a 6 x 129 byte array (774 bytes total) since the Propeller has more than enough memory for your project. You'd access the array using the channel number and index like "table[noparse][[/noparse] chan*129 + i ]" and you'd just declare the array as "VAR byte table[noparse][[/noparse] 6 * 129 ]".

    Note that it's impossible to tell what you're trying to accomplish from your program fragment. If this data table is fixed, you could simply define it in a DAT section like:
    DAT
    table   byte   1, 2, 3, 4, 5, 6 ....
              byte   11, 12, 13, 14, 15, 16 ...
    


    and so on for a total of 774 values.
  • KyeKye Posts: 2,200
    edited 2010-07-18 15:00
    Here Ya go. It also includes locking support for multi cog acess.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Ryan RaffertyRyan Rafferty Posts: 13
    edited 2010-07-19 05:02
    Gerry and Mike, Thanks for your help with this. I understand the concern of simultaneous access to the EEPROM, but the host system that sends the requests for data will only send requests to one of the six cogs at a time. Then it will wait for the full response before requesting data from another cogs. So it wouldn't be accessing it simultaneously.

    Gerry, I didn't know that if a pin is set high by one cog, it cannot be set low by another. That's good information for me moving forward. Thank you for that.

    Mike, I like your idea of using the byte array. I am used to Visual Basic and was getting hung up on the table[noparse][[/noparse]1..6] but then realized that I can't hold an entire string in each element of the array. Since I can't have a two dimensional array (matrix) I thought that method wouldn't work. Your suggestion of table[noparse][[/noparse] chan*129 + i ] is a great idea. I will try that next and let you know how it works out. The data table is not fixed, but very rarely changes. If I could read it from the EEPROM on bootup and store it in the variables, that would be great.

    Kye, I have just downloaded your code and it looks great. BTW, I really like the simplicity of the TRXEngine. Thank you for your contributions.

    I really appreciate all the help.

    Thanks,
    Ryan
  • Ryan RaffertyRyan Rafferty Posts: 13
    edited 2010-07-19 15:58
    Gerry, You said that if a pin is left high by one cog, it cannot be brought low by another.

    If a pin is left low when a cog is finished with it, can another cog then use it switching it low and high and then leaving it low again ?

    I have a serial LCD Display that I can only send data to form one cog. If I try to output to it from another cog, it doesn't display anything. If I got back and trigger an output to it form the original cog, it displays fine. Could that be my problem there ?

    Thanks,
    Ryan

    PS. Still working on the EEPROM read into memory. I will post once I resolve that and let you know what worked best.
  • Ryan RaffertyRyan Rafferty Posts: 13
    edited 2010-07-19 17:10
    OK, so I used Kye's function (I2C_ROMEngine.readPage) to load the data into the RAM from the EEPROM on bootup and that worked great. Rather than looping byte by byte through 774 elements of an array, I just reference the RAM using Kye's TRXEngine.transmitString function and pointing to the address where I loaded the data.

    Now I just need to clean up the function that writes to the EEPROM for updates.

    Thank you so much for all of your help.

    Ryan
  • Gerry KeelyGerry Keely Posts: 75
    edited 2010-07-19 17:31
    Hi ryan



    If you look at page 26 of the Propeller Manual it explains how the I/O resources are shared by the cogs, better than I could explain it.

    you can get a copy of the manual here

    http://www.parallax.com/ProductInfo/Microcontrollers/PropellerGeneralInformation/PropellerMediaPage/tabid/832/Default.aspx



    Gerry
  • Ryan RaffertyRyan Rafferty Posts: 13
    edited 2010-07-19 22:45
    Kye, is there a way to implement a timeout in your TRXEngine receiveCharacter function. Right now it waits indefinitely which works great for my application, I just have another idea that would be nice to have a timeout if no additional data comes in after X number of milliseconds.

    Thanks for your help.
    Ryan
  • KyeKye Posts: 2,200
    edited 2010-07-19 23:14
    First, attached is the new updated version of the TRX engine I'll release it soon.

    Now, for timeout just do this.
    PUB receiveCharacterTimeout(recieverPin, baudRate, timeoutInMilliseconds) | snapshot
     
      recieverPin := ((recieverPin <# 31) #> 0)
      snapshot := cnt 
     
      repeat until(timeoutInMilliseconds < (cnt - snapshot)) 
     
        ifnot(ina[noparse][[/noparse]recieverPin])
          reutn receiveCharacter(recieverPin, baudRate)
     
      return 0  
    

    The code my be wrong but the idea is to just keep checking until the I/O line goes low as fast as possible until the time is up.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Ryan RaffertyRyan Rafferty Posts: 13
    edited 2010-07-20 13:47
    That makes sense. I will give it a shot and let you know how it goes.

    Thanks,
    Ryan
Sign In or Register to comment.