balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

SPI CS/CE with active high

Sun Jan 06, 2019 1:48 pm

Hello,

sorry for my bad english but I hope you understand my question. I would like program an EEPROM 93C56 at the SPI-Interface with the linux flashrom tool. I use a Raspberry Model B with the following kernel and SPI driver

[email protected]:~ $ cat /proc/version
Linux version 4.14.79+ ([email protected]333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1159 Sun Nov 4 17:28:08 GMT 2018
[email protected]:~ $ sudo modprobe spi-bcm2835
[email protected]:~ $

But my EEPROM will not recognized because the raspberry use active low for the CS/CE pin as standard. Is it possible to change the behavior to active high ?

thx
Mario
Germany

AnneRanch
Posts: 72
Joined: Fri Oct 19, 2018 1:48 pm

Re: SPI CS/CE with active high

Fri Jan 11, 2019 5:05 pm

Yes, you need to set the BCM processor SPi configuration register. Not sure how it will interact with your driver- it is obviously set for CE "low" now.

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Mon Jan 14, 2019 3:42 pm

I did check linux flashroom tool and that device is not listed. This mean even if you set the CS High it won't work


Interfacing the chip using bit banging is not complicated. I got some old code in PLM51 with the 93C46 hanging in one diskette at home.
This tell you how old that device is ;-)

I will dig the code and make a small python script. I will post the code tonight.

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Mon Jan 14, 2019 6:09 pm

Ok I did this in my luch time. It should work but can't confirm before tonight!

Be aware that some 93C46 only works with 5V so you will need some level shifter to make it work.

The python3 class

Code: Select all

import RPi.GPIO as GPIO
#ORG = 0  ASSUME 8Bits data



class eerom93CX6:

  def __init__(self,type=9366, CS=12,SK=16,DI=20,DO=21):
     if type == 9366:
        self.bitMask=256
        self.andMask=511
        self.addressRange=9
        self.size=512
     elif type == 9356:
        self.bitMask=256
        self.andMask=511
        self.addressRange=9
        self.size=256
     else:
        self.bitMask=64
        self.andMask=127
        self.addressRange=7
        self.size=128

     self.CS=CS
     self.SK=SK
     self.DI=DI
     self.DO=DO

     GPIO.setwarnings(False)
     GPIO.setwarnings(False)
     GPIO.setmode(GPIO.BCM)
     GPIO.setup(CS,GPIO.OUT)
     GPIO.setup(SK,GPIO.OUT)
     GPIO.setup(DI,GPIO.OUT)
     GPIO.setup(DO,GPIO.IN,pull_up_down=GPIO.PUD_UP)
     GPIO.output(CS,0)
     GPIO.output(SK,0)
     GPIO.output(DI,0)

  def bitOUT(self,value):
     GPIO.output(self.DI,value)
     GPIO.output(self.SK,1)
     GPIO.output(self.SK,0)

  def bitIN(self):
     GPIO.output(self.SK,1)
     value=GPIO.input(self.DO)
     GPIO.output(self.SK,0)
     return value

  def read(self,address):
     data=0
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(1)
     self.bitOUT(0)
     #set address
     for i in range(self.addressRange):
       if (address & self.bitMask) == self.bitMask:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       address= (address << 1) & self.andMask
     #read 8 bits
     for i in range(8):
       data = data << 1
       if self.bitIN():
         data = data | 1
     GPIO.output(self.CS,0)
     GPIO.output(self.DI,0)
     return data

  def enable(self):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(1)
     for i in range(self.addressRange -2):
       self.bitOUT(0)
     GPIO.output(self.CS,0)

  def disable(self):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(0)
     for i in range(self.addressRange -2):
       self.bitOUT(0)
     GPIO.output(self.CS,0)


  def write(self,address,data):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(1)
     #set address
     for i in range(self.addressRange):
       if (address & self.bitMask) == self.bitMask:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       address= (address << 1) & self.andMask
     #write 8 bits data
     for i in range(8):
       if (data & 128) == 128:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       data= (data << 1) & 255
     GPIO.output(self.DI,0)
     GPIO.output(self.CS,0)
     #wait for ready
     GPIO.output(self.CS,1)
     while not self.bitIN():
        pass
     GPIO.output(self.CS,0)
the script read93C56.py which write binary file "eerom.dat"

Code: Select all

import eerom93CX6


#assume default pin
CS= 12
SK= 16
DI= 20
DO= 21


file=open("eerom.dat","wb")


eerom = eerom93CX6.eerom93CX6(9356,CS=12,SK=16,DI=20,DO=21)

for i in range(eerom.size):
   v = eerom.read(i)
   if i % 16 == 0:
     print("{:03X} : ".format(i),end="")
   print("{:2x} ".format(v),end="")
   file.write(v.to_bytes(1,byteorder='big'))
   if i % 16 == 15:
     print()

print("file eerom.dat written\n")
file.close()

And finally the script write93C56.py which read eerom.dat and write the data into the chip.

Code: Select all

import eerom93CX6
import sys


filename="eerom.dat"

if len(sys.argv) == 2:
   filename = sys.argv(1)

print("From file ",filename," to eerom.");

file=open(filename,"rb")

data = file.read()
file.close()

eerom = eerom93CX6.eerom93CX6(9356,CS=12,SK=16,DI=20,DO=21)

eerom.enable()
print("Writing eerom")

for i in range(len(data)):
   if i >= eerom.size:
     break;
   v = data[i]
   eerom.write(i,v)
   if i % 16 == 0:
     print("{:03X} : ".format(i),end="")
   print("{:2x} ".format(v),end="")
   if i % 16 == 15:
     print()
     
eerom.disable()
print("Writing Done\nRead eerom back")

for i in range(eerom.size):
   v = eerom.read(i)
   if i % 16 == 0:
     print("{:03X} : ".format(i),end="")
   print("{:2x} ".format(v),end="")
   if i % 16 == 15:
     print()
UPDATE*** Update script, fix bugs and confirm that 93C46 works

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Fri Jan 18, 2019 7:21 pm

Thank you very much!!!

I will try it directly tomorrow. Only one question yet. Does it need a special driver or only the bcm2835 ?

thx
Mario

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Fri Jan 18, 2019 7:40 pm

No driver!

I'm not using the SPI at all. Just GPIO pins with a python3 script.

Pins definition
CS=12,
SK=16,
DI=20,
DO=21

If you have an old Raspberry Pi B, 26 pins connectors, you will need to set new pin definition.

P.S. don't forget that a lot of 93CX6 eeroms work only on 5V. Please check the specification. If it is, then use some 3.3V to 5V adapter like this one.
https://www.sparkfun.com/products/12009 or put a resistor divider on D0 pin ,2k/3K3. This way you don't put 5V on the raspberry Pi GPIO

Andyroo
Posts: 1569
Joined: Sat Jun 16, 2018 12:49 am
Location: Lincs U.K.

Re: SPI CS/CE with active high

Fri Jan 18, 2019 9:09 pm

Why not use an inverter or transistor and a couple of resistors?

You could also handle the 3.3v to 5V difference for this pin with the transistor at the same time :lol:
Need Pi spray - these things are breeding in my house...

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Fri Jan 18, 2019 9:40 pm

Good chance that only two resistors will do the trick.
PI_93C46.jpg
93C46 to Raspberry PI
PI_93C46.jpg (53.88 KiB) Viewed 879 times

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Sun Jan 20, 2019 3:48 pm

[email protected] for the great idea. But I have some questions to the suggestion.

As I described I want use my old Raspberry 1 Model B. This model have only the 26-pin I/O connector. Is it also possible to use the GPIO ports 22, 23, 24 and 25 and to remap in your script? These GPIO ports should be free and not reserved from the SPI or I2C driver. Is it right that you recommend an 2,2kOhm and an 3,3kOhm resistor?
I'm not a software developer. Must be the class file and script file in a special directory?

Many Thanks to Canada !

Regards
Mario
Germany
Attachments
raspberry-pi-rev2-gpio-pinout-1024x715.jpg
raspberry-pi-rev2-gpio-pinout-1024x715.jpg (148.86 KiB) Viewed 804 times

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Sun Jan 20, 2019 7:41 pm

Yes just change the GPIO in the read and write script!

eerom = eerom93CX6.eerom93CX6(9356,CS=22,SK=23,DI=24,DO=25)


Most of the 93CX6 only works with 5V. Please check the technical specification.


The Raspberry PI have only 3.3V GPIO. They can't support more than that!

Only the output from the 93CX6 needs to be converted to 3.3V. All inputs from the 93CX6 will work on 3.3V since the ViH is 2.7V.

Then to get 3.3V from a 5V output we need to create a resistor divider. Check wikipedia to know how it works. https://en.wikipedia.org/wiki/Voltage_divider


4K7/10K will do also or any value of resistors when 5V is near 3V. Be sure that the current is not to much. (< 2ma)

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Mon Jan 21, 2019 8:12 am

Hello,

I understand your hint about the voltage difference but the voltage divider is currently not my main issue.

I try to understand your Python script. My 93C56 is currently soldered on a PCB and is set in the 16-bit Mode (ORG is connected to Vcc). Therefore the address bits are going from A0-A7 and the data bits from D0-D15. Is it for example enough to change the range for the data bits in your read script ?

#read 8 bits
for i in range(8): <<<<-------- 16 ???
data = data << 1
if self.bitIN():
data = data | 1

I don't know where the program code is for the address counter.

Many Thanks !
Mario

P.S. Sorry again for my english !

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Mon Jan 21, 2019 3:38 pm

I will made tonight then change to the class to allow 8 or 16 bits. I will also use my old PI B.


Check Table5 to see how many bits for address and data.
https://www.jameco.com/Jameco/Products/ ... 393601.pdf

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Mon Jan 21, 2019 4:18 pm

I know this datasheet. I just wanted to say, that with 8-bit mode the address bits are going from A0-A8 and in 16-bit mode from A0-A7. I think currently only the 8-bit mode is programmed in your script. I have tried to change it but if you would do it for me, this would be very nice.

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Tue Jan 22, 2019 1:01 am

I modified the eerom93CX6 class to be 8 or 16 bits with the 'org'parameters. I also changed the GPIO for 22,23,24 and 25. This way you could use the Raspberry Pi B.


eerom93CX6.py

Code: Select all

import RPi.GPIO as GPIO
#ORG = 1  ASSUME 16Bits data



class eerom93CX6:


  def __init__(self,type=9356,org=1,CS=22,SK=23,DI=24,DO=25):
     self.org=org
     if org ==0:
       self.dataBitSize=8
     else:
       self.dataBitSize=16
#===== 9366 =====
     if type == 9366:
       if org == 0:
          self.bitMask=256
          self.addressRange=9
          self.size=512
       else:
          self.bitMask=128
          self.addressRange=8
          self.size=256
#===== 9356 =====
     elif type == 9356:
       if org ==0:
          self.bitMask=256
          self.addressRange=9
          self.size=256
       else:
          self.bitMask=128
          self.addressRange=8
          self.size=128
#===== 9346 =====
     else:
       if org ==0:
          self.bitMask=64
          self.addressRange=7
          self.size=128
       else:
          self.bitMask=32
          self.addressRange=6
          self.size=64

     print("BitMasK=",self.bitMask)
     print("addressRange=",self.addressRange)
     print("size=",self.size)


     self.CS=CS
     self.SK=SK
     self.DI=DI
     self.DO=DO

     GPIO.setwarnings(False)
     GPIO.setwarnings(False)
     GPIO.setmode(GPIO.BCM)
     GPIO.setup(CS,GPIO.OUT)
     GPIO.setup(SK,GPIO.OUT)
     GPIO.setup(DI,GPIO.OUT)
     GPIO.setup(DO,GPIO.IN,pull_up_down=GPIO.PUD_UP)
     GPIO.setup(7,GPIO.OUT)
     if org == 0:
       GPIO.output(7,0)
     else:
       GPIO.output(7,1)

     GPIO.output(CS,0)
     GPIO.output(SK,0)
     GPIO.output(DI,0)

  def bitOUT(self,value):
     GPIO.output(self.DI,value)
     GPIO.output(self.SK,1)
     GPIO.output(self.SK,0)

  def bitIN(self):

     GPIO.output(self.SK,1)
     GPIO.output(self.SK,0)
     value=GPIO.input(self.DO)
     return value

  def eraseAll(self):
     self.enable()
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(0)
     for i in range(self.addressRange -2):
       self.bitOUT(0)
     GPIO.output(self.CS,0)




  def read(self,address):
     data=0
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(1)
     self.bitOUT(0)
     #set address
     for i in range(self.addressRange):
       if (address & self.bitMask) == self.bitMask:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       address= address << 1

     #read data bits
     for i in range(self.dataBitSize):
       data = data << 1
       if self.bitIN():
         data = data | 1
     GPIO.output(self.CS,0)
     GPIO.output(self.DI,0)
     return data

  def enable(self):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(1)
     for i in range(self.addressRange -2):
       self.bitOUT(0)
     GPIO.output(self.CS,0)

  def disable(self):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(0)
     self.bitOUT(0)
     for i in range(self.addressRange -2):
       self.bitOUT(0)
     GPIO.output(self.CS,0)


  def write(self,address,data):
     GPIO.output(self.CS,0)
     self.bitOUT(0)
     GPIO.output(self.CS,1)
     self.bitOUT(0)
     self.bitOUT(1)
     self.bitOUT(0)
     self.bitOUT(1)
     #set address
     for i in range(self.addressRange):
       if (address & self.bitMask) == self.bitMask:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       address= address << 1
     #write data
     if self.org == 0:
        databitMask = 0x0080
     else:
        databitMask=  0x8000

     for i in range(self.dataBitSize):
       if (data & databitMask) == databitMask:
         self.bitOUT(1)
       else:
         self.bitOUT(0)
       data= data << 1
     GPIO.output(self.DI,0)
     GPIO.output(self.CS,0)
     #wait for ready
     GPIO.output(self.CS,1)
     while not self.bitIN():
        pass
     GPIO.output(self.CS,0)
read93C56.py

Code: Select all

#!/usr/bin/python3
import eerom93CX6



file=open("eerom.dat","wb")


eerom = eerom93CX6.eerom93CX6(9356,org=1,CS=22,SK=23,DI=24,DO=25)


for i in range(eerom.size):
   v = eerom.read(i)
   if i % 8 == 0:
     print("{:03X} : ".format(i),end="")
   print("{:04X} ".format(v),end="")
   file.write(v.to_bytes(2,byteorder='little'))
   if i % 8 == 7:
     print()


print("file eerom.dat written\n")
file.close()

write93C56.py

Code: Select all

#!/usr/bin/python3
import eerom93CX6
import sys
import time


filename="eerom.dat"

if len(sys.argv) == 2:
   filename = sys.argv[1]

print("From file ",filename," to eerom.");

file=open(filename,"rb")

data = file.read()
file.close()

eerom = eerom93CX6.eerom93CX6(9356,org=1,CS=22,SK=23,DI=24,DO=25)

eerom.enable()


print("Writing eerom")
dataFormat="{:02X} "


if eerom.org == 1:
  dataFormat="{:04X} "
  #if 16bits (org=1) then convert 8bits to 16bits (small endian)
  data16bits=[]
  for i in range(len(data)//2):
    data16bits.append(data[i*2] | data[(i*2)+1] << 8)
  data = data16bits


for i in range(len(data)):
   if i >= eerom.size:
     break;
   v = data[i]
   eerom.write(i,v)
   time.sleep(0.01)
   if i % 8 == 0:
     print("{:03X} : ".format(i),end="")
   print(dataFormat.format(v),end="")
   if i % 8 == 7:
     print()

eerom.disable()

print("Writing Done\nRead eerom back")

for i in range(eerom.size):
   v = eerom.read(i)
   if i % 8 == 0:
     print("{:03X} : ".format(i),end="")
   print(dataFormat.format(v),end="")
   if i % 8 == 7:
     print()
P.S. read93C56.py will create a file 'eerom.dat' which is little endian.

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Jan 24, 2019 7:28 am

Thanks for the script. I have not tested it yet and I'm just now trying to understand it. Because I'm yet never programmed have in Python I need a little bit.

Thanks
Mario

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Tue Mar 19, 2019 2:22 pm

Hello danjperron,

Sorry for the big delay but I have in the meantime tested a lot of things. Unfortunately I have so far no success with the programming of the EEPROM. For better testing, I borrowed a Logic Analyzer from a friend and bought an additional 93c46 EEPROM.
Then I modified your script a little bit because a "0" was too much sent in the op code. Please take a look in my jpg files. For a test I have wrote the string "HELLO" to the 93c46 EEPROM. After the write command your script reads the EEPROM data for verification. But if you look at the received data they are completely different. Do you have an idea what is going wrong. If you want I can send you the analyzer log (Saleae Analyzer).

Thanks for your help.
Mario

https://drive.google.com/file/d/15Tz-vY ... sp=sharing
https://drive.google.com/file/d/18Jl_Mt ... sp=sharing
https://drive.google.com/file/d/1VjwAD3 ... sp=sharing
https://drive.google.com/file/d/1Ksishd ... sp=sharing
https://drive.google.com/file/d/1i9npVg ... sp=sharing

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Thu Mar 21, 2019 2:55 am

Mario,
I didn't check your python script yet but I had 2 errors on my post.


#1 Error on Fritzing design. pin1 of 93CX6 needs to be on GPIO12 not on GND. (Correct in the python script).
#2 Error on write93C56.py line 9

I should have used bracket and not parentheses. I was using the default file eerom.dat! This is why I didn't catch that one.

Code: Select all

if len(sys.argv) == 2:
   filename = sys.argv[1]

For the 93c46 did you change the type or you kept 9356

Code: Select all

eerom = eerom93CX6.eerom93CX6(9346,CS=12,SK=16,DI=20,DO=21)

All my 93C46 works fine without change except for the bugs above,

read93C46.gif
93C46 read byte at 0x5b = 100
read93C46.gif (23.02 KiB) Viewed 143 times
The first data bits is always 1 . Even if you have 10 zeros before it will start with the first one. The read command is 110 in binary.
I wrote at address 0x5B the value of 100 and it returns 100.

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Mar 21, 2019 8:26 am

Thank your very much for your feedback but now I'm absolut confused :D . To the minor issues.
danjperron wrote:
Thu Mar 21, 2019 2:55 am

#1 Error on Fritzing design. pin1 of 93CX6 needs to be on GPIO12 not on GND. (Correct in the python script).
Because I use a Rapsberry 1 Model B my Pinout is anyway different. I use

cable color / Rapsberry Pin / Atmel 93c46 Pin
red / pin 2 (+5V) / pin 8 (Vcc)
black / pin 6 (GND) / pin 5 (GND)
cyan / pin 15 (GPIO22) / pin 1 (CS)
green / pin 16 (GPIO23) / pin 2 (SK)
orange / pin 18 (GPIO24) / pin 3 (DI)
yellow / pin 22 (GPIO25) / pin 4 (DO) voltage divider inserted
additional there is a connect between Vcc and ORG on the 93c46 for the 16-bit mode.

That's correct in my opinion. Also everything looks good in the logic analyzer.
danjperron wrote:
Thu Mar 21, 2019 2:55 am

#2 Error on write93C56.py line 9
I should have used bracket and not parentheses. I was using the default file eerom.dat! This is why I didn't catch that one.
In the last version of your write script the bug was already fixed
danjperron wrote:
Thu Mar 21, 2019 2:55 am

For the 93c46 did you change the type or you kept 9356
Yes, I have changed the type from 93c56 to 93c46


Now to my major issue what I mean,

In your screenshot it is good to see that your script begin the transfer with the bit combination 0110 (CS is high and the SK with rising edge). If I understand the Atmel guide correct the read operation should start with the bit sequense 110 (not with the first 0).
Atmel Read.JPG
Atmel Read.JPG (26.86 KiB) Viewed 130 times
Therefore I deleted this first 0 in your script for every operation:

read operation
line 107

write enable
line 132

write disable
line 146

write operation
line 161

Now I'm absolut confused because you have success with programming. I don't understand the following:

- the CS is going high
- the next SK with a rising edge takes over the DI bit
- thats in your screenshot a "0" and not a "1"
- why is yours "0110" correct and not my "110" ?

Thanks
Mario

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Thu Mar 21, 2019 11:15 am

In your screenshot it is good to see that your script begin the transfer with the bit combination 0110 (CS is high and the SK with rising edge). If I understand the Atmel guide correct the read operation should start with the bit sequense 110 (not with the first 0).
You have to read between the lines. Sequence start with the bit 1.
The AT93C46 is accessed via a simple and versatile three-wire serial communication
interface. Device operation is controlled by seven instructions issued by the host processor. A valid instruction starts with a rising edge of CS and consists of a start bit (logic
“1”) followed by the appropriate op code and the desired memory address location.
the first 1 is called SB (start bit).
Then using 0b110 or sending 8 bits like this 0b00000110 is the same. This provides a way to use a standard SPI device.

Mind you that removing the 0 before the SB doesn't hurt anyway.



I will check it tonight with my B version 1.0. I wrote the script on my Pi 3B+ and I tested yesterday on my Pi2.

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Mar 21, 2019 12:02 pm

danjperron wrote:
Thu Mar 21, 2019 11:15 am
Then using 0b110 or sending 8 bits like this 0b00000110 is the same.
I think that's my mistake. I thought, after the rising edge of the CS, the direct following input bit is read as Op code. That means, 0b110, 0b00110, or 0b0000110 are exactly the same op-code (e.g. read operation) ?

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Mar 21, 2019 1:21 pm

Now I have an explanation for the start procedure of the transmission but why is my eeprom wrong programmed. Please take a look at my analyzer screenshot :

1. write enable operation
93c46 write enable.JPG
93c46 write enable.JPG (29.9 KiB) Viewed 90 times
2. write operation sends the bytes 0x4548 to the EEPROM address 0x00
93c46 write 2 bytes.JPG
93c46 write 2 bytes.JPG (37.02 KiB) Viewed 90 times
3. write disable operation
93c46 write disable.JPG
93c46 write disable.JPG (28.71 KiB) Viewed 90 times

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Mar 21, 2019 1:24 pm

4. read operation at address 0x00
93c46 read 2 bytes.JPG
93c46 read 2 bytes.JPG (37.67 KiB) Viewed 89 times
You see, the values are completly different. Maybe my main issue is now more clearly.

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Thu Mar 21, 2019 2:53 pm

OK! you are using 16 bits.

I'm using 8 bits ! you should split your 16 bits into two 8 bits.


My ORG pin is at GND for 8 bits operation.

I will have to check , on 16 bits, what is the memory bank behavior. I hope that 16 bits address 0 is 8 bits address 0(LSB) and 1 (MSB).


Daniel


Note to myself . I Completely forgot that I made a 16 bits version.

balz333
Posts: 13
Joined: Sun Jan 06, 2019 1:46 pm
Location: North Rhine-Westphalia, Germany

Re: SPI CS/CE with active high

Thu Mar 21, 2019 4:14 pm

Here a little example what I want write to the EEPROM
Example.JPG
Example.JPG (22.41 KiB) Viewed 60 times
In the 16-bit mode

Address bits = A5-A0
Data bits = D15-D0

danjperron
Posts: 3239
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: SPI CS/CE with active high

Fri Mar 22, 2019 2:36 am

Ok I tried my latest code with 8/16 bits capability.

I had no problem at all.

Both of my old Raspberry Pi model B are in use but my Pi model A was available!

Image

I'm using 2K/3K3 on DO to reduce the 5V to 3.3V.

I used the same color wires and same pins.

I added GPIO 17 which is wiringpi 0 to control the group mode.

And this is the result of my test

Code: Select all

[email protected]:~ $ echo "set Group to 1 -> 16 bits"
set Group to 1 -> 16 bits
[email protected]:~ $ gpio mode 0 OUT
[email protected]:~ $ gpio write 0 1
[email protected]:~ $ gpio readall
 +-----+-----+---------+------+---+-Model  A-+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |  OUT | 1 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |  OUT | 0 | 15 || 16 | 0 | OUT  | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | OUT  | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 0 | OUT  | CE1     | 11  | 7   |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+-Model  A-+---+------+---------+-----+-----+
[email protected]:~ $ echo "write all zero"
write all zero
[email protected]:~ $ dd if=/dev/zero of=zero.dat bs=128 count=1
1+0 records in
1+0 records out
128 bytes copied, 0.0042909 s, 29.8 kB/s
[email protected]:~ $ hexdump zero.dat
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000080
[email protected]:~ $ python3 write93C46.py zero.dat
From file  zero.dat  to eerom.
BitMasK= 32
addressRange= 6
size= 64
Writing eerom
000 : 0000 0000 0000 0000 0000 0000 0000 0000 
008 : 0000 0000 0000 0000 0000 0000 0000 0000 
010 : 0000 0000 0000 0000 0000 0000 0000 0000 
018 : 0000 0000 0000 0000 0000 0000 0000 0000 
020 : 0000 0000 0000 0000 0000 0000 0000 0000 
028 : 0000 0000 0000 0000 0000 0000 0000 0000 
030 : 0000 0000 0000 0000 0000 0000 0000 0000 
038 : 0000 0000 0000 0000 0000 0000 0000 0000 
Writing Done
Read eerom back
000 : 0000 0000 0000 0000 0000 0000 0000 0000 
008 : 0000 0000 0000 0000 0000 0000 0000 0000 
010 : 0000 0000 0000 0000 0000 0000 0000 0000 
018 : 0000 0000 0000 0000 0000 0000 0000 0000 
020 : 0000 0000 0000 0000 0000 0000 0000 0000 
028 : 0000 0000 0000 0000 0000 0000 0000 0000 
030 : 0000 0000 0000 0000 0000 0000 0000 0000 
038 : 0000 0000 0000 0000 0000 0000 0000 0000 
[email protected]:~ $ echo " write Hello world in UNICODE"
 write Hello world in UNICODE
[email protected]:~ $ echo "Hello World!" | iconv -f ascii -t UNICODE -o Hello.dat
[email protected]:~ $ hexdump -C Hello.dat
00000000  ff fe 48 00 65 00 6c 00  6c 00 6f 00 20 00 57 00  |..H.e.l.l.o. .W.|
00000010  6f 00 72 00 6c 00 64 00  21 00 0a 00              |o.r.l.d.!...|
0000001c
[email protected]:~ $ python3 write93C46.py Hello.dat
From file  Hello.dat  to eerom.
BitMasK= 32
addressRange= 6
size= 64
Writing eerom
000 : FEFF 0048 0065 006C 006C 006F 0020 0057 
008 : 006F 0072 006C 0064 0021 000A Writing Done
Read eerom back
000 : FEFF 0048 0065 006C 006C 006F 0020 0057 
008 : 006F 0072 006C 0064 0021 000A 0000 0000 
010 : 0000 0000 0000 0000 0000 0000 0000 0000 
018 : 0000 0000 0000 0000 0000 0000 0000 0000 
020 : 0000 0000 0000 0000 0000 0000 0000 0000 
028 : 0000 0000 0000 0000 0000 0000 0000 0000 
030 : 0000 0000 0000 0000 0000 0000 0000 0000 
038 : 0000 0000 0000 0000 0000 0000 0000 0000 
[email protected]:~ $ python3 read93C46.py
BitMasK= 32
addressRange= 6
size= 64
000 : FEFF 0048 0065 006C 006C 006F 0020 0057 
008 : 006F 0072 006C 0064 0021 000A 0000 0000 
010 : 0000 0000 0000 0000 0000 0000 0000 0000 
018 : 0000 0000 0000 0000 0000 0000 0000 0000 
020 : 0000 0000 0000 0000 0000 0000 0000 0000 
028 : 0000 0000 0000 0000 0000 0000 0000 0000 
030 : 0000 0000 0000 0000 0000 0000 0000 0000 
038 : 0000 0000 0000 0000 0000 0000 0000 0000 
file eerom.dat written

[email protected]:~ $ hexdump -C eerom.dat
00000000  ff fe 48 00 65 00 6c 00  6c 00 6f 00 20 00 57 00  |..H.e.l.l.o. .W.|
00000010  6f 00 72 00 6c 00 64 00  21 00 0a 00 00 00 00 00  |o.r.l.d.!.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080
[email protected]:~ $ echo "switch to 8 bits"
switch to 8 bits
[email protected]:~ $ gpio write 0 0
[email protected]:~ $ python3 read93C46_8bits.py
BitMasK= 64
addressRange= 7
size= 128
000 : FE FF 00 48 00 65 00 6C 
008 : 00 6C 00 6F 00 20 00 57 
010 : 00 6F 00 72 00 6C 00 64 
018 : 00 21 00 0A 00 00 00 00 
020 : 00 00 00 00 00 00 00 00 
028 : 00 00 00 00 00 00 00 00 
030 : 00 00 00 00 00 00 00 00 
038 : 00 00 00 00 00 00 00 00 
040 : 00 00 00 00 00 00 00 00 
048 : 00 00 00 00 00 00 00 00 
050 : 00 00 00 00 00 00 00 00 
058 : 00 00 00 00 00 00 00 00 
060 : 00 00 00 00 00 00 00 00 
068 : 00 00 00 00 00 00 00 00 
070 : 00 00 00 00 00 00 00 00 
078 : 00 00 00 00 00 00 00 00 
file eerom.dat written

[email protected]:~ $ hexdump -C eerom.dat
00000000  fe ff 00 48 00 65 00 6c  00 6c 00 6f 00 20 00 57  |...H.e.l.l.o. .W|
00000010  00 6f 00 72 00 6c 00 64  00 21 00 0a 00 00 00 00  |.o.r.l.d.!......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080
[email protected]:~ $
Last edited by danjperron on Fri Mar 22, 2019 11:00 am, edited 1 time in total.

Return to “Interfacing (DSI, CSI, I2C, etc.)”