Wednesday, 3 July 2013

GPi gz_test does not test SPI actually!

So I started testing EEPROM 25LC256, with the following function call.

# *** EEPROM ***
fteeprom.TestEeporm25Lc256v01(spiChannelNumber = 0, spiChipEnableNumber = 1, startAddress = 0x4100, testDataByte = 0x55)

However, RPi did not read back the 0x55 written to EEPROM.  So I suspected the SPI cable might be faulty or SPI connection is somewhere broken.

So I fell back to Guzunty Pi and upload and tested gz_test, to make sure JTAG, CLK0, and SPI are still OK.  The test gz_test run OK, but then I found that I made a big mistake - gz_test actually does not need SPI and could still run, because it a a passive frequency divider, it does not SPI talk to RPi.

In other words, gz_test still runs if SPI was faulty.

So I could not use GPi gz_test to test SPI OK or not.

So I went back to do SPI loop test.

.END

# *****************************************************************************
# Module - fteeprom.py
# Description - SPI EEPROM
# *****************************************************************************

# fteeprom.py v2.0 tlfong01 2013jul03

# *****************************************************************************
# Imports
# *****************************************************************************

import time
import spidev

import ftspi
import ftprint

# *****************************************************************************
# Constants and variables
# *****************************************************************************

# *****************************************************************************
# Function - TestWriteReadEepormDataByte()
# Version - v1.2 tlfong01 2013may29
# Description - Write 1 data byte then read back
# Sample call - fteeprom.TestWriteReadEepromDataByte(spiChannelNumber = 0,
#               spiChipEnableNumber = 1, startAddress = 0x4100,
#               testDataByte = 0x55)
# Sample output -
# *** Start Test 25LC256 ***
# Write data byte =  0x55
# Read data byte  =  0x55
# *** Stop  Test 25LC256 ***
# *****************************************************************************

def TestEeporm25Lc256v01(spiChannelNumber, spiChipEnableNumber, startAddress, testDataByte): 

    ftprint.PrintDoubleSpaceLine("*** Start Test 25LC256 ***")   

    spiChannel = spidev.SpiDev()  
    spiChannel.open(spiChannelNumber, spiChipEnableNumber)   

    WriteEepromDataByte(spiChannel, startAddress, testDataByte)
    print "Write data byte = ", hex(testDataByte)

    readBackDataByte = ReadEepromDataByte(spiChannel, startAddress)
    print "Read data byte  = ", hex(readBackDataByte)

    ftprint.PrintDoubleSpaceLine("*** Stop  Test 25LC256 ***") 


# *****************************************************************************
# Basic functions
# *****************************************************************************

def WriteEepromDataByte(spiChannel, startAddress, dataByte): # v1.1 tlfong01 2013may21

    EePromCommandWriteLatchEnable    = 0x06
    EepromCommandWrite               = 0x02
    FiveMilliSeconds = 0.005

    startAddressUpper = startAddress >> 8
    startAddressLower = startAddress & 0x00ff

    ftspi.SpiWrite(spiChannel, [EePromCommandWriteLatchEnable])
    time.sleep(FiveMilliSeconds)

    ftspi.SpiWrite(spiChannel, [EepromCommandWrite, startAddressUpper, startAddressLower, dataByte])
    time.sleep(FiveMilliSeconds)

def ReadEepromDataByte(spiChannel, startAddress): # v1.1 tlfong01 2013may21

    EepromCommandRead = 0x03
    FiveMilliSeconds = 0.005
    DummyDataByte = 0x00
    readSpiDataList  = [0x00, 0x00, 0x00, 0x00, 0x00]

    startAddressUpper = startAddress >> 8
    startAddressLower = startAddress & 0x00ff                                          

    readSpiDataList = ftspi.SpiWrite(spiChannel, [EepromCommandRead, startAddressUpper, startAddressLower, DummyDataByte])
    dataByte = readSpiDataList[3]
    return dataByte

def WriteReadEepromDateByte(spiChannel, startAddress, testDataByte): # v1.1 tlfong01 2013may21
    testDataByte = 0x34
    testStartAddress = 0x0411

    WriteEepromDataByte(spiChannel, startAddress, dataByte)
    print "Write data byte = ", hex(testDataByte)

    readBackDataByte = ReadEepromDataByte(spiChannel, startAddress)
    print "Read data byte  = ", hex(readBackDataByte)


# *****************************************************************************
# Old functions
# *****************************************************************************

def TestMcp23S17SpiSlaveSelector01(mcp23S17Address, eepromSubAddress, testStartAddress, testDataByte):

    # *** Set up SPI channel 00 for MCP23S17, channel 01 for EEPROM 25LC256 ***

    SpiChannel0 = 0
    SpiChipEnable0 = 0
    SpiChipEnable1 = 1

    Mcp23s17SubAddress0 = 0

    spiChannel00 = spidev.SpiDev()
    spiChannel00.open(SpiChannel0, SpiChipEnable0)

    spiChannel01 = spidev.SpiDev()
    spiChannel01.open(SpiChannel0, SpiChipEnable1)

    # *** Set up MCP23s17 Port A all out to drive HC137 #1, Port B to drive 2 74HC137 #2 ***

    All8pinOutput = 0x00
    SetupMcp23s17Ports(spiChannel00, Mcp23s17SubAddress0, All8pinOutput, All8pinOutput)

    # *** Select EEPROM 25LC256 ***

    SelectSpiSlave(spiChannel00, Mcp23s17SubAddress0, eepromSubAddress)

    # *** Write Eeprom ***

    WriteEepromDataByte(spiChannel01, startAddress = testStartAddress, dataByte = testDataByte)

    print "Write data byte = ", hex(testDataByte)

    # *** Read Eeprom ***

    readBackDataByte = ReadEepromDataByte(spiChannel01, startAddress = testStartAddress)

    print "Read data byte  = ", hex(readBackDataByte)

    # *** Close SPI channel ***

    spiChannel00.close()
    spiChannel01.close()

def TestMcp23s17MultipleSlaveDevices(mcp23s17SubAddress, eepromSubAddress1, eepromSubAddress2):

    # *** Set up SPI channel 00 for MCP23S17, channel 01 for EEPROM 25LC256 ***

    SpiChannel0 = 0
    SpiChipEnable0 = 0
    SpiChipEnable1 = 1

    Mcp23s17SubAddress0 = 0

    spiChannel00 = spidev.SpiDev()
    spiChannel00.open(SpiChannel0, SpiChipEnable0)

    spiChannel01 = spidev.SpiDev()
    spiChannel01.open(SpiChannel0, SpiChipEnable1)

    # *** Set up MCP23s17 Port A all out to drive HC137 #1, Port B to drive 2 74HC137 #2 ***

    All8pinOutput = 0x00
    SetupMcp23s17Ports(spiChannel00, mcp23s17SubAddress, All8pinOutput, All8pinOutput)

    SelectHC137PortA = 0x20 # Bits 4,5 = HC137 pins 5,6 = 0,1 selects chip
    WriteDataByteMcp23s17(spiChannel00, mcp23s17SubAddress, RegisterAddressArrayMcp23s17, OutputLatchIndex, PortA, SelectHC137PortA)
                       
    PrintEightBitPattern(" SelectHC137PortA = ", SelectHC137PortA)

    print "Now select chip, then hold ..."
    while True:
        pass
 
    # *** Test EEPROM #1 ***

    # *** Select EEPROM 25LC256 #1 ***

    SelectSpiSlave(spiChannel00, mcp23s17SubAddress, eepromSubAddress1)

    # *** Write Eeprom ***

    testDataByte = 0x51
    testStartAddress = 0x0411
    WriteEepromDataByte(spiChannel01, startAddress = testStartAddress, dataByte = testDataByte)
    print "Write data byte = ", hex(testDataByte)

    # *** Read Eeprom ***

    readBackDataByte = ReadEepromDataByte(spiChannel01, startAddress = testStartAddress)
    print "Read data byte  = ", hex(readBackDataByte)

    # *** Test EEPROM #2 ***

    # *** Select EEPROM 25LC256 #2 ***

    SelectSpiSlave(spiChannel00, mcp23s17SubAddress, eepromSubAddress2)

    # *** Write Eeprom ***

    testDataByte = 0x34
    testStartAddress = 0x0411
    WriteEepromDataByte(spiChannel01, startAddress = testStartAddress, dataByte = testDataByte)
    print "Write data byte = ", hex(testDataByte)

    # *** Read Eeprom ***

    readBackDataByte = ReadEepromDataByte(spiChannel01, startAddress = testStartAddress)
    print "Read data byte  = ", hex(readBackDataByte)  

    # *** Close SPI channel ***

    spiChannel00.close()  
    spiChannel01.close()

def Test25Lc256():

    PrintDoubleSpaceLine("*** Start testing 25LC256 ***")

    # *** Set up SPI channel ***
    # import spidev # WiringPi Python wrapper
    # spidev.max_speed_hz = 10000 # seems no effect, clock always 2 MHz !!!
    spiEeprom = spidev.SpiDev()
    # spiEeprom.open(0, 0)

    spiEeprom.open(0, 1)

    # *** 25LC256 instructions ***
    EepromCommandWriteStatusRegister = 0x01
    EepromcCommandWrite              = 0x02
    EePromCommandRead                = 0x03
    EepromCommandWriteLatchDisable   = 0x04
    EepromCommandReadStatusRegister  = 0x05
    EePromCommandWriteLatchEnable    = 0x06

    # *** 25LC256 addresses ***
    #EepromStartAddress0= 0x0000
    #EepromStartAddressUpper0 = 0x00
    #EepromStartAddressLower0 = 0x00

    EepromStartAddress1= 0x0300
    EepromStartAddressUpper1 = 0x03
    EepromStartAddressLower1 = 0x00

    # *** SPI variables and constants ***

    writeSpiDataList = [0x00]
    readSpiDataList  = [0x00, 0x00, 0x00, 0x00, 0x00]

    DummyDataByte = 0x00
    TestDataByte55  = 0x55
    TestDataByteAa  = 0xaa

    WriteProtectNone        = 0x00 # -
    WriteProtectUpperFourth = 0x04 # 0x6000 to 0x7fff
    WriteProtectUpperHalf   = 0x08 # 0x4000 to 0x7fff
    WriteProtectAll         = 0x0c # 0x0000 to 0x7fff

    FiveMilliSeconds = 0.005

    # *** Enable Write Enable Latch ***
    # while True:

    # ********************************************************
    # spiEeprom.xfer2([EePromCommandWriteLatchEnable])  

    #SpiWrite(spiEeprom.xfer2, [EePromCommandWriteLatchEnable])
    SpiWrite(spiEeprom, [EePromCommandWriteLatchEnable])

    time.sleep(FiveMilliSeconds)

    # *** Read Status Register ***
    readSpiDataList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WEL bit after Write Enable ***")
    PrintEightBitPattern("Read back byte 0 = ", readSpiDataList[0])
    PrintEightBitPattern("Read back byte 1 = ", readSpiDataList[1])
    time.sleep(FiveMilliSeconds)

    # *** Disable Write Enable Latch ***
    spiEeprom.xfer2([EepromCommandWriteLatchDisable])
    time.sleep(FiveMilliSeconds)

    # *** Check WEL (Write Enable Latch) bit (Bit 1) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WEL bit after Write Disable ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Write Enable ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(0.005)

    # *** Check WEL (Write Enable Latch) bit (Bit 1) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WEL bit after Write Enable ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Write protect upper fourth ****
    spiEeprom.xfer2([EepromCommandWriteStatusRegister, WriteProtectUpperFourth])
    time.sleep(0.005)

    # *** Check Status Register ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking Write Protect Bits ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Write Enable ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(0.005)

    # *** Write protect none ****
    spiEeprom.xfer2([EepromCommandWriteStatusRegister, WriteProtectNone])
    time.sleep(0.005)

    # *** Check Status Register ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking Write Protect Bits ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Write Enable ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(0.005)

    # *** Write 2 data bytes at address 0x0300 ****

    # while True:
    spiEeprom.xfer2([EepromcCommandWrite, EepromStartAddressUpper1, EepromStartAddressLower1, TestDataByte55, TestDataByte55])

    # *** Check WIP (Write In Progress) bit (Bit 0) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WIP bit immediately after writing 1 byte without waiting 5 mS ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Check WIP (Write In Progress) bit (Bit 0) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WIP bit again, after waiting 5 mS ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])

    # *** Enable Write Enable Latch ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(FiveMilliSeconds)

    # *** Read back data at address 0x0000 ***
 
    time.sleep(1)

    #while True:
    readSpiDataList = spiEeprom.xfer2([EePromCommandRead, EepromStartAddressUpper1, EepromStartAddressLower1, DummyDataByte, DummyDataByte])
 
    PrintDoubleSpaceLine("*** Read back data byte written ***")
    PrintEightBitPattern("Read back byte 0 = ", readSpiDataList[0])
    PrintEightBitPattern("Read back byte 1 = ", readSpiDataList[1])
    PrintEightBitPattern("Read back byte 2 = ", readSpiDataList[2])
    PrintEightBitPattern("Read back byte 3 = ", readSpiDataList[3])
    PrintEightBitPattern("Read back byte 4 = ", readSpiDataList[4])

    # *** Write Enable ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(0.005)

    # *** Write 2 data bytes at address 0x0000 ****
    spiEeprom.xfer2([EepromcCommandWrite, EepromStartAddressUpper1, EepromStartAddressLower1, TestDataByteAa, TestDataByteAa])

    # *** Check WIP (Write In Progress) bit (Bit 0) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WIP bit immediately after writing 1 byte without waiting 5 mS ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

    # *** Check WIP (Write In Progress) bit (Bit 0) ***
    readInByteList = spiEeprom.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WIP bit again, after waiting 5 mS ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])

    # *** Enable Write Enable Latch ***
    spiEeprom.xfer2([EePromCommandWriteLatchEnable])
    time.sleep(FiveMilliSeconds)

    # *** Read back data at address 0x0000 ***
 
    readSpiDataList = spiEeprom.xfer2([EePromCommandRead, EepromStartAddressUpper1, EepromStartAddressLower1, DummyDataByte, DummyDataByte])
 
    PrintDoubleSpaceLine("*** Read back data byte written ***")
    PrintEightBitPattern("Read back byte 0 = ", readSpiDataList[0])
    PrintEightBitPattern("Read back byte 1 = ", readSpiDataList[1])
    PrintEightBitPattern("Read back byte 2 = ", readSpiDataList[2])
    PrintEightBitPattern("Read back byte 3 = ", readSpiDataList[3])
    PrintEightBitPattern("Read back byte 4 = ", readSpiDataList[4])  
 
    # *** Close SPI channel ***
    spiEeprom.close()

    #while True:
    #    pass

    PrintDoubleSpaceLine("*** Stop testing write/read 25LC256 ***")


def Write25Lc256(spiChannel, channelNumber, chipEnableNumber, dataByte):

    spiChannel.open(channelNumber, chipEnableNumber)

    PrintDoubleSpaceLine("*** Start writing 25LC256 ***")

    # *** 25LC256 instructions ***
    EepromCommandWriteStatusRegister = 0x01
    EepromcCommandWrite              = 0x02
    EePromCommandRead                = 0x03
    EepromCommandWriteLatchDisable   = 0x04
    EepromCommandReadStatusRegister  = 0x05
    EePromCommandWriteLatchEnable    = 0x06

    # *** 25LC256 addresses ***

    EepromStartAddress1= 0x0300
    EepromStartAddressUpper1 = 0x03
    EepromStartAddressLower1 = 0x00

    # *** SPI variables and constants ***

    writeSpiDataList = [dataByte]
    readSpiDataList  = [0x00, 0x00, 0x00, 0x00, 0x00]

    DummyDataByte = 0x00
    TestDataByte55  = 0x55
    TestDataByteAa  = 0xaa

    WriteProtectNone        = 0x00 # -
    WriteProtectUpperFourth = 0x04 # 0x6000 to 0x7fff
    WriteProtectUpperHalf   = 0x08 # 0x4000 to 0x7fff
    WriteProtectAll         = 0x0c # 0x0000 to 0x7fff

    FiveMilliSeconds = 0.005

    SpiWrite(spiChannel, [EePromCommandWriteLatchEnable])

    time.sleep(FiveMilliSeconds)

    # *** Write 2 data bytes at address 0x0000 ****
    spiChannel.xfer2([EepromcCommandWrite, EepromStartAddressUpper1, EepromStartAddressLower1, dataByte, dataByte])

    # *** Read Status Register ***
    readSpiDataList = spiChannel.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WEL bit after Write Enable ***")
    PrintEightBitPattern("Read back byte 0 = ", readSpiDataList[0])
    PrintEightBitPattern("Read back byte 1 = ", readSpiDataList[1])
    time.sleep(FiveMilliSeconds)

    # *** Disable Write Enable Latch ***
    spiChannel.xfer2([EepromCommandWriteLatchDisable])
    time.sleep(FiveMilliSeconds)

    # *** Check WEL (Write Enable Latch) bit (Bit 1) ***
    readInByteList = spiChannel.xfer2([EepromCommandReadStatusRegister, DummyDataByte])
    PrintDoubleSpaceLine("*** Checking WEL bit after Write Disable ***")
    PrintEightBitPattern("Read back byte 0 = ", readInByteList[0])
    PrintEightBitPattern("Read back byte 1 = ", readInByteList[1])
    time.sleep(0.005)

def Read25Lc256DataByte(spiChannel, channelNumber, chipEnableNumber, eepromStartAddress):

    spiChannel.open(channelNumber, chipEnableNumber)

    PrintDoubleSpaceLine("*** Start reading 25LC256 ***")

    # *** 25LC256 instructions ***
    EePromCommandRead                = 0x03

    eepromStartAddressUpper = eepromStartAddress >> 8
    eepromStartAddressLower = eepromStartAddress & 0x00ff

    # *** SPI variables and constants ***

    readSpiDataList  = [0x00, 0x00, 0x00, 0x00, 0x00]
    DummyDataByte = 0x00

    # *** Read back data at address 0x0000 ***
 
    readSpiDataList = spiChannel.xfer2([EePromCommandRead, eepromStartAddressUpper, eepromStartAddressLower, DummyDataByte])
                                                     
    PrintDoubleSpaceLine("*** Read back data byte written ***")
    PrintEightBitPattern("Read back byte 0 = ", readSpiDataList[0])
    PrintEightBitPattern("Read back byte 1 = ", readSpiDataList[1])
    PrintEightBitPattern("Read back byte 2 = ", readSpiDataList[2])
    PrintEightBitPattern("Read back byte 3 = ", readSpiDataList[3])

    dataByte = readSpiDataList[3]
    return dataByte

# .END

No comments:

Post a Comment