2017-01-20 30 views
1

Я пытаюсь читать/записывать данные из ST EEPROM M95640-WКаков правильный способ форматирования данных для отправки HAL SPI в STM32?

Acording в техническое описание, для команды данных операций чтения должны быть отформатирована как:

M95640-W Read operation

Первыми является 8-битной инструкцией " Read from Memory Array ": 0x03 (B00000011)

Второй - это 16-разрядный адрес.

Но когда я посылаю команду и данные, которые я получил это:

Адрес 0x0001 (B00000001): M95640 Read from address 0x1

И только проверить позицию данных с зеркальными битами

Адрес 0x0081 (B10000001): M95640 Read from address 0x81


Так что я не могу найти ошибку в своем коде, почему она отправляет данные таким образом. Он отправляет 0x20 команда за исключением 0x03. Он отправляет 0x48 адрес, за исключением 0x01 и 0x80 за исключением 0x81. Похоже, я получил неверный перевод данных между типами uint16_t -> uint8_t *.

Так вот код: инициализация

#define EEPROM_SPI hspi1 
#define EEPROM_READ 0x03 // Read from Memory Array 

/** 
    * @brief Reads a block of data from the EEPROM. 
    * @param pBuffer: pointer to the buffer that receives the data read from the EEPROM. 
    * @param ReadAddr: EEPROM's internal address to read from. 
    * @param NumByteToRead: number of bytes to read from the EEPROM. 
    * @retval None 
    */ 
uint8_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { 
    /*!< Select the EEPROM: Chip Select low */ 
    EEPROM_LED_ON(); 
    EEPROM_CS_LOW(); 

    /*!< Send "Read from Memory" instruction and MSB of WriteAddr */ 
    EEPROM_SendInstruction((uint8_t*)EEPROM_READ, 1); 

    /*!< Send WriteAddr address byte to read from */ 
    EEPROM_SendInstruction((uint8_t*)ReadAddr, 2); 

    if (HAL_SPI_Receive_DMA(&EEPROM_SPI, (uint8_t*)pBuffer, NumByteToRead) != HAL_OK) { 
     Error_Handler(); 
    } 

    /*!< Deselect the EEPROM: Chip Select high */ 
    EEPROM_CS_HIGH(); 
    EEPROM_LED_OFF(); 

    return 0; 
} 

void EEPROM_SendInstruction(uint8_t *instruction, uint8_t size) { 
    while (EEPROM_SPI.State == HAL_SPI_STATE_RESET) { 
     osDelay(1); 
    } 

    if (HAL_SPI_Transmit_DMA(&EEPROM_SPI, (uint8_t*)instruction, (uint16_t)size) != HAL_OK) { 
     Error_Handler(); 
    } 
} 

SPI:

static 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_8BIT; 
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; 
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; 
    hspi1.Init.NSS = SPI_NSS_SOFT; 
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; 
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; 
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE; 
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; 
    hspi1.Init.CRCPolynomial = 7; 

    if (HAL_SPI_Init(&hspi1) != HAL_OK) { 
     Error_Handler(); 
    } 
} 

UPD1: я пакет, как @Guillaume Мишель сказал, и она работала: M95640 Read from address 0x81 Working way

UPD2 Я опубликовал libriary на Github, данные для записи и чтения полностью функциональны. Справки можно ознакомиться с кодом и добавить некоторые новые функции.

ответ

2

Ваш код, кажется, не написан для использования DMA, поэтому не используйте его. Попробуйте использовать HAL_SPI_Receive и HAL_SPI_Transmit вместо HAL_SPI_Receive_DMA и HAL_SPI_Transmit_DMA.

Полярность и фаза кажутся хорошо, но двойная проверка.

Я не уверен, что так вы назвали EEPROM_SendInstruction. Попробуйте это вместо:

uint8_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { 

    uint8_t tmpBuf[2]; 

    /*!< Select the EEPROM: Chip Select low */ 
    EEPROM_LED_ON(); 
    EEPROM_CS_LOW(); 

    /*!< Send "Read from Memory" instruction and MSB of WriteAddr */ 
    tmpBuf[0] = EEPROM_READ; 
    EEPROM_SendInstruction(tmpBuf, 1); 

    /*!< Send WriteAddr address byte to read from */ 
    tmpBuf[0] = (uint8_t)(ReadAddr<<8); 
    tmpBuf[1] = (uint8_t)ReadAddr; 
    EEPROM_SendInstruction(tmpBuf, 2); 

    if (HAL_SPI_Receive_DMA(&EEPROM_SPI, (uint8_t*)pBuffer, NumByteToRead) != HAL_OK) { 
     Error_Handler(); 
    } 

    /*!< Deselect the EEPROM: Chip Select high */ 
    EEPROM_CS_HIGH(); 
    EEPROM_LED_OFF(); 

    return 0; 
} 
+0

Да! Я уже сделал то же самое и решил проблему. В ближайшее время я обновлю вопрос. Спасибо! – Bulkin

+0

Ах. DMA работает, но пока я отключил его, поскольку управлять линией CS сложнее - он должен быть включен и выключен прерываниями. Я проверю его позже. – Bulkin