Shop OBEX P1 Docs P2 Docs Learn Events
Asm code for Fram? — Parallax Forums

Asm code for Fram?

kenmackenmac Posts: 96
edited 2009-01-02 09:46 in Propeller 1
Hi folks,
Has anyone done some simple ASM code for the Fram chip?
I am using a FM24C64 and can control it OK using the i2c Spin code.
However, I need to minimise the overall writing time, by eliminating the Spin time overheads, thus the need for ASM code.
I have looked at the SdspiFemto.spin, which has ASM coding for i2c and SPI, but it seems overly complex for a Fram.

kenmac

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8

Comments

  • AleAle Posts: 2,363
    edited 2008-12-30 11:54
    You can use the code in Chip's bootloader, it is assembler. I think you can strip what is spi and just use the i2c part.
  • kenmackenmac Posts: 96
    edited 2008-12-31 08:17
    OK, it seems that I will need to adapt the code in sdspiFemto.spin.
    I need some help in understanding the description of operation contained in the file.
    The following is an extract of same:

    '' This portion is normally run only once during initialization and the driver remains
    '' resident in a cog.  These routines can be used completely independently of the rest
    '' of the Propeller OS.  The start routine here expects the address of a 2 long area
    '' to be used for passing information to the I/O routines in the COG.  This area should
    '' be located in an area of memory not expected to be overlaid by data or a program that
    '' might be loaded since the COG routines will be accessing this information after an
    '' operation has completed.
    
    '' This object provides an I2C EEPROM read/write routine that can handle both 100KHz and
    '' 400KHz bus speeds and EEPROM page sizes of 64, 128, or 256 bytes (or no paging/no delay
    '' as with Ramtron serial RAM).  The SPIN interpreter can be started after reading, either
    '' in the same COG used by these routines or in a free COG.  The control information is
    '' passed in a 2 long parameter block whose address is passed to the COG when it is started.
    '' The parameter block is updated when the operation is completed.  Note that these are shown
    '' here as they appear in a long value rather than the order of the bytes in memory.
    
    '' -------------------------------------------------------------------
    '' |   cmd/status   |          I/O pin / device / address            |
    '' -------------------------------------------------------------------
    '' |           byte count           |          HUB address           |
    '' -------------------------------------------------------------------
    
    '' The EEPROM address is in the same format used by other routines with the I/O pin pair
    '' in bits 21..19, the device address in bits 18..16, and the 64K address in bits 15..0.
    '' Note that the I/O pin pair is the number of the SCL pin divided by 2.  The SDA pin is
    '' always the next higher numbered pin.  The command code is in the low order bits of the
    '' high order byte of the first long (see ioCmdMask).  This is always non-zero to indicate
    '' that a command is to be performed by the COG routines.  When the command is finished,
    '' this is set to zero.  The errorFlag bit is set to one if a NAK was read after a write
    '' transfer.  This is the only error reported by these routines.  A read operation and
    '' zero-length writes do involve several write transfers for addressing, but the data
    '' read transfer has no error checking.  When the command is completed, the device address,
    '' byte count, and HUB address are all updated to their values at that time.  For the
    '' verify operation (ioVerifyCmd), an error is reported if the checksum is not zero and
    '' the HUB address field is not incremented.  It may be used for some other checksum
    '' reporting in the future.
    



    It says the control is 2 longs, stored somewhere in Hub memory.
    As I understand from the diagram, the command/status is in the MSB byte of the first Long.
    I don't understand the comments re "I/O pin pair" being in bits 19..21, and is the SCL pin divided by 2?
    OK, SCL = pin 28, so that means 14 is the I/O pair??? How does that relate to the bits in Pins 19..21?
    The device address is the chip select bits?
    The 64K address bits is the device's memory location?
    Where does the device ident. code appear e.g. an Eeprom/Fram = %1010xxxx ?
    The 2nd Long seems to have the byte count in the MSW and the Hub address in the LSW.
    I assume the Hub address word is the pointer to where the 2 Longs are stored?
    Is the byte count referring to the page size? e.g. 256 bytes requires the 2 bytes
    For a Fram chip, this Word would be zero ?

    That's a few queries to start off.


    Happy New Year to all,
    Ken Mac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-31 14:51
    sdspiFemto.spin should not need any kind of adaptation to work with FRAM. Serial FRAM is intentionally designed to be a "drop-in" replacement for EEPROM with the significant difference that there's no delay needed to allow for the write cycle to complete. sdspiFemto.spin doesn't add any delays and requires the caller to do that (or to test for a response from the EEPROM indicating that the write has completed).

    The address of the 2 long control block is passed to the assembly routines when they're started in their own cog. The high order byte of the first long is the operation and status code. It should be the last thing set by the user since the assembly cog is looking there for something to do and will immediately fetch and decode the control block when the command bits are non-zero. The other 3 bytes of that long contain the EEPROM / FRAM starting address to be used.

    It's possible to attach up to 512K bytes of serial memory to every even/odd pair of I/O pins for a total of 8MB of storage. These routines handle the EEPROM address that way and derive the I/O pin numbers and device select code from the high order bits of that 8MB address. The "I/O pin pair" bits are bits 19..22 and represent I/O pins 0/1, 2/3, 4/5, 6/7, ... , 30/31. Bits 16..18 are used to construct the device select code since there are 8 possible EEPROMs on any one I2C bus. Bits 0..15 are used as the address for the EEPROM. For EEPROMs less than 64K, the high order bits are ignored. For EEPROMs larger than 64K, multiple device select codes are used.

    The hub address in the 2nd long is the address where the data transfer is to be made (read or write). The byte count is the number of bytes to be transferred. For reads, the data cannot span two separate devices. It has to reside completely within one device (64K or less). For writes, the data has to fit within a single "page" which is defined by the device. Usually this is 64, 128, or 256 bytes depending on the device.

    These routines can also handle non-memory I2C devices. In that case, the entire device select code and 0, 1, or 2 bytes of control information are provided in the 24 bit "EEPROM address" field as described in the comments.

    These routines also handle low level SPI operations using additional operation codes. These are intended specifically for SD cards. You can ignore them if you want.
    Look at the various Spin interface routines to see how the commands are constructed. These mostly start with a wait for completion of any in-process operation, start a new operation, then wait for completion of that.

    Post Edited (Mike Green) : 12/31/2008 3:01:01 PM GMT
  • kenmackenmac Posts: 96
    edited 2009-01-01 00:43
    Thanks Mike.
    So the I/O pair bits are actually 22..19, not 21..19 as described?
    That makes more sense - I couldn't see how the number 15 could be represented by three bits.

    OK, I don't need to know how the ASM code works if it can work "as is " for a Fram chip.
    What I do need to understand now is the correct method of using the Spin parts to control it all.
    So, could you please give an example of implementing the following:

    Write one byte to a Fram at location $1F40, the chip address = %001, pin pair = 28/29

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-01 16:51
    OBJ i2c : "sdspiFemto"
    
    VAR
       long controlBlock
       byte dataByte
    
    PUB test
       i2c.start(controlBlock)
       if i2c.writeEEPROM((28 << 18) | (%001 << 16) | $1F40, @dataByte, 1)
          ' an error occurred, perhaps the EEPROM or FRAM is missing
       else
          ' success
    
    


    The left shift of 18 takes into account that the even "pair" number starts at bit 19.
  • kenmackenmac Posts: 96
    edited 2009-01-02 02:01
    Thanks Mike,
    Initially I was a bit confused by the "28<<18", (I thought it should be <<19 ) but eventually I realised it was just performing the required "SCL/2" function, and being the "even" number, the lsb will always be 0, and thus won't affect the msb of the chip select number(bit18) if it is set.
    Anyway, I tested it and it works OK, so I'll work from there.

    Questions -
    What is the write speed used there?
    Can it be set up to run at Prop. clock speed? (Fram can read/write at clock speed )

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-02 05:36
    FRAM can write at clock speed, but the I2C bus is limited in clock speed. Slow mode is 100KHz. Fast mode is 400KHz. Super fast mode is 1MHz. The sdspiFemto routines can manage at best 400KHz. Some EEPROMs don't work well with these routines at 400KHz, so the normal speed using the Spin calls is 100KHz. There's a bit in the command byte that specifies which speed to be used. Look at the comments and Spin routines. It should be possible to do I2C at 1MHz, but you'd need to write your own special purpose routines. sdspiFemto makes some sacrifices in the interest of generality and would need to be rewritten completely from the ground up to get better speed.

    SPI FRAMs can run at clocks up to 20MHz. It's a real challenge to get the Propeller to do SPI at anywhere near that speed.

    Post Edited (Mike Green) : 1/2/2009 5:42:05 AM GMT
  • kenmackenmac Posts: 96
    edited 2009-01-02 09:46
    Thanks Mike,
    I have the particular Fram's datasheet with the info on the required protocol, so I might have a go at some "bit banging" to control the Fram.
    It won't be immediately tho, there are some higher priority projects beckoning.

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
Sign In or Register to comment.