title: Not able to read from an external EEPROM using the STM32F103C8
body: <p>I'm trying to write and read from an external <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/20001749K.pdf" rel="nofollow noreferrer">EEPROM</a>. There is a start bit (SB) followed by an opcode, then a 6-bit address and then the actual data. I've combined the SB and opcode into one byte that I can send as a start condition. I'm able to enable, erase and then write to the EEPROM. I'm assuming this is working since the HAL functions return HAL_OK and I can see the valid waveforms on the scope. </p>
  
  <p>What I can't seem to do is read the data back. For the READ operation I don't see any waveforms on the scope. The number of clock cycles required is odd-numbered and not in multiples of 8. I don't know how I can send odd number of clock cycles since all the data is either 8, 16 or 32-bit. Wherever there are 25 or 29 clock cycles need, I seem to be sending 32 and where the required cycles are 9, I seem to be sending 16. I'm really hoping to avoid bit-banging as suggested in <a href="https://electronics.stackexchange.com/questions/64927/how-to-write-to-93lc46b-eeprom-from-an-arduino-using-spi">this thread</a>.</p>
  
  <p>Here is the main code:</p>
  
  <pre><code>int main(void)
  {
    HAL_Init();
    MX_GPIO_Init();
    MX_SPI1_Init();
    __HAL_SPI_ENABLE(&amp;hspi1);
  
    // pull the CS pin high to select the EEPROM (active HIGH)
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
    HAL_Delay(10);
  
    // Enable the EEPROM
    enable_status = Enable_EEPROM(&amp;EEPROM_SPI_PORT);
    HAL_Delay(10);
  
    // Erase the value at address 0x00
    erase_status = Erase_EEPROM(&amp;EEPROM_SPI_PORT, addr);
    HAL_Delay(10);
  
    // Write data 0xABCD at addr 0x00
    write_status = Write_EEPROM(&amp;EEPROM_SPI_PORT, addr, tx_data);
    HAL_Delay(10);
  
    // Disabling the EEPROM (with an EWDS) after a WRITE as described in the datasheet
    disable_status = Disable_EEPROM(&amp;EEPROM_SPI_PORT);
    HAL_Delay(10);
  
    // Re-enabling it
    enable_status = Enable_EEPROM(&amp;EEPROM_SPI_PORT);
    HAL_Delay(10);
  
    // Read from the EEPROM. This part isn't working.
    read_status = Read_EEPROM(&amp;EEPROM_SPI_PORT, addr, rx_data);
    HAL_Delay(10);
  
    // Pull the CS pin low to deselect the chip again.
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
  
  
    while (1)
    {
  
    }
  }
  </code></pre>
  
  <p>The SPI is initialized to handle 16-bit data values</p>
  
  <pre><code>SPI_HandleTypeDef hspi1;
  
  /* SPI1 init function */
  void MX_SPI1_Init(void)
  {
  
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(&amp;hspi1) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
  }
  </code></pre>
  
  <p>These are the EEPROM functions</p>
  
  <pre><code>#define ERASE   0x07 // erase specific memory location. This is followed by the 8-bit address and then by the 16-bit data.
  #define READ    0x06 // read the memory location.
  #define WRITE   0x05 // write to the memory location
  
  #define EEPROM_SPI_PORT hspi1
  extern SPI_HandleTypeDef EEPROM_SPI_PORT;
  
  
  //Enable the EEPROM
  //Accepts: SPI handle
  //Returns: Success or failure of the enable operation
  uint8_t Enable_EEPROM (SPI_TypeDef *spi_handle) {
      uint16_t ewen = (0x04 &lt;&lt; 8) | 0b00110000;
      if (HAL_SPI_Transmit(spi_handle, &amp;ewen, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
      else return FALSE;
  }
  
  //Disable the EEPROM
  //Accepts: SPI handle
  //Returns: Success or failure of the disable operation
  uint8_t Disable_EEPROM (SPI_TypeDef *spi_handle) {
      uint16_t ewds = (0x04 &lt;&lt; 8) | 0b00000000;
      if (HAL_SPI_Transmit(spi_handle, &amp;ewds, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
      else return FALSE;
  }
  
  //Read from the EEPROM
  //Accepts: SPI handle, memory address and data buffer where the read value will be stored
  //Returns: Success or failure of read operation
  uint8_t Read_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr, uint16_t data) {
      uint16_t write_package;
      write_package = (READ &lt;&lt; 8 | addr);
  //  if (HAL_SPI_Transmit(spi_handle, &amp;write_package, 1, HAL_MAX_DELAY) == HAL_OK) {
  //      HAL_Delay(10);
  //      if (HAL_SPI_Receive(spi_handle, &amp;data, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
  //      else return FALSE;
  //  }
      if (HAL_SPI_TransmitReceive(spi_handle, &amp;write_package, &amp;data, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
      else return FALSE;
  }
  
  //Write to the EEPROM
  //Accepts: SPI handle, memory address and data to be written
  //Returns: Success or failure of write operation
  uint8_t Write_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr, uint16_t data) {
      uint16_t write_package[2];
      write_package[0] = (WRITE &lt;&lt; 8 | addr);
      write_package[1] = data;
      if (HAL_SPI_Transmit(spi_handle, write_package, 2, HAL_MAX_DELAY) == HAL_OK) return TRUE;
      else return FALSE;
  }
  
  //Erase a specific memory address from the EEPROM
  //Accepts: SPI handle and the memory address to be erased
  //Returns: Success or failure of erase operation
  uint8_t Erase_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr) {
      uint16_t write_package;
      write_package = (ERASE &lt;&lt; 8 | addr);
      if (HAL_SPI_Transmit(spi_handle, &amp;write_package, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
      else return FALSE;
  }
  </code></pre>
  
  <p>EDIT: I’ve attached waveforms here as well. </p>
  
  <p>Enable</p>
  
  <p><a href="https://i.stack.imgur.com/eKSfy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eKSfy.png" alt="enable"></a></p>
  
  <p>Erase</p>
  
  <p><a href="https://i.stack.imgur.com/Z5h8z.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Z5h8z.png" alt="erase"></a></p>
  
  <p>Write </p>
  
  <p><a href="https://i.stack.imgur.com/MYpYL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/MYpYL.png" alt="enter image description here"></a></p>