SPI/25L64
About
This article covers how to connect serial SPI flash memory to your Carambola. I use M25P64 flash memory in this case which is 8MB.
Connecting
Building firmware
- Get latest OpenWrt repository and build freshly.
- Enter
make menuconfig
and enable- Kernel modules
- SPI Support
- kmod-spi-dev
- Edit file
nano build_dir/linux-ramips_rt305x/linux-2.6.39.4/arch/mips/ralink/rt305x/mach-carambola.c
- Or if you want to edit before build:
nano target/linux/ramips/files/arch/mips/ralink/rt305x/mach-carambola.c
Replace content with file:
/* * CARAMBOLA board support * * Copyright (C) 2011 Darius Augulis <darius@8devices.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> #include <asm/mach-ralink/machine.h> #include <asm/mach-ralink/rt305x.h> #include <asm/mach-ralink/rt305x_regs.h> #include <asm/sizes.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> #include "devices.h" #ifdef CONFIG_MTD_PARTITIONS static struct mtd_partition carambola_partitions[] = { { .name = "u-boot", .offset = 0, .size = SZ_128K + SZ_64K, }, { .name = "u-boot-env", .offset = MTDPART_OFS_APPEND, .size = SZ_64K, }, { .name = "factory", .offset = MTDPART_OFS_APPEND, .size = SZ_64K, }, { .name = "kernel", .offset = SZ_256K + SZ_64K, .size = SZ_1M, }, { .name = "rootfs", .offset = SZ_256K + SZ_64K + SZ_1M, .size = SZ_4M + SZ_2M, }, { .name = "openwrt", .offset = SZ_256K + SZ_64K, .size = SZ_4M + SZ_2M + SZ_1M, } }; #endif /* CONFIG_MTD_PARTITIONS */ static struct physmap_flash_data carambola_flash_data = { #ifdef CONFIG_MTD_PARTITIONS .nr_parts = ARRAY_SIZE(carambola_partitions), .parts = carambola_partitions, #endif }; static int __init carambola_register_gpiodev(void) { static struct resource res = { .start = 0xFFFFFFFF, }; struct platform_device *pdev; pdev = platform_device_register_simple("GPIODEV", 0, &res, 1); if (!pdev) { printk(KERN_ERR "carambole: GPIODEV init failed\n"); return -ENODEV; } return 0; } static struct i2c_gpio_platform_data carambola_i2c_gpio_data = { .sda_pin = 1, .scl_pin = 2, }; static struct platform_device carambola_i2c_gpio = { .name = "i2c-gpio", .id = 0, .dev = { .platform_data = &carambola_i2c_gpio_data, }, }; #ifdef CONFIG_MTD_PARTITIONS static struct mtd_partition spiflash_partitions[] = { { .name = "data", .offset = 0, .size = 0x800000, /* 8MB flash */ // .mask_flags = MTD_WRITEABLE, } }; #endif /* CONFIG_MTD_PARTITIONS */ static const struct flash_platform_data spiflash_flash = { .type = "w25x64", #ifdef CONFIG_MTD_PARTITIONS .parts = spiflash_partitions, .nr_parts = ARRAY_SIZE(spiflash_partitions), #endif }; static struct spi_board_info __initdata spiflash_spi_slave_info[] = { { .modalias = "m25p80", .platform_data = &spiflash_flash, .irq = -1, .max_speed_hz = 52428800, .bus_num = 0, .chip_select = 0, }, }; static struct platform_device *carambola_devices[] __initdata = { &carambola_i2c_gpio }; static void __init carambola_init(void) { rt305x_gpio_init((RT305X_GPIO_MODE_GPIO << RT305X_GPIO_MODE_UART0_SHIFT) | RT305X_GPIO_MODE_I2C); carambola_register_gpiodev(); platform_add_devices(carambola_devices, ARRAY_SIZE(carambola_devices)); rt305x_register_flash(0, &carambola_flash_data); rt305x_register_spi(spiflash_spi_slave_info, ARRAY_SIZE(spiflash_spi_slave_info)); rt305x_esw_data.vlan_config = RT305X_ESW_VLAN_CONFIG_LLLLW; rt305x_register_ethernet(); rt305x_register_wifi(); rt305x_register_wdt(); rt305x_register_usb(); } MIPS_MACHINE(RAMIPS_MACH_CARAMBOLA, "CARAMBOLA", "CARAMBOLA", carambola_init);
Uploading and testing
- Upload firmware to Carambola
scp test@192.168.0.104:/home/test/carambola_spi_flash/bin/ramips/openwrt-ramips-rt305x-carambola-squashfs-sysupgrade.bin /tmp
Host '192.168.0.104' is not in the trusted hosts file. (fingerprint md5 02:d9:64:44:60:18:5a:c4:e3:15:6f:02:13:e3:20:eb) Do you want to continue connecting? (y/n) y test@192.168.0.104's password: openwrt-ramips-rt305x-carambola-squashfs-sysu 100% 2688KB 1.3MB/s 00:02
- Flash firmware
sysupgrade -v /tmp/openwrt-ramips-rt305x-carambola-squashfs-sysupgrade.bin
Saving config files... etc/sysctl.conf etc/shells etc/rc.local etc/profile etc/passwd etc/inittab etc/hosts etc/group etc/firewall.user etc/dropbear/dropbear_rsa_host_key etc/dropbear/dropbear_dss_host_key etc/config/wireless etc/config/system etc/config/network etc/config/firewall etc/config/dropbear etc/config/dhcp Sending TERM to remaining processes ... syslogd klogd dnsmasq hotplug2 Sending KILL to remaining processes ... Switching to ramdisk... Performing system upgrade... Unlocking firmware ... Writing from <stdin> to firmware ... Appending jffs2 data from /tmp/sysupgrade.tgz to firmware... Writing from <stdin> to firmware ... Upgrade completed Rebooting system... Restarting system.
- Check if Carambola found connected memory
dmesg | grep 25p
m25p80 spi0.0: w25x64 (8192 Kbytes)
- Check for existence of data block:
cat /proc/mtd
dev: size erasesize name mtd0: 00030000 00010000 "u-boot" mtd1: 00010000 00010000 "u-boot-env" mtd2: 00010000 00010000 "factory" mtd3: 000d0000 00010000 "kernel" mtd4: 006e0000 00010000 "rootfs" mtd5: 00530000 00010000 "rootfs_data" mtd6: 007b0000 00010000 "firmware" mtd7: 00800000 00001000 "data"
- If you have fresh chip, probably you want to erase it
mtd erase mtd7
- After this you can mount it and use as regular memory device
mount -t jffs2 /dev/mtdblock7 /mnt