stm32 и внешняя вспышка W25q16

Я работаю над STM32L432KC с W25Q16. Каждый раз я получаю 0xFF. Согласно таблице данных, чтобы получить код производителя чипа, мне нужно отправить 0x90 и 3 фиктивных байта. Чип должен вернуть 0xEF, 0x17. Но по какой-то причине я получаю 2 байта 0xFF.

SPI_HandleTypeDef hspi1;

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_32;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

#define SPI_SEL2_Pin GPIO_PIN_15
#define SPI_SEL2_GPIO_Port GPIOA
#define ChipSelect()            HAL_GPIO_WritePin(SPI_SEL2_GPIO_Port, SPI_SEL2_Pin, GPIO_PIN_RESET)
#define ChipDeselect()          HAL_GPIO_WritePin(SPI_SEL2_GPIO_Port, SPI_SEL2_Pin, GPIO_PIN_SET)

#define COMMAND_IDENTIFICATION 0x90

uint8_t buffer_tx[4];
uint8_t buffer_rx[2];

uint16_t GetIdentification()
{
    buffer_tx[0] = COMMAND_IDENTIFICATION;
    buffer_tx[1] = 0x0;
    buffer_tx[2] = 0x0;
    buffer_tx[3] = 0x0;

    ChipSelect();
    HAL_SPI_Transmit(&hspi1, buffer_tx, 4, 1000); // send 0x90, 0x0, 0x0, 0x0
    HAL_SPI_Receive(&hspi1, buffer_rx, 2, 1000); // receive 0xFF, 0xFF 
    ChipDeselect();
    return ((uint8_t)buffer_rx[0] << 8) | (uint8_t)buffer_rx[1];
}

int main(void)
{
    MX_SPI1_Init();
    HAL_Delay(1000);
    uint16_t id = GetIdentification();
    printf("Manufacturer ID: 0x%.4X\r\n", id);
    while 
    {
    }   
}

Как я могу это исправить?

schematic


person Raj Kumar    schedule 02.09.2020    source источник
comment
Определены ли ваши вызовы инициализации в другом месте? Куда вы звоните HAL_Init()? или MX_GPIO_Init()?   -  person DaV    schedule 04.09.2020
comment
Да, я это сделал.   -  person Raj Kumar    schedule 11.09.2020


Ответы (1)


Трудно понять, что происходит не так, не имея доступа к настройке вашего оборудования. Похоже, вы на правильном пути, просто держитесь и проверьте все возможные источники ошибок и сузите проблему до чего-то простого и проверяемого. И сначала выясните, возможно, это проблема с оборудованием, а затем попробуйте исправить программное обеспечение.

Некоторые подсказки, которые могут помочь:

  • 0xFF в строке данных SPI (в данном случае DO / MISO), вероятно, означает, что он всегда находится в состоянии HIGH. Таким образом, микросхема флеш-памяти не отвечает на ваши команды. Это может помочь проверить это с помощью логического анализатора, осциллографа или аналогичного устройства во время работы с драйвером. Также проверьте, видны ли ожидаемые биты данных на выводе MOSI, если это возможно. Виден ли CLK?

  • Проверьте все напряжения на контактах с помощью мультиметра. Соответствуют ли измеренные значения ожидаемым? (/ Удерживать контакт?)

  • Был ли вывод GPIO, используемый для выбора микросхемы (PA15), сконфигурирован как выходной вывод? (Также можно сделать в конфигураторе STM32CubeMX.)

    /* configure /CS pin to be an output pin */
    GPIO_InitTypeDef init = {0};
    init.Pin = SPI_SEL2_Pin;
    init.Speed = GPIO_SPEED_FREQ_LOW;
    init.Mode = GPIO_MODE_OUTPUT_PP;
    init.Pull = GPIO_NOPULL;
    if (HAL_GPIO_Init(SPI_SEL2_GPIO_Port, &init) != HAL_OK) {
        Error_Handler();
    }
    ChipDeselect();
    HAL_Delay(100);
  • Правильно ли настроено периферийное устройство SPI? cпроверьте полярность и фазу тактовых импульсов SPI (т.е. hspi1.Init.CLKPolarity и hspi1.Init.CLKPhase), порядок битов (т.е. hspi1.Init.FirstBit (сначала MSB / LSB)) и тактовую частоту (т.е. hspi1.Init. BaudRatePrescaler (начните с низкого значения и при необходимости увеличьте его позже)). Ознакомьтесь с таблицей данных, иногда методом проб и ошибок. тоже может помочь.

  • Флэш-чип может быть отключен. - После беглого взгляда на таблицу, похоже, что есть альтернативная команда для 0x90 с номером инструкции 0xAB, которая называется Release Power-down / Device ID (см. Раздел 9.3.7 в таблице). - Помните, что эта инструкция разбудит чип только при использовании в ее краткой форме, цитируя таблицу:

Чтобы вывести устройство из состояния пониженного энергопотребления, выдается команда, переводя вывод / CS в низкий уровень, сдвигая код команды «ABh» и переводя / CS в высокий уровень, как показано на рисунке 38a. рисунок 38a из таблицы данных W25Q16JV

  • Поищите в Интернете и попробуйте найти похожие драйверы в качестве справочника. Эти микросхемы флэш-памяти Winbond довольно распространены. Как только вы поймете, как считывать идентификатор производителя с флэш-памяти, становится проще интегрировать другие команды / функции в драйвер, шаг за шагом следуя таблице данных. (Также прочтите раздел о регистре состояния и конфигурации (глава 7), биты состояния, вероятно, нужно будет опрашивать во время операций записи позже.) Разделите вещи на небольшие функции, которые можно протестировать индивидуально ...

  • HAL_SPI_TransmitReceive () может быть полезен для отправки и получения данных за один раз.

person rel    schedule 02.09.2020