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 menuconfigand 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