23LC1024 manual programming - Page 1
Forum section: electronics / projects

author: q12
author_rank: Contributor
timestamp: September 15, 2022, 04:23:52 pm
content: Hello, I buy recently this 23LC1024https://ww1.microchip.com/downloads/aemDocuments/documents/MPD/ProductDocuments/DataSheets/23A1024-23LC1024-1-Mbit-SPI-Serial-SRAM-with-SDI-and-SQI-Interface-DS20005142.pdfwhich is a SRAM chip.I followed a tutorial in which the testing program had only: #include <SPI.h> in it. And it worked without problems. I actually tested with real arduino uno and in proteus simulator, with an arduino uno component there.Both worked.-- I also read the datasheet chip as well and figure out from there [a way] of communicating with it. This part is exactly what I want to test. A 23LC1024 manual programming.Here are two diagrams from the datasheet that I used all the time while coding:andWith help from the Arduino forums, I advanced to a point where I get a result, but is not the correct result.What I am doing in this code: I am directly accessing the pins of the RAM, by a method called 'Bit Banging'. I am hardcoding the instructions, and sending them manually as simply as possible.The result is still incorrect. Please, advise me where the problem is that I can't see?This is the output console from the Proteus simulator. The transmitted bits should be the same in the received/read bits. I am clearly missing something, but what?The folowing is the Arduino code:Code:#include "Arduino.h"/************SRAM opcodes: commands to the 23LC1024 memory chip ******************/#define clk 13 // Manual Serial Clock#define wpin 12 // Write pin#define rpin 11 // Read pin#define cspin 10 // Chip Select/************Global Variables*********************/byte bcode = 0b11100111; // test bitcode to send/receive only oncevoid setup(void) {Serial.begin(9600);pinMode(clk, OUTPUT);pinMode(wpin, OUTPUT);pinMode(rpin, OUTPUT);pinMode(cspin, OUTPUT);digitalWrite(cspin,LOW); // ChipSelect CS is Low to start and High to end a read/write operation.digitalWrite(rpin,LOW); // initialize read pin as Output Low/*-----------------------------------Writing------------------------------------*/digitalWrite(cspin, LOW); // starting write operationSerial.println("Transmiting data:");digitalWrite(clk, 0);//-------------1st: 8bit initialization-------------//this is 00000010for (int i = 0; i < 6; i++) {digitalWrite(clk, 1);digitalWrite(wpin, 0); // only 6 0'sdigitalWrite(clk, 0);}digitalWrite(clk, 1);digitalWrite(wpin, 1); // 7th bitdigitalWrite(clk, 0);digitalWrite(clk, 1);digitalWrite(wpin, 0); // 8th bitdigitalWrite(clk, 0);//-------------2nd: 24bit address-------------------//this is 00000000 00000000 00000001for (int i = 0; i < 23; i++) {digitalWrite(clk, 1);digitalWrite(wpin, 0); // last 23 addr bitsdigitalWrite(clk, 0);}digitalWrite(clk, 1);digitalWrite(wpin, 1); // first 1 addr bit (reading from R to L)digitalWrite(clk, 0);//-------------3rd 8bit code-----------------------digitalWrite(clk, 1);digitalWrite(wpin, bcode); // WRITE bitcode into RAM addressSerial.println(bcode, BIN);digitalWrite(clk, 0);//CSpindigitalWrite(clk, 1);// from datasheet: "A write is terminated by the CS being brought high"digitalWrite(cspin,HIGH); // finishing write operationdigitalWrite(clk, 0);digitalWrite(clk, 1);digitalWrite(cspin,LOW); // starting read operationdigitalWrite(clk, 0);/*-----------------------------------Reading------------------------------------*/Serial.println("Receiving data:");//-------------1st: 8bit initialization-------------// this is 00000011for (int i = 0; i < 6; i++) {digitalWrite(clk, 1);digitalWrite(wpin, 0); // only 6 0'sdigitalWrite(clk, 0);}digitalWrite(clk, 1);digitalWrite(wpin, 1); // 7th bitdigitalWrite(clk, 0);digitalWrite(clk, 1);digitalWrite(wpin, 1); // 8th bitdigitalWrite(clk, 0);//-------------2nd: 24bit address-------------------//this is 00000000 00000000 00000001for (int i = 0; i < 23; i++) {digitalWrite(clk, 1);digitalWrite(wpin, 0); // last 23 addr bitsdigitalWrite(clk, 0);}digitalWrite(clk, 1);digitalWrite(wpin, 1); // first 1 addr bit (reading from R to L)digitalWrite(clk, 0);//-------------3rd 8bit code-----------------------//this should be 11100111byte result = 0;String strout="";for (int i = 0; i < 8; i++) {digitalWrite(clk, 1);// In SDI mode, the transfer is two bits per clock pulse.strout+=bitRead(rpin, i); // is giving me 11010000 instead of 11100111digitalWrite(clk, 0);}Serial.println(strout); // READ bitcode into RAM addressdigitalWrite(cspin, HIGH); // finishing read operation}void loop() { // we have nothing to do in the loop}//End of programThe summary of my code is very simple: I write this hardcoded : "byte bcode = 0b11100111; " that I am sending to be written into the chip at address 000...0001 (24bits long address) and then I am reading the chip output pin again at the same address and retrieve the data stored at that address. But instead of being 11100111 (this lovely test pattern), is something else. Is this result that appears, doesnt matter what input pattern I insert:The guys from arduino forums introduced me to bit banging and I have a pretty good idea what it is. I am not that advanced into SPI comunication though, but I also got the idea.Its this chip... you see? It has some very special way of communicating even if is SPI. Its fromMicrochipand they always had to add some weird way of access, indifferent of the component they sell. But after figuring out the little details and make it work, then is a very reliable component.All I need is NOT to comunicate through a standard SPI way, but through bitbanging, simulating a SPI comunication. Thats my intention.I strongly believe is not a matter of arduino anymore. Because the guys there would have spotted already any mistake. We are banging this code for a few days already. I believe is a matter of microchip mischievousness in sending/receiving that entire instruction. It is my conclusion after staring too much into this problem.I also find this little detail that I have no idea how to implement it. But it is exactly the same result that I keep getting in the output, indiferent what input test bitcode I send:https://youtu.be/MCi7dCBhVpQ?t=1064Thank you !PS: I almost forget. I put anattachmenthere with the arduino code, the proteus save file with all the components inside as in the image I posted, and the circuit diagram.

author: ledtester
author_rank: Super Contributor
timestamp: September 15, 2022, 04:55:02 pm
content: This does not look like the correct use of the bitread() function:Code:strout+=bitRead(rpin, i);bitread documentation:https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitread/The bitread function accesses the n-th bit of a number and returns either 0 or 1. It does not perform a digitalRead.You want to do something like this:Code:byte read_byte() {byte x = 0;for (byte i = 0; i < 8; i++) {digitalWrite(clk, 1);x = (x << 1) | digitalRead(rpin);digitalWrite(clk, 0);}return x;}This read_byte() function returns a byte value instead of a string.

author: q12
author_rank: Contributor
timestamp: September 15, 2022, 05:22:02 pm
content: Thank you, here I modified your code, to actually output a result:Code:byte read_byte() {String strout2="";byte x = 0;for (byte i = 0; i < 8; i++) {digitalWrite(clk, 1);x = (x << 1) | digitalRead(rpin);strout2+=x;digitalWrite(clk, 0);}Serial.println(strout2);return x;}and here is implemented:Code://-------------3rd 8bit code-----------------------//this should be 11100111read_byte();digitalWrite(cspin,HIGH); //finishing read operation}The result console output is still incorrect, showing me: 00000000This means is an empty value at that address. Hmmm...

author: strawberry
author_rank: Super Contributor
timestamp: September 15, 2022, 07:15:57 pm
content: maybe Arduino digitalRead() digitalWrite() is causing some timing issuesoscilloscope, maybe signal is in ill-quality

author: ledtester
author_rank: Super Contributor
timestamp: September 15, 2022, 07:18:06 pm
content: Here's another problem:Code:pinMode(rpin, OUTPUT);rpin should be an INPUT.

author: q12
author_rank: Contributor
timestamp: September 16, 2022, 03:15:40 am
content: Excellent debugging mister @ledtester ! Please, keep going.I didnt see this last one at all. I was sure I have some nasty code in there. But they slip from my view when I am trying to debug it. Especially after ~1week of concentration and many-many trying and error. Another eye is gold. Especially for this kind of project that is totally new to me, new chip, new mentality of comunicating using the bitbang and somewhat new commands in arduino to get used to. A lot of new stuff for me. A lot to learn. So thank you for sticking with me.

author: darkspr1te
author_rank: Frequent Contributor
timestamp: September 16, 2022, 06:28:20 am
content: Quote from: q12 on September 16, 2022, 03:15:40 amMy father used to say "Cannot see the wood for the tree's" in situations like this.darkspr1te

author: Pepito
author_rank: Newbie
timestamp: September 30, 2022, 03:59:55 pm
content: now this program is correct

author: Faranight
author_rank: Unknown
timestamp: October 04, 2022, 05:42:56 am
content: I recently managed to get this chip working on a SPI line on ATmega328P (AVR Studio 7), and even ported the code to the new AVR32DB32. It worked fine on the PCB, but when I tested it on a breadboard, it was returning gibberish. I found out that the rise/fall times of the SPI line were too fast for the wiring and caused some major ringing that skewed the communication results. The solution was to add three 330 ohm resistors in series with the MISO, MOSI and CLK lines.

author: TomS_
author_rank: Frequent Contributor
timestamp: October 05, 2022, 07:14:49 am
content: It looks to me like you are changing the output value (wpin) *after* you bring the clock high, whereas the timing diagram suggests the value should change *before* the clock goes high. Each bit is latched into the chip on the rising edge of the clock.This means you are not sending the data you think you are sending.