w5100 Shield не может инициализировать Ethe rnet, когда вставлена ​​определенная SD-карта - PullRequest
0 голосов
/ 17 июня 2020

Arduino IDE 1.8.9 macOS, Ethe rnet lib 2.0.0, SD lib 1.2.4

Atmega2560 + Ethe rnet Shield w5100

Возникла странная проблема. Мой w5100 Shield не может настроить сеть, если вставлена ​​часть SD-карт, в то время как другие SD-карты не вызывают проблем. Все SD-карты имеют размер 256 МБ и отформатированы с помощью SDFormatter. SD-карта сама по себе работает правильно в обоих случаях.

Проблема может быть воспроизведена с помощью простого наброска:

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h> 

#define PIN_SD 4

void setup() {
  
  Serial.begin(115200);

  if (!SD.begin(PIN_SD)) {
    Serial.println("SD fail");
  }

  pinMode(PIN_SD, OUTPUT);
  digitalWrite(PIN_SD, HIGH);

  byte mac[6] = {0x52, 0xa0, 0xe9, 0x90, 0x47, 0x28};
  if (Ethernet.begin(mac)) {
    Serial.println(Ethernet.localIP());
  }
  else
  {
    Serial.println("Net Fail");
  }
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

Я попытался детализировать проблему и обнаружил проблема исходит от W5100Class::softReset() в w5100.cpp. Мягкий сброс запускается во время init (), и функция не может получить ожидаемое значение из MR (Регистр режима).

Чтобы прояснить, я ввел несколько выходов в softReset(void) следующим образом:

// Soft reset the Wiznet chip, by writing to its MR register reset bit
uint8_t W5100Class::softReset(void)
{
 uint16_t count=0;

 Serial.println("Wiznet soft reset");
 Serial.println(readMR(), HEX);
 // write to reset bit
 writeMR(0x80);
 // then wait for soft reset to complete
 do {
 uint8_t mr = readMR();
 Serial.print("mr=");
 Serial.println(mr, HEX);
 if (mr == 0) return 1;
 delay(1);
 } while (++count < 20);
 return 0;
}

Вот последовательные выходы с хорошей SD-картой.

w5100 init
Wiznet soft reset
0
mr=0
Wiznet soft reset
0
mr=0
w5100.cpp: detect W5100 chip
Wiznet soft reset
0
mr=0
chip is W5100
w5100 found
172.10.0.70

Вот последовательные выходы с проблемной c SD-картой.

w5100 init
Wiznet soft reset
FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
Wiznet soft reset
FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
w5100.cpp: detect W5100 chip
Wiznet soft reset
FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
mr=FF
Net Fail

В ненормальном состоянии case, MR остается 0xff около мягкого сброса.

Есть идеи по этому поводу?

Кажется, инициализация SD-карты вызывает повреждение / переполнение где-то в памяти. Пытался выяснить разницу между 2 группами SD карт. На данный момент:

  • Если файлы копируются с ma c на SD-карту с помощью того же адаптера, гораздо быстрее записывать BAD-карту.
  • С дополнительным выводом в SD lib, Я обнаружил, что ХОРОШИЕ карты - это SD_CARD_TYPE_SD2, а плохие карты - SD_CARD_TYPE_SD1. Поскольку нет достаточного количества образцов (фактическое-3, 2 ПЛОХО, 1 ХОРОШО), я не могу сказать, что это ключевой момент.

Sd2Card.h

/** Standard capacity V1 SD card */
uint8_t const SD_CARD_TYPE_SD1 = 1;
/** Standard capacity V2 SD card */
uint8_t const SD_CARD_TYPE_SD2 = 2;
/** High Capacity SD card */
uint8_t const SD_CARD_TYPE_SDHC = 3;

Обновить 20200701:

У меня есть другие SD-карты для тестирования. Оказывается, SD_CARD_TYPE_SD1 не имеет значения, поскольку некоторые ХОРОШИЕ карты имеют SD_CARD_TYPE_SD1.

Похоже, проблема возникает только с картами с одинаковым чипом / партией. Параметры файловой системы точно такие же. Так может быть проблема с SD-чипом ...

Card type:         SD1
Clusters:          15608
Blocks x Cluster:  32
Total Blocks:      499456

Volume type is:    FAT16
Volume size (Kb):  249728
Volume size (Mb):  243
Volume size (Gb):  0.24

обновление 20200703

Проблема на самом деле из Sd2Card::init() в файле Sd2Card.cpp

  while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
    unsigned int d = millis() - t0;
    if (d > SD_INIT_TIMEOUT) {
      error(SD_CARD_ERROR_CMD0);
      goto fail;
    }
  }

Пока cardCommand(CMD0, 0) вызывается с ПЛОХОЙ SD-карты, rnet не сработает.

...