0

I have checked a few bit bang posts here but still couldn't figure it out.

The datasheet of the EEPROM is at: Datasheet of FT93C66A

I tried to interface with SPI but to no avail, so I decided to use bit bang instead. The MCU runs at 50MHz so I also need to add some delay as some posts mentioned.

Configuration:

PA2->SCL, PA4->DO, PA5->DI, PA6->CS, VCC and GND are also linked properly. ORG is disconnected for 16-bit mode.


Initialization of PORT A

  • Because I use bit bang, I only setup PA0 and PA1 for UART to send debugging message to PuTTY;

  • PLL runs at 50MHz;

  • UART part code is tested as correct so I don't show it

void PortA_UART_Init(void){
    // Initiate Port A for UART VCOM communication to PC using PuTTY

    SYSCTL_RCGC1_R |= 0x00000001;       // Activate UART 0 that interfaces PA0 and PA1
                                        // Check page 651 of datasheet - using U1Rx and U1Tx        
    SYSCTL_RCGC2_R |= 0x00000001;       // Activate Port A              
    UART0_CTL_R &= ~0x00000001;         // UART0 module disable, check datasheet page 918
    
    // ----- Initialization -----
    UART0_IBRD_R = 27;                  // IBRD = int(50,000,000/(16*115200)) = int(27.1267)
    UART0_FBRD_R = 8;                   // Fractional part = int(0.1267 * 64 + 0.5) = 8
    UART0_LCRH_R = 0x70;                // Data sheet page 916, 8-bit FIFO, One stop bit, No parity bits
    UART0_CTL_R |= 0x00000001;          // UART0 module enable, datasheet page 918
    GPIO_PORTA_AFSEL_R |= 0x03;         // Enable alternative function for PA1 and PA0 (number 2 is chosen by PCTL)
    GPIO_PORTA_DEN_R |= 0x03;           // Enable PA1 and PA0
    GPIO_PORTA_PCTL_R = 
        (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011;  // Set alternative function 1 for PA1 and PA0
    GPIO_PORTA_AMSEL_R &= ~0x03;        // Disable analog on PA1 and PA0     
}
  • Now I also initiate PA2, 4, 5 and 6 for bit bang:
void PortA_Bit_Bang_Init(void){
    // Initiate Port A for bit bang, no SSI initialization
    // Majority of initialization code for PortA already done

    GPIO_PORTA_DEN_R |= 0x74;           // Enable PA6, PA5, PA4 and PA2, 0111_0100
    GPIO_PORTA_DIR_R |= 0x64;           // PA2, PA5 and PA6 for output
    GPIO_PORTA_AMSEL_R &= ~0x34;        // Disable analog on PA5, PA4 and PA2  
}

Because PPL runs at 50MHz, while EEPROM runs around 1-2MHz, I manually added a lot of delay code using a timer. The delay works well so I don't post the code here.

My question: Is the following pseudo code correct for EWEN?

  • EWEN: Must be sent before any operation: Send 100 followed by 11XXXXXX (I choose 11000000) so total of 11 bits. This is also the reason I choose to use bit bang, because standard SPI uses 16 bit FIFO. The EEPROM also needs 27 bits for writing under 16-bit mode.I have no idea how to use the FIFO to do this.

Timing graph: Timing graph

Pseudo code:

CS High
Clock Low
Delay for 1ms
// Send start bit and OpCode - 100
PA5 High (PA5 connects with EEPROM's DI) - this is sending 1
Delay for 1ms
Clock High
Delay for 1ms
Clock Low
Delay for 1ms
PA5 Low - this is sending 0
Delay for 1ms
Clock High
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA keeps low for the second 0
Delay for 1ms
Clock Low
Delay for 1ms
Delay for 1ms

// Send 1100_0000
PA5 High - Send 1
Delay for 1ms
Clock High
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps to be high for the second 1
Delay for 1ms
Clock Low
Delay for 1ms
PA5 Low - this is sending 0
Delay for 1ms
Clock High
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps low for second 0
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps low for third 0
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps low for fourth 0
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps low for fifth 0
Delay for 1ms
Clock Low
Delay for 1ms
Clock High - PA5 keeps low for last 0
Delay for 1ms
Clock Low
Delay for 1ms

// Pull down CS
CS Low
Delay for 1ms
CS High
```
  • 1
    First up, get yourself a cheapy usb logic analyser - they’re around $10 USD. Actually, get yourself a couple. With one of these you’ll see exactly what is happening in the interface to the eeprom. Secondly, why are you using these old serial eeproms? Surely you can use an internal flash sector to store data? Anyway, at a quick glance I can’t see anything glaringly wrong. You might want to post your actual code. Personally I’d suggest using a serial flash - heaps more storage and can be used for storing firmware update images or an I2C eeprom. – Kartman Feb 07 '22 at 00:40
  • Hi @Kartman thanks for the reply. Yeah I'll get a logic analyzer quickly as I'm totally blind here. The reason I'm using serial eeproms is because, eh, I'm trying to repurpose the tiva launchpad as a rom writer/reader/eraser (kinda build one's own birdfeeder project). This is just for practice thus 1) I purchase random roms, and 2) No library is used. I'm trying SSI interfacing again (because without a logic analyzer I'm really blind) but will post the bit-banging EWEN code shortly. – Nicholas Humphrey Feb 07 '22 at 00:53
  • 1
    @NicholasHumphrey The easiest way (not the most readable way, but the easiest to get right and working) is a state machine driven by a timer. You can set the timer frequency as you see fit (looks like it can be as bad as 250 kHz or as high as 2 MHz.) But I'd shoot initially for 250-500 kHz or less before I would shoot the moon and go for higher speeds. You want things to work, not necessarily work fast, on the first go. Also, I agree with Kartman about ***any*** logic analyzer. Get one. But state machines are dirt-easy to code and bullet-proof. I'd start there. – jonk Feb 07 '22 at 01:58
  • 1
    @NicholasHumphrey Set down with a piece of paper and the datasheet and then look over every single one of the commands and queries available to you. Look at how things are started, how the opcode is transmitted, the following data groups, and how the session is terminated (CS goes low and, it appears, one added clock once that happens... though you should decide for yourself about that.) You can work out the details on paper and organize them. Once you do that, it's trivial to implement. Each state transitions to the next or else returns to the IDLE state. It's not overly complex to do this. – jonk Feb 07 '22 at 07:34
  • @jonk thanks! I'll print it out and take a closer look. I think the difference in speed confused me quite a bit, to the point that I added a delay for every command. The state machine idea looks interesting although I never implemented one myself. There is a chapter for state machine in the book I'm reading so should be good. – Nicholas Humphrey Feb 07 '22 at 14:15
  • 1
    @NicholasHumphrey There is some subtlety to developing a good state machine for 3-wire. And that's usually the crux of making it "simple" vs "complicated" as well as between making it versatile for other devices and commands and queries that you may find in future devices and having it have to undergo changes every time you meet something new. The "Start Bit" is one of those subtle issues. If you can imagine the start bit correctly and well, then the rest just "flows out of that, nicely." If you incorporate too much knowledge into the start bit, the rest is always a mess. Just some advice. – jonk Feb 07 '22 at 18:45
  • 1
    @NicholasHumphrey I also very highly recommend a book called "XINU" by Douglas Comer. Don't buy ANY of the newer books. Go straight back to the very first one he wrote, circa 1983. It will have a RED cover. In it, he discusses a concept called a "delta queue." This queue is perhaps the most useful embedded technique to learn. It's very simple and remarkably useful. Combined with the SPI state machine and a single periodic timer, the entire SPI state machine can run simply and flawlessly in the background, yet callable from the foreground main code. It's pure beauty of SPI motion in action. – jonk Feb 07 '22 at 18:48
  • 1
    @NicholasHumphrey Bit-banging 3-wire for embedded use, without the need for an operating system per se but only a very simple tool from one, is something that should be developed into a very educational lesson plan. It would start with the basics of just learning to use interrupts, state machine concepts in C, delta-queue in C, and culminate in a versatile library that "just works right" for a wide variety of devices and is simple to use and robust and solid as a rock. As good as if you had a hardware peripheral designed to handle a wide variety of 3-wire devices. It just sings like a melody. – jonk Feb 07 '22 at 18:54
  • Hi @jonk thanks a lot for the comments, especially for the recommendation of XINU as I'd never know about it if not for your recommendation. Regarding bit bang and state machine, my most recent adventure was to use bit bang the last time without state machine while waiting for the logic analyzer, which was a failure. I wired a LED for some crude observation but that definitely does not work as well as a logic analyzer. My next try is going to be with state machine hopefully, once I figure out the speed issue. I suspect maybe I delayed too much? Not really sure. Thanks again for the help! – Nicholas Humphrey Feb 09 '22 at 02:29
  • 1
    @NicholasHumphrey DO NOT use delays. Set up a timer. It "just works." A software delay is the (almost) worst way to go. – jonk Feb 09 '22 at 03:23
  • Yes I'm using a timer for delays. Would that be good enough? – Nicholas Humphrey Feb 09 '22 at 03:57

0 Answers0