auric 0 13 февраля Опубликовано 13 февраля (изменено) · Жалоба Работаю с EEPROM m95160, вроде все работает, но такое ощущение, что на костылях. Сразу скажу, я не работал со внешними EEPROM, тк устраивал внутренний FLASH у STM32, но тут решил поставить, тк надо чуть ли не по одному байту писать, жалко память. Короче, пишу я разрешение на запись, а судя по документации это должно выглядеть примерно так: EEPROMState m95160_WriteEnable(void){ u8 cmd[] = {M95160_WREN}; //#define M95160_WREN (0x06) // write enable u8 TryCount = 0; while ( M95160_WIP & m95160_ReadStatus() ) { if (TryCount > 60000) return EEPROM_STATUS_PENDING; TryCount++; } EEPROM_Write(cmd,1); return EEPROM_STATUS_COMPLETE; } сама запись байте по SPI условно такая while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //Detect SPI send flag bit (send buffer empty) SPI_I2S_SendData(SPI2, data); //Send data via SPI2 peripheral while(SPI2->SR & SPI_SR_BSY); // Wait for end of Busy flag далее читаю статус уже в ожидании бита WEL (ну статус я читаю и перед отправкой команды M95160_WREN, жду свободного бита WIP "запись идет", хотя если честно может и нет там смысла, но на всякий случай воткнул проверку, число попыток от балды, просто большое, считаем что частота проца 72МГц, ну там порядка 3 мс думаю будет задержка ожидания - не вникал). Но факт я не от балды посылаю команду когда захотел. u8 m95160_ReadStatus(void) { u8 cmd[] = {M95160_RDSR, 0xFF}; //#define M95160_RDSR (0x05) // read status register u8 status[] = {0xFF, 0xFF}; EEPROM_Write_Read(cmd, status, 2); return status[1]; } запись и чтение такое: while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //Detect SPI send flag bit (send buffer empty) SPI_I2S_SendData(SPI2, data); //Send data via SPI2 peripheral while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET); // Wait for end of data receive return ((unsigned char)SPI_I2S_ReceiveData(SPI2)); // Return the received byte from RX Buffer Короче загвоздка в том, что на отладке иногда у меня такая вот процедура выходит по ошибке превышения числа попыток: while ( !(M95160_WEL & m95160_ReadStatus()) ) { if (TryCount > 60000) return EEPROM_STATUS_ERROR; // m95160_WriteEnable(); //включить бит WEL TryCount++; } Если раскоментировать дополнительную посылку команды, то все хорошо, но если оставить только одну команду до этой проверки (а внутри цикла команда остается закомментированной), то в отладке пошагово !!! ИНОГДА!!! я все-таки на второй третьей итерации в цикле попыток прохожу этот While, а если отладку запустить непрерывно до следующей точке останова за циклом, то я выхожу из функции раньше точки останова после цикла стабильно. Отсюда вопрос: Это надо долго ждать (кстати если ставить delay, то хоть 10мс - только хуже работает) или я что-то не так проверяю перед отправкой M95160_WREN ? Короче кто что подскажет? Или нормально так зацикливать что уходит туча команд, какая-нибудь завершится успехом? Опять же смущает момент, что команда M95160_WREN не требует забирать из DR байт данных - я и не делаю этого, а потом читаю статус и забираю соответствующие байты, по идее могу нарваться на то, что принимая байт при чтении, я могу ложно принять старый байт (пока не уверен что это вообще возможно, просто предположил). Может есть смысл пересмотреть процедуру чтения и/или записи без чтения, чтобы хвосты эти чистить? Изменено 13 февраля пользователем auric Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
auric 0 13 февраля Опубликовано 13 февраля (изменено) · Жалоба upd: кстати чистить хвосты командой SPI_I2S_ReceiveData(SPI2)); после записи байта (после проверки SPI_SR_BSY) не помогло. Кстати какая частота шины SPI доступна, не пойму? По таймингам клока SPI вроде около 5МГц. У меня SPI на 2,5МГц настроен, запас вроде есть, на этой настройке достаточно медленный TM1638 работает и ничего не выкаблучивается, в паузы вклиниваюсь я с EEPROM. Изменено 13 февраля пользователем auric Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться