Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Hi,
wie kriege ich den SPI-Bus unter dem aktuellen Openwrt (backfire) mit
GPIOs zum Laufen? Wo finde ich Einstellungen zu den verwendeten GPIOs,
oder eine zugehörige Doku?
Openwrt kompiliert, kmod-spi-bitbang, kmod-spi-dev, kmod-spi-gpio und
spidev-test sind fest eingebaut, scheinen aber kein device zu erzeugen.
Hardware: Edimax BR-6104KP
VG
Weiß nicht, ob es noch aktuell ist. Die Infos findet man im Quellcode
(spi_gpio.c). Gibt also 2 Möglichkeiten:
1.: entsprechende platform_data in deiner
arch/mips/adm5120/edimax/br-6104kp.c definieren. Näheres dazu beschreibt
auch die Datei include/linux/spi/spi_gpio.h. Komplettes Image neu bauen.
2.: in spi_gpio.c gleich folgende Sachen auskommentieren und auf deine
GPIO-Nummern ändern:
* #define DRIVER_NAME "myboard_spi2"
* #define SPI_MISO_GPIO 119
* #define SPI_MOSI_GPIO 120
* #define SPI_SCK_GPIO 121
* #define SPI_N_CHIPSEL 4
* #include "spi_gpio.c"
Also das abschließende */ entsprechend vor die erste Zeile hier
verschieben und die Zeichen vor der Raute entfernen. Dann müsste man
eigentlich nur noch diese Datei kompilieren.
Hallo ALrK3uMW,
bist du schon weiter... ich versuche nun seit ein paar Tagen SPI am
WGT634 zum laufen zu bringen. Und habe zur Zeit die "selbe" Frage / bin
auf dem selben Stand wie du.
-alex
Hallo,
ich habe ein CAN-Bus Controller mit einem BR-6104K (SoC ADM5120)
verbunden. Über SPI kann ich den Controller initialisieren:
BusyBox v1.19.3 (2012-04-0512:15:53 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
ATTITUDE ADJUSTMENT (bleeding edge, r30857) ----------
root@OpenWrt:/# uname -a
Linux OpenWrt 3.1.10#6 Thu Apr 516:39:22 CEST 2012 mips GNU/Linux
root@OpenWrt:/# insmod mcp251x
root@OpenWrt:/# cat /sys/kernel/debug/gpio
GPIOs 0-3, adm5120 gpio0:
gpio-2 (MCP251x CAN INT ) in hi
GPIOs 8-22, adm5120 gpio1:
gpio-17 (spi_gpio.1 ) in lo
gpio-18 (spi_gpio.1 ) out lo
gpio-20 (spi_gpio.1 ) out lo
gpio-21 (spi1.0 ) out hi
root@OpenWrt:/# insmod mcp251x
[ 368.736000] mcp251x spi1.0: probed
root@OpenWrt:/# ip link set can0 type can bitrate 125000 loopback on
root@OpenWrt:/# ifconfig can0 up
[ 402.324000] mcp251x spi1.0: CNF: 0x030xb50x01
root@OpenWrt:/# ip -details link show can0
10: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
link/can
can <LOOPBACK> state ERROR-ACTIVE restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
root@OpenWrt:/# cat /sys/kernel/debug/gpio
GPIOs 0-3, adm5120 gpio0:
gpio-2 (MCP251x CAN INT ) in hi
GPIOs 8-22, adm5120 gpio1:
gpio-17 (spi_gpio.1 ) in lo
gpio-18 (spi_gpio.1 ) out lo
gpio-20 (spi_gpio.1 ) out lo
gpio-21 (spi1.0 ) out hi
root@OpenWrt:/# cat /proc/interrupts
CPU0
2: 0 MIPS cascade [INTC]
7: 33933 MIPS timer
9: 2477 INTC uart-pl010
12: 0 INTC mcp251x
17: 614 INTC eth0, eth1
ERR: 0
root@OpenWrt:/# dmesg | tail -5
[ 368.732000] mcp251x spi1.0: CANSTAT 0x80 CANCTRL 0x07
[ 368.736000] mcp251x spi1.0: probed
[ 402.308000] mcp251x spi1.0: INTC_REG_IRQ_ENABLE = 0x212
[ 402.308000] mcp251x spi1.0: GPIO2 IRQ initialized
[ 402.324000] mcp251x spi1.0: CNF: 0x030xb50x01
Sieht soweit gut aus, aber es wird kein IRQ ausgelöst, wenn ich eine CAN
Nachricht sende:
root@OpenWrt:/# cansend can0 123#DEADBEEF
root@OpenWrt:/# cat /proc/interrupts
CPU0
2: 0 MIPS cascade [INTC]
7: 34334 MIPS timer
9: 2845 INTC uart-pl010
12: 0 INTC mcp251x
17: 669 INTC eth0, eth1
ERR: 0
root@OpenWrt:/# cat /sys/kernel/debug/gpio
GPIOs 0-3, adm5120 gpio0:
gpio-2 (MCP251x CAN INT ) in lo
GPIOs 8-22, adm5120 gpio1:
gpio-17 (spi_gpio.1 ) in lo
gpio-18 (spi_gpio.1 ) out lo
gpio-20 (spi_gpio.1 ) out lo
gpio-21 (spi1.0 ) out hi
GPIO2 ist im Status "in lo" und sollte einen IRQ auslösen.
Ich habe zuerst versucht, den IRQ Initialisierung in der Board
Definition unterzubringen - ohne Erfolg. Daher habe ich
versuchsweise dies nun in den CAN Controller Treiber
eingebaut (mcp251x.c):
static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
{
struct mcp251x_priv *priv = dev_id;
struct spi_device *spi = priv->spi;
struct net_device *net = priv->net;
unsignedlong flags;
unsignedint intc_reg_int_level;
mutex_lock(&priv->mcp_lock);
dev_dbg(&spi->dev, " in mcp251x_can_ist ...\n");
// ADM5120 IRQs can only be level, not edge so we are going// switch level and only use high to low trigger
spin_lock_irqsave(&level_register_lock, flags);
{
intc_reg_int_level = BIT(4) ^ intc_read_reg(INTC_REG_INT_LEVEL);
intc_write_reg(INTC_REG_INT_LEVEL, intc_reg_int_level);
}
spin_unlock_irqrestore(&level_register_lock, flags);
// we only need falling edgeif (BIT(4) & intc_reg_int_level)
return(IRQ_HANDLED);
while (!priv->force_quit) {
...
}
}
...
staticint mcp251x_open(struct net_device *net)
{
struct mcp251x_priv *priv = netdev_priv(net);
struct spi_device *spi = priv->spi;
struct mcp251x_platform_data *pdata = spi->dev.platform_data;
int ret;
unsignedint ire;
unsignedlong flags;
ret = open_candev(net);
if (ret) {
dev_err(&spi->dev, "unable to set initial baudrate!\n");
return ret;
}
mutex_lock(&priv->mcp_lock);
if (pdata->transceiver_enable)
pdata->transceiver_enable(1);
priv->force_quit = 0;
priv->tx_skb = NULL;
priv->tx_len = 0;
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
DEVICE_NAME, priv);
if (ret) {
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
if (pdata->transceiver_enable)
pdata->transceiver_enable(0);
close_candev(net);
goto open_unlock;
} else {
spin_lock_irqsave(&level_register_lock, flags);
// enable interrupt on GPIO 2// pp37 ADM5120 manual
ire = intc_read_reg(INTC_REG_IRQ_ENABLE);
ire |= BIT(4) | BIT(9); // II0E | SWIE
intc_write_reg(INTC_REG_IRQ_ENABLE, ire);
dev_dbg(&spi->dev, " INTC_REG_IRQ_ENABLE = 0x%x\n", ire);
// Enable CSX0/INTX0 processing as described on pp131 of ADM5120 manual
SW_WRITE_REG(SWITCH_REG_GPIO_CONF2, BIT(4));
// sets GPIO4 and 2 as active low// pp41/42 of ADM5120 manual.
intc_write_reg(INTC_REG_INT_LEVEL, BIT(4) | intc_read_reg(INTC_REG_INT_LEVEL));
spin_unlock_irqrestore(&level_register_lock, flags);
dev_dbg(&spi->dev, " GPIO2 IRQ initialized\n");
}
...
}
nizza ~/projekte/openwrt/trunk_3.1 (svn)-[trunk:30857] % cat build_dir/linux-adm5120_router_le/linux-3.1.10/arch/mips/adm5120/edimax/br-61xx.c
/*
* Edimax BR-61xx support
*
* Copyright (C) 2007-2008 Gabor Juhos <juhosg@openwrt.org>
*
* 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"br-61xx.h"#include<prom/admboot.h>#include<linux/spi/spi_gpio.h>#include<linux/can/platform/mcp251x.h>#include<linux/irq.h>#include<linux/interrupt.h>#include<linux/kernel.h>
Hat jemand eine Idee, warum der IRQ im MCP251x Modul nicht ausgelöst
wird ?
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang