1

I have a problem. My EEPROM is 93lc66b. I am doing the following to write and after that, read the data.

uint16_t Inst_EWEN = 0x9800;
uint16_t Inst_WRITE = 0xA01F;
uint16_t Inst_Read = 0xC000;
uint16_t dataIn = 2;
uint8_t dataForUart[20];
int messageLength;

//Switch off CS
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(100);

//switch on CS for EWEN
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
HAL_SPI_Transmit(&hspi2, &Inst_EWEN, 1, 1000);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(0.3);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);

HAL_SPI_Transmit(&hspi2, &Inst_WRITE, 1, 1000);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);

///////////////////////////////////////////////////////////////////////////////////

//Switch on CS for read
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);

HAL_SPI_Transmit(&hspi2, &Inst_Read, 1, 1000);

HAL_SPI_Receive(&hspi2, &dataIn, 1, 1000);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
    HAL_Delay(100);
    ///////////////////////////////////////////////////////////////////////////////////

//Send to Uart na UART'a
messageLength = sprintf(&dataForUart,"Read data: %d", dataIn);
HAL_UART_Transmit(&hlpuart1, &dataForUart, messageLength, 1000);`

After executing this function I got 0. I don't know whether I understand the datasheet. First I have to send EWEN operation (1001100000000000 -0x9800). Next Write operation (1010000000011111 - 0xA01F) and next Read operation (1100000000000000 - 0xC000). Maybe I have bad understanding how bits work ?

Sorenp
  • 320
  • 2
  • 12
25pawel
  • 11
  • 1

2 Answers2

1

93lc66 is not an SPI part, it is microwire. If you want to use an SPI interface to access microwire memories then you need to change the clock phase between reading and writing.

Write with CPHA=0, read the response with CPHA=1. Note that you need to disable the peripheral to change the mode.

Also note that the command word length is not necessarily a multiple of 8 bits; you need to pad it on the left with zeros. Your examples above appear to be padding on the right. This is incorrect, it will mean you are misaligned for the data.

Tom V
  • 4,827
  • 2
  • 5
  • 22
0
  1. Assert the CS line, this needs to be pulled high for this device.
  2. Send the EWEN instruction, according to the datasheet the EWEN instruction is 0xC0 so just a single byte.
  3. Write your 16 bit data into an address (256 x 16-bit) according to the datasheet 1 byte address + 2 bytes data
  4. Try to read it back out, by writing the address to DI and observe the data returned on DO (here I'm actually unsure whether or not you need to provide dummy bytes on the input)

Little edit, after reading Tom's answer, I checked the timing diagram of the SPI protocol and the device datasheet, I'm getting a CPOL = 0 and CPHA = 0. Correct me if I'm wrong here Tom :)

Sorenp
  • 320
  • 2
  • 12
  • 1
    DI must be set up T_DIS before the rising edge of CLK and held T_DIH after it (both 100ns at 3.3V). This is CPOL=0 CPHA=0 (SPI mode 0). DO becomes valid T_PD after the rising edge of clock (250ns at 3.3V). Because the STM32 doesn't have programmable setup and hold, the only way I have found to read it reliably is to read it on the falling edge of CLK: CPOL=0 CPHA=1 (SPI mode 1). Fortunately it is never necessary to write and read at the same time and it is safe to stop the peripheral with the clock low to change modes. – Tom V Jul 13 '21 at 08:32
  • Nice one @TomV, I will keep that in mind and leave the edit so others can see it. Thanks! – Sorenp Jul 13 '21 at 08:34