Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
| ru:toh:tp-link:tl-mr3420:deep.mmc.hack [2016/01/18 09:06] – [Способ подключения] Dioptimizer | ru:toh:tp-link:tl-mr3420:deep.mmc.hack [2018/02/17 19:15] – ↷ Links adapted because of a move operation | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Расширенный моддинг MMC ====== | ||
| + | ===== Способ подключения ===== | ||
| + | | {{media: | ||
| + | | {{media: | ||
| + | |||
| + | // | ||
| + | |||
| + | Существует два способа модификации с использованием разных GPIO для CS1, а также два варианта установки необходимого ПО для непосредственного использования карточки памяти подключенной к устройству.\\ | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | **Более подробно мод расписан в соседней [[toh: | ||
| + | ===== Подключение MMC/SD карты памяти к шине spi0.1 ===== | ||
| + | |||
| + | ==== Основные изменения в прошивке ==== | ||
| + | |||
| + | < | ||
| + | === Вариант GPIO как CS1 === | ||
| + | В качестве CS для MMC/SD карты памяти, | ||
| + | |||
| + | == Использование GPIO 7 - как CS1 для общей шины: == | ||
| + | <code diff> | ||
| + | Index: target/ | ||
| + | =================================================================== | ||
| + | --- target/ | ||
| + | +++ target/ | ||
| + | @@ -50,7 +50,7 @@ | ||
| + | void __init ath79_register_m25p80(struct flash_platform_data *pdata) | ||
| + | { | ||
| + | | ||
| + | - ath79_spi_data.num_chipselect = 1; | ||
| + | + ath79_spi_data.num_chipselect = 2; | ||
| + | | ||
| + | | ||
| + | | ||
| + | Index: target/ | ||
| + | =================================================================== | ||
| + | --- target/ | ||
| + | +++ target/ | ||
| + | @@ -9,6 +9,9 @@ | ||
| + | */ | ||
| + | |||
| + | # | ||
| + | +#include < | ||
| + | +#include < | ||
| + | +#include < | ||
| + | |||
| + | # | ||
| + | |||
| + | @@ -16,12 +19,14 @@ | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | +#include " | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | +#define TL_MR3X20_GPIO_CS1_MMC 7 | ||
| + | # | ||
| + | |||
| + | # | ||
| + | @@ -32,6 +37,26 @@ | ||
| + | # | ||
| + | # | ||
| + | |||
| + | +static struct mmc_spi_platform_data ath79_mmc_data = { | ||
| + | + | ||
| + | + | ||
| + | + | ||
| + | + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct ath79_spi_controller_data ath79_spi1_cdata = { | ||
| + | + .cs_type = ATH79_SPI_CS_TYPE_GPIO, | ||
| + | + .cs_line = TL_MR3X20_GPIO_CS1_MMC, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct spi_board_info ath79_spi_info[] = { | ||
| + | + { | ||
| + | + .bus_num = 0, | ||
| + | + .chip_select = 1, | ||
| + | + .max_speed_hz = 25000000, | ||
| + | + .modalias = " | ||
| + | + .platform_data = & | ||
| + | + .controller_data = & | ||
| + | + } | ||
| + | +}; | ||
| + | + | ||
| + | | ||
| + | | ||
| + | | ||
| + | @@ -97,6 +122,9 @@ | ||
| + | | ||
| + | |||
| + | | ||
| + | + | ||
| + | + spi_register_board_info(ath79_spi_info, | ||
| + | + ARRAY_SIZE(ath79_spi_info)); | ||
| + | } | ||
| + | |||
| + | | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | === Вариант Internal CS1 === | ||
| + | |||
| + | ^ Internal CS ^ AR724X ^ AR933X ^ | ||
| + | | CS1 | QSS LED (GPIO0) | UART In (GPIO9) | | ||
| + | | CS2 | SYS LED (GPIO1) | UART Out (GPIO10) | | ||
| + | На устройствах AR724X: Для того, чтобы использовать внутренний CS1 - необходимо [[# | ||
| + | |||
| + | На устройствах AR933X: Для того, чтобы использовать внутренний CS1 - необходимо [[# | ||
| + | |||
| + | <code diff> | ||
| + | Index: target/ | ||
| + | =================================================================== | ||
| + | --- target/ | ||
| + | +++ target/ | ||
| + | @@ -50,7 +50,7 @@ | ||
| + | void __init ath79_register_m25p80(struct flash_platform_data *pdata) | ||
| + | { | ||
| + | | ||
| + | - ath79_spi_data.num_chipselect = 1; | ||
| + | + ath79_spi_data.num_chipselect = 2; | ||
| + | | ||
| + | | ||
| + | | ||
| + | Index: target/ | ||
| + | =================================================================== | ||
| + | --- target/ | ||
| + | +++ target/ | ||
| + | @@ -9,13 +9,19 @@ | ||
| + | */ | ||
| + | |||
| + | # | ||
| + | +#include < | ||
| + | +#include < | ||
| + | +#include < | ||
| + | |||
| + | # | ||
| + | +#include < | ||
| + | |||
| + | +#include " | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | +#include " | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | @@ -32,6 +38,26 @@ | ||
| + | # | ||
| + | # | ||
| + | |||
| + | +static struct mmc_spi_platform_data ath79_mmc_data = { | ||
| + | + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct ath79_spi_controller_data ath79_spi1_cdata = { | ||
| + | + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, | ||
| + | + .cs_line = 1, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct spi_board_info ath79_spi_info[] = { | ||
| + | + { | ||
| + | + .bus_num = 0, | ||
| + | + .chip_select = 1, | ||
| + | + .max_speed_hz = 25000000, | ||
| + | + .modalias = " | ||
| + | + .platform_data = & | ||
| + | + .controller_data = & | ||
| + | + } | ||
| + | +}; | ||
| + | + | ||
| + | | ||
| + | | ||
| + | | ||
| + | @@ -80,6 +106,9 @@ | ||
| + | u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); | ||
| + | u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); | ||
| + | |||
| + | + /* Enabling internal CS1, disable GPIO 0 */ | ||
| + | + ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1); | ||
| + | + | ||
| + | | ||
| + | |||
| + | | ||
| + | @@ -97,6 +126,9 @@ | ||
| + | | ||
| + | |||
| + | | ||
| + | + | ||
| + | + spi_register_board_info(ath79_spi_info, | ||
| + | + ARRAY_SIZE(ath79_spi_info)); | ||
| + | } | ||
| + | |||
| + | | ||
| + | </ | ||
| + | |||
| + | == Переключение GPIO0 (QSS LED) в CS1 на AR724X: == | ||
| + | |||
| + | <code c> | ||
| + | /* Enabling internal CS1, disable GPIO 0 */ | ||
| + | ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1); | ||
| + | </ | ||
| + | //(Уже используется в верхнем примере.)// | ||
| + | |||
| + | == Отключение UART и переключение GPIO 9(Rx) в CS1 на AR933X: == | ||
| + | <code c> | ||
| + | /* Disable UART, enabling GPIO 9 and GPIO 10 */ | ||
| + | ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_EN); | ||
| + | /* Enabling internal CS1, disable GPIO 9 */ | ||
| + | ath79_gpio_function_enable(AR933X_GPIO_FUNC_SPI_CS_EN1); | ||
| + | </ | ||
| + | \\ | ||
| + | === Реализация подключение/ | ||
| + | {{http:// | ||
| + | |||
| + | // | ||
| + | |||
| + | Всего используем два свободных GPIO7-> | ||
| + | Создаем дополнительную кнопку по примеру: | ||
| + | <code diff> | ||
| + | diff --git a/ | ||
| + | index 9323b31..2c51142 100644 | ||
| + | --- a/ | ||
| + | +++ b/ | ||
| + | @@ -50,7 +50,7 @@ static struct ath79_spi_platform_data ath79_spi_data; | ||
| + | void __init ath79_register_m25p80(struct flash_platform_data *pdata) | ||
| + | { | ||
| + | | ||
| + | - ath79_spi_data.num_chipselect = 1; | ||
| + | + ath79_spi_data.num_chipselect = 2; | ||
| + | | ||
| + | | ||
| + | | ||
| + | diff --git a/ | ||
| + | index 5924ac5..892d66f 100644 | ||
| + | --- a/ | ||
| + | +++ b/ | ||
| + | @@ -9,6 +9,9 @@ | ||
| + | */ | ||
| + | |||
| + | # | ||
| + | +#include < | ||
| + | +#include < | ||
| + | +#include < | ||
| + | |||
| + | # | ||
| + | |||
| + | @@ -17,21 +20,45 @@ | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | +#include " | ||
| + | # | ||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | +#define TL_MR3X20_GPIO_CS1_MMC 7 | ||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | +#define TL_MR3X20_GPIO_BTN_MMC 18 | ||
| + | |||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | |||
| + | +static struct mmc_spi_platform_data ath79_mmc_pdata = { | ||
| + | + .detect_delay = 250, /* card detection delay in msec */ | ||
| + | + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct ath79_spi_controller_data ath79_spi1_cdata = { | ||
| + | + .cs_type = ATH79_SPI_CS_TYPE_GPIO, | ||
| + | + .cs_line = TL_MR3X20_GPIO_CS1_MMC, | ||
| + | +}; | ||
| + | + | ||
| + | +static struct spi_board_info ath79_spi_info[] __initdata = { | ||
| + | + { | ||
| + | + .bus_num = 0, | ||
| + | + .chip_select = 1, | ||
| + | + .max_speed_hz = 25000000, | ||
| + | + .modalias = " | ||
| + | + .platform_data = & | ||
| + | + .controller_data = & | ||
| + | + } | ||
| + | +}; | ||
| + | + | ||
| + | | ||
| + | | ||
| + | | ||
| + | @@ -72,6 +99,13 @@ static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { | ||
| + | | ||
| + | | ||
| + | | ||
| + | + }, { | ||
| + | + .desc = " | ||
| + | + .type = EV_KEY, | ||
| + | + .code = KEY_MMC_BUTTON, | ||
| + | + .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, | ||
| + | + .gpio = TL_MR3X20_GPIO_BTN_MMC, | ||
| + | + .active_low = 1, | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | @@ -97,6 +131,9 @@ static void __init tl_ap99_setup(void) | ||
| + | | ||
| + | |||
| + | | ||
| + | + | ||
| + | + spi_register_board_info(ath79_spi_info, | ||
| + | + ARRAY_SIZE(ath79_spi_info)); | ||
| + | } | ||
| + | |||
| + | | ||
| + | </ | ||
| + | |||
| + | После компиляции, | ||
| + | Далее, необходимо создать [[docs: | ||
| + | <code bash> | ||
| + | uci add system button | ||
| + | uci set system.@button[-1].button=mmc | ||
| + | uci set system.@button[-1].action=pressed | ||
| + | uci set system.@button[-1].handler=' | ||
| + | uci add system button | ||
| + | uci set system.@button[-1].button=mmc | ||
| + | uci set system.@button[-1].action=released | ||
| + | uci set system.@button[-1].handler=' | ||
| + | uci commit system | ||
| + | </ | ||
| + | |||
| + | **Примечание: | ||
| + | |||
| + | == Подключение/ | ||
| + | < | ||
| + | <pre class=" | ||
| + | ... | ||
| + | [ 1968.380000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff | ||
| + | [ 1968.550000] mmc0: SD Status: Invalid Allocation Unit size. | ||
| + | [ 1968.560000] mmc0: host does not support reading read-only switch. assuming write-enable. | ||
| + | [ 1968.570000] mmc0: new SD card on SPI | ||
| + | [ 1968.570000] mmcblk0: mmc0:0000 00000 1.90 GiB | ||
| + | [ 1968.580000] | ||
| + | < | ||
| + | [ 2008.900000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff | ||
| + | [ 2009.070000] mmc0: SD Status: Invalid Allocation Unit size. | ||
| + | [ 2009.080000] mmc0: host does not support reading read-only switch. assuming write-enable. | ||
| + | [ 2009.090000] mmc0: new SD card on SPI | ||
| + | [ 2009.090000] mmcblk0: mmc0:0000 00000 1.90 GiB | ||
| + | [ 2009.100000] | ||
| + | ... | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | === Модули === | ||
| + | < | ||
| + | {{: | ||
| + | |||
| + | **Обновление: | ||
| + | Для [[doc: | ||
| + | \\ | ||
| + | < | ||
| + | == На уровне ядра (kernel): == | ||
| + | <code diff> | ||
| + | Index: target/ | ||
| + | =================================================================== | ||
| + | --- target/ | ||
| + | +++ target/ | ||
| + | @@ -240,6 +240,10 @@ | ||
| + | # CONFIG_SPI_RB4XX is not set | ||
| + | # CONFIG_SPI_RB4XX_CPLD is not set | ||
| + | # CONFIG_SPI_VSC7385 is not set | ||
| + | +CONFIG_EXT4_FS=y | ||
| + | +CONFIG_MMC=y | ||
| + | +CONFIG_MMC_SPI=y | ||
| + | +CONFIG_MMC_BLOCK=y | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | // | ||
| + | Также следует учесть, | ||
| + | В конечном счете, если ядро Trank' | ||
| + | |||
| + | Интеграция необходимых модулей в ядро, позволяет использовать обнаруженную карточку памяти на ровне с флеш-памятью.\\ | ||
| + | При этом, можно использовать карточку памяти в качестве расширенной файловой системы - [[doc: | ||
| + | \\ | ||
| + | |||
| + | ==== Измерения ==== | ||
| + | |||
| + | == Тест скоростей spi0.1: == | ||
| + | Скорость чтения/ | ||
| + | < | ||
| + | root@OpenWrt: | ||
| + | 14+0 records in | ||
| + | 14+0 records out | ||
| + | 14680064 bytes (15 MB) copied, 20.9663 s, 700 kB/s | ||
| + | root@OpenWrt: | ||
| + | 14+0 records in | ||
| + | 14+0 records out | ||
| + | 14680064 bytes (15 MB) copied, 25.2994 s, 580 kB/s | ||
| + | root@OpenWrt: | ||
| + | </ | ||
| + | |||
| + | Результат утилиты **hdparm**: | ||
| + | < | ||
| + | root@OpenWrt: | ||
| + | |||
| + | / | ||
| + | | ||
| + | | ||
| + | root@OpenWrt: | ||
| + | </ | ||
| + | |||
| + | == Нагрузка на CPU во время чтения/ | ||
| + | < | ||
| + | <pre class=" | ||
| + | root@OpenWrt: | ||
| + | Mem: 28224K used, 1120K free, 0K shrd, 5784K buff, 5592K cached | ||
| + | CPU: 0% usr <font color=" | ||
| + | Load average: 1.21 0.88 0.60 2/60 28540 | ||
| + | PID PPID USER | ||
| + | | ||
| + | | ||
| + | 559 2 root | ||
| + | ... | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | **Итог: | ||
| + | |||
| + | == Тест одновременного использования spi0.0 и spi0.1: == | ||
| + | Здесь стоит уточнить способ выполнения теста. \\ | ||
| + | Посылается две параллельные команды чтение\запись с разделительным command оператором "''&''" | ||
| + | |||
| + | Результат следующий: | ||
| + | |||
| + | == Питание: | ||
| + | ^ Режим ^ Значение ^ | ||
| + | | Спящий режим (простой) | ~1mA | | ||
| + | | Чтение данных | ~18mA | | ||
| + | | Запись данных | ~23mA | | ||
| + | |||
| + | ==== Логи ==== | ||
| + | |||
| + | == Лог загрузки и инициализации карточки: | ||
| + | < | ||
| + | <pre class=" | ||
| + | ... | ||
| + | < | ||
| + | [ 0.740000] m25p80 spi0.0: found en25f32, expected m25p80 | ||
| + | [ 0.750000] m25p80 spi0.0: en25f32 (4096 Kbytes) | ||
| + | [ 0.750000] 5 tp-link partitions found on MTD device spi0.0 | ||
| + | [ 0.760000] Creating 5 MTD partitions on " | ||
| + | [ 0.760000] 0x000000000000-0x000000020000 : " | ||
| + | [ 0.770000] 0x000000020000-0x00000013de00 : " | ||
| + | [ 0.770000] mtd: partition " | ||
| + | [ 0.790000] 0x00000013de00-0x0000003f0000 : " | ||
| + | [ 0.790000] mtd: partition " | ||
| + | [ 0.810000] mtd: partition " | ||
| + | [ 0.810000] mtd: partition " | ||
| + | [ 0.820000] 0x000000370000-0x0000003f0000 : " | ||
| + | [ 0.830000] 0x0000003f0000-0x000000400000 : " | ||
| + | [ 0.840000] 0x000000020000-0x0000003f0000 : " | ||
| + | [ 0.860000] libphy: ag71xx_mdio: | ||
| + | [ 0.860000] eth0: Atheros AG71xx at 0xba000000, irq 5, mode:GMII | ||
| + | [ 1.420000] eth0: Found an AR7240/ | ||
| + | [ 2.450000] eth1: Atheros AG71xx at 0xb9000000, irq 4, mode:MII | ||
| + | [ 3.000000] ag71xx ag71xx.0 eth1: connected to PHY at ag71xx-mdio.1: | ||
| + | < | ||
| + | [ 3.060000] TCP: cubic registered | ||
| + | [ 3.060000] NET: Registered protocol family 17 | ||
| + | [ 3.070000] 8021q: 802.1Q VLAN Support v1.8 | ||
| + | [ 3.080000] VFS: Mounted root (squashfs filesystem) readonly on device 31:2. | ||
| + | [ 3.090000] Freeing unused kernel memory: 268k freed | ||
| + | < | ||
| + | [ 3.320000] mmc0: new SD card on SPI | ||
| + | [ 3.480000] mmcblk0: mmc0:0000 00000 1.90 GiB | ||
| + | [ 3.490000] | ||
| + | ... | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | == Вид ошибки в случае НЕ обнаружения карточки памяти на уровне ядра: == | ||
| + | < | ||
| + | ... | ||
| + | [ 6.070000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff | ||
| + | ... | ||
| + | [ 8.710000] mmc0: error -145 whilst initialising SD card | ||
| + | ... | ||
| + | [ | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | |||
| + | == Обнаруженные разделы: | ||
| + | < | ||
| + | <pre class=" | ||
| + | root@OpenWrt: | ||
| + | <font color=" | ||
| + | root@OpenWrt: | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | == Debug информация: | ||
| + | < | ||
| + | root@OpenWrt: | ||
| + | clock: | ||
| + | vdd: 20 (3.2 ~ 3.3 V) | ||
| + | bus mode: 2 (push-pull) | ||
| + | chip select: | ||
| + | power mode: 2 (on) | ||
| + | bus width: | ||
| + | timing spec: 0 (legacy) | ||
| + | signal voltage: 1 (3.30 V) | ||
| + | root@OpenWrt: | ||
| + | </ | ||
| + | |||
| + | ===== Обсуждение на форуме ===== | ||
| + | |||
| + | [[https:// | ||