SD Karte oder MMC Card über Slot 2 machbar?
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
SD Karte oder MMC Card über Slot 2 machbar?
Wie wärs mit dem Anschluss einer MMC oder SD-Card im SPI Modus wie z.B. bei:
http://wrt-wiki.bsr-clan.de/index.php?t ... sys_WRT54G
Der Bootloader u-Boot sollte hiermit eigentlich zurechtkommen können und da eine SD oder MMC Karte ja über einen Adapter vom PC aus beschreibbar ist, gäbs da ja noch einen echten Handhabungsvorteil... ... ...
Und zusätzliche 32 MByte oder 512 MByte wären ja auch nicht von Pappe:)
Z.B. müsste man eigentlich damit auch MP3/Ogg (oder sehr kurze/einfache Videoclips) abspielen können.
IMHO ein klarer Punktvorteil bei Funktionalität/Preis/Kapazität/Beschaffbarkeit/Risiko/Aufwand!)
- Frieder
(PS: Dieses Posting ist inspiriert durch den Thread http://forum.tuxbox-cvs.sourceforge.net ... hp?t=39999)
http://wrt-wiki.bsr-clan.de/index.php?t ... sys_WRT54G
Der Bootloader u-Boot sollte hiermit eigentlich zurechtkommen können und da eine SD oder MMC Karte ja über einen Adapter vom PC aus beschreibbar ist, gäbs da ja noch einen echten Handhabungsvorteil... ... ...
Und zusätzliche 32 MByte oder 512 MByte wären ja auch nicht von Pappe:)
Z.B. müsste man eigentlich damit auch MP3/Ogg (oder sehr kurze/einfache Videoclips) abspielen können.
IMHO ein klarer Punktvorteil bei Funktionalität/Preis/Kapazität/Beschaffbarkeit/Risiko/Aufwand!)
- Frieder
(PS: Dieses Posting ist inspiriert durch den Thread http://forum.tuxbox-cvs.sourceforge.net ... hp?t=39999)
-
- Tuxboxer
- Beiträge: 5001
- Registriert: Montag 11. November 2002, 15:26
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
Nun, da ist sicher das letzte Wort noch nicht gesprochen:)Die erreichbare Schreib-/ Lesegeschwindigkeit liegt bei ~200 KB/s.
Wenn man sich unter http://kiel.kool.dk:27/mmc.c die allerunterste Routine mmc_spi_io() anschaut:
Code: Alles auswählen
static unsigned char mmc_spi_io(unsigned char data_out)
{
int i;
unsigned char result = 0, tmp_data = 0;
for(i=0; i<8; i++) {
if(data_out & (0x01 << (7-i)))
port_state |= SD_DI;
else
port_state &= ~SD_DI;
*gpioaddr_output = port_state;
port_state |= SD_CLK;
*gpioaddr_output = port_state;
tmp_data = *gpioaddr_input;
port_state &= ~SD_CLK;
*gpioaddr_output = port_state;
result <<= 1;
if(tmp_data & SD_DO)
result |= 1;
}
return(result);
}
- result wird unnötigerweise auf 0 gesetzt
- die Schleife ist nicht "unrolled"
- in der Schleife wird ein aufwändiges (0x01 << (7-i)) berechnet
- es ist C und noch kein Assembler und das Setzen/Löschen/Testen der jeweiligen Pins scheint mir unnötig kompliziert
- bei dem Linksysrouter gibt es keine Hardwareunterstützung für SPI und so läuft das ganze mit "BitBanging". Vielleicht gibts Hardwareunterstützung an Slot2?
Und selbst wenn keine Hardwareunterstützung da ist, wird eine 66MHz CPU schon noch mit mehr als 200 kByte pro Sekunde bitbanged IO betreiben können:
330 Zyklen pro Byte ( >40 Zyklen pro Bit) sind IMHO kein hartes Limit - ohne den PowerPC näher zu kennen gehe ich davon aus, dass das 2 bis 5fache schon drin sein dürfte.
Also Video muss vermutlich "leider draussen bleiben" aber für "subVideo-Anvendungen" ist einiger Raum da.
Frieder[/b]
-
- Tuxboxer
- Beiträge: 5001
- Registriert: Montag 11. November 2002, 15:26
-
- IDE-Frickler und Berufspessimist
- Beiträge: 464
- Registriert: Samstag 27. Juli 2002, 21:13
Dir ist schon klar daß die CPU im Linksys mit 200Mhz läuft....just_me hat geschrieben: Und selbst wenn keine Hardwareunterstützung da ist, wird eine 66MHz CPU schon noch mit mehr als 200 kByte pro Sekunde bitbanged IO betreiben können
RR4711
Astra 19.2/Hotbird 13.0
Philips SAT 2xI Avia 600/eNX mit heilem Frontpanel-Prozessor aber irgendwas anderem kaputt
Philips SAT 2xI Avia 600/eNX Base 1.6.3/ CRAMFS vom 28.11.2002
Nokia SAT 2xI Avia 500/GTX 32/32/8 BMON1.0/jffs2 Head 28.01.03
Philips SAT 2xI Avia 600/eNX mit heilem Frontpanel-Prozessor aber irgendwas anderem kaputt
Philips SAT 2xI Avia 600/eNX Base 1.6.3/ CRAMFS vom 28.11.2002
Nokia SAT 2xI Avia 500/GTX 32/32/8 BMON1.0/jffs2 Head 28.01.03
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
-
- Interessierter
- Beiträge: 91
- Registriert: Donnerstag 17. März 2005, 08:20
-
- Developer
- Beiträge: 2183
- Registriert: Mittwoch 10. Dezember 2003, 07:59
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
..was soll man damit sinnvolles anfangen?
Hmm, ich glaube, die Situation ist besser als es zunächst aussieht!)Dir ist schon klar daß die CPU im Linksys mit 200Mhz läuft....
Da ich des PowerPC-Assemblercodes nicht mächtig bin folgt hier ein Beispiel, bei dem ich mit einer 8 Bit CPU argumentiere.
Der SPI Code
Code: Alles auswählen
extern volatile bit MOSI; /* master out, slave in */
extern volatile bit MISO; /* master in, slave out */
extern volatile bit MCLK; /* master clock */
unsigned char spi_io(unsigned char out_byte)
{
unsigned char i=8;
do {
MOSI = out_byte & 0x80;
out_byte <<= 1;
MCLK = 1;
if(MISO)
out_byte += 1;
MCLK = 0;
} while(--i);
return out_byte;
}
Code: Alles auswählen
mov a,dpl
mov r3,#0x08
00103$:
add a,acc
mov _MOSI,c
setb _MCLK
jnb _MISO,00102$
inc a
00102$:
clr _MCLK
djnz r3,00103$
mov dpl,a
ret
Und selbst wenn der PowerPC nicht über 200 kByte/s käme, würde dies eine CPU Load von lediglich 10% für das Lesen eines 196 kBit/s MP3 Streams bedeuten - 90% wären also noch anderweitig zu gebrauchen
Frieder
Disclaimer: Alle Rechenfehler sind selbstgemacht!)
-
- Senior Member
- Beiträge: 1339
- Registriert: Donnerstag 24. April 2003, 12:12
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
Hallo Npq,
wie ist denn die Pin Belegung von Slot 2 und welches sind die entsprechenden Register?
Unter http://wiki.tuxbox-cvs.sourceforge.net/Hauptseite "DBox2 Hardware" bin ich leider nicht fündig geworden
wie ist denn die Pin Belegung von Slot 2 und welches sind die entsprechenden Register?
Unter http://wiki.tuxbox-cvs.sourceforge.net/Hauptseite "DBox2 Hardware" bin ich leider nicht fündig geworden
-
- Senior Member
- Beiträge: 255
- Registriert: Donnerstag 25. August 2005, 11:34
In dem Fall kann man es gleich beim CPLD mit anschliessen, das sind ja tatsächlich nur ein paar Pins bei SD-Cards: Die Idee hatte ich vor einer ganzen Weile schon mal, aber hatte keine konkrete Anwendung vor Augen.vSaAmTp hat geschrieben:die idee ist garnet schlecht. wär damit booten möglich? wär ja dann fast wie ne dreambox mit stick. festplatte ist ja auch in arbeit.
Bilder direkt von der Karte der Kamera könnte aber ab und zu interessant sein.
Auf jeden Fall ist das von der Hardware recht einfach. Und der Rest ist dann Software (TM) :-)
Ach so: Booten geht recht sicher auch davon (egal wie man das SD-Card Interface nun anschliesst), solange der U-Boot im Flash der Box das unterstützt: Und im Prinzip ist es sogar einfacher wenn man erstmal nur booten will, im Kernel ist die Welt doch um einiges komplizierter...
Ciao,
Dboxbaer
... und der Rest ist dann Software (TM)
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
Wenn sich auf dem Board Platz für den Anschluss einerDBoxBaer hat geschrieben:In dem Fall kann man es gleich beim CPLD mit anschliessen, das sind ja tatsächlich nur ein paar Pins bei SD-Cards: Die Idee hatte ich vor einer ganzen Weile schon mal, aber hatte keine konkrete Anwendung vor Augen.
- MMC-Card, RS-MMC Card (18x24x1.4 mm³) oder notfalls MMCmicro (14x12x1.1 mm³)
oder einer
- SD-Card, miniSD-Card oder microSD "TransFlash" (15x11x1 mm³)
fände, wäre das schon hammerhart:)
Alle der genannten Varianten liessen sich über CPLD wohl mit mehr als der 10 MBit Baudrate der Ethernet Schnittstelle auch im SPI Modus betreiben...
Und auf lange Sicht gäbe es noch I/O Karten für SD oder MMC (z.B. SD WLAN Karten, die im Prinzip mit den 10 MBit Halbduplex der eingebauten Ethernetschnittstelle mithalten könnten, falls irgendwann mal Treiber dafür verfügbar werden.)
-
- Tuxboxer
- Beiträge: 4332
- Registriert: Dienstag 7. Mai 2002, 17:04
Kann man denn dann nicht ein interface bauen was eine HD als SD Karte tarnt?Alle der genannten Varianten liessen sich über CPLD wohl mit mehr als der 10 MBit Baudrate der Ethernet Schnittstelle auch im SPI Modus betreiben...
---------------------------
Alle weiteren Infos findest Du im WIKI
Bitte vor dem posten Boardregeln lesen und verstehen!
Wie erstelle ich ein Bootlog? Wo finde ich die FAQ?
Alle weiteren Infos findest Du im WIKI
Bitte vor dem posten Boardregeln lesen und verstehen!
Wie erstelle ich ein Bootlog? Wo finde ich die FAQ?
-
- Senior Member
- Beiträge: 255
- Registriert: Donnerstag 25. August 2005, 11:34
Wofür? Das man die interne Festplatte über ein Kabel an einen SD Card Reader stecken kann? Oder um so ein IDE Interface an die Box zu bauen? Dann hat man eine Hardware, die das SD Interface enthält und eine zweite, die eine Platte mit SD Interface ausstattet. Hmm, klingt für mich komplizierter als es sein muss. Dann schon lieber 100MBit oder USB2.0 :-)Tommy hat geschrieben:Kann man denn dann nicht ein interface bauen was eine HD als SD Karte tarnt?Alle der genannten Varianten liessen sich über CPLD wohl mit mehr als der 10 MBit Baudrate der Ethernet Schnittstelle auch im SPI Modus betreiben...
Zurück zum SD Anschluss:
Die diversen SDIO Karten sind mir heute morgen auch mal in den Sinn gekommen. Aber ob sich das lohnt, weiss ich nicht: Da darf man die Performance dann nämlich nicht mehr ignorieren, und dann wird die Hardware doch wieder kompliziert. Und das Treiberproblem erst.
Ich finde ein SD Card Interface aber gerade deshalb attraktiv weil es (ohne Perfomance "Übertreibungen") recht einfach sein kann und ein paar interessante Nutzungen erlaubt, gerade auch mit interner Festplatte:
- Mal eben ein paar Fotos von der Digicam auf dem Fernsehe anschauen zu können oder diese auch gleich auf die interne Platte zu kopieren.
- Gilt auch für MP3 Dateien: Die MP3 Sammlung auf ner Platte in der Box updaten oder von dort kopieren.
Aber auch ein neues Image (bzw. Teile davon, also neuen Kernel, Module, oder irgendwelche Config-Dateien) auch mal ohne Netzwerk auf die Box kopieren zu können gefällt mir als Möglichkeit. Oder temporär mal ein "TestImage" von so einer Karte zu booten...
Ciao,
Dboxbaer
... und der Rest ist dann Software (TM)
-
- Interessierter
- Beiträge: 96
- Registriert: Samstag 6. Oktober 2001, 00:00
Hier mal der angepasste treiber und die hardware Beschreibung.
Der init läuft durch (Panasonic 512MB SD Karte):
mmc Hardware init
mmc Card init
mmc Card init *1*
mmc Card init *2*
Size = 483840 KByte, hardsectsize = 512 byte, sectors = 967680
Aber beim:
register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,&mmc_bdops, hd_sizes[0]*2);
kommt ein segfault, das sollten mal die kernel experten hier untersuchen.
Partition check:
mmca:Oops: kernel access of bad area, sig: 11
NIP: C3BF33E4 XER: 20000000 LR: C0083810 SP: C17C5C30 REGS: c17c5b80 TRAP: 0300 Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 00000810, DSISR: 0000100B
TASK = c17c4000[147] 'insmod' Last syscall: 128
last math 00000000 last altivec 00000000
GPR00: C0083810 C17C5C30 C17C4000 C015073C 00009032 00000001 00000080 00000000
GPR08: 00000045 C015075C C011B95C 00000800 22004022 100375EC 00000000 00000000
GPR16: 00000001 10030000 10030000 00000000 00009032 10046E38 0000003F 00000000
GPR24: 00000001 C3BF4960 C01C30C8 00000001 C17C4000 C17C5C90 00000000 C3BF33B4
Call backtrace:
C0084B30 C0083810 C0014708 C0035CB8 C0020528 C00231D4 C005844C
C00588A0 C0057DA4 C005839C C0058278 C3BF3ED4 C3BF3F4C C3BF3FDC
Der init läuft durch (Panasonic 512MB SD Karte):
mmc Hardware init
mmc Card init
mmc Card init *1*
mmc Card init *2*
Size = 483840 KByte, hardsectsize = 512 byte, sectors = 967680
Aber beim:
register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,&mmc_bdops, hd_sizes[0]*2);
kommt ein segfault, das sollten mal die kernel experten hier untersuchen.
Partition check:
mmca:Oops: kernel access of bad area, sig: 11
NIP: C3BF33E4 XER: 20000000 LR: C0083810 SP: C17C5C30 REGS: c17c5b80 TRAP: 0300 Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 00000810, DSISR: 0000100B
TASK = c17c4000[147] 'insmod' Last syscall: 128
last math 00000000 last altivec 00000000
GPR00: C0083810 C17C5C30 C17C4000 C015073C 00009032 00000001 00000080 00000000
GPR08: 00000045 C015075C C011B95C 00000800 22004022 100375EC 00000000 00000000
GPR16: 00000001 10030000 10030000 00000000 00009032 10046E38 0000003F 00000000
GPR24: 00000001 C3BF4960 C01C30C8 00000001 C17C4000 C17C5C90 00000000 C3BF33B4
Call backtrace:
C0084B30 C0083810 C0014708 C0035CB8 C0020528 C00231D4 C005844C
C00588A0 C0057DA4 C005839C C0058278 C3BF3ED4 C3BF3F4C C3BF3FDC
Code: Alles auswählen
/* Makefile
TARGET := mmc
TUXBOX := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -fsigned-char -msoft-float -pipe -ffixed-r2 -Wno-uninitialized -mmultiple -mstring -mcpu=823
INCLUDE := -I/dbox2/cdk/bin/powerpc-tuxbox-linux-gnu/include
CFLAGS := -DMODULE -D__KERNEL__ ${TUXBOX} ${INCLUDE}
CC := /dbox2/cdk/bin/powerpc-tuxbox-linux-gnu-gcc
${TARGET}.o: ${TARGET}.c
.PHONY: clean
clean:
rm -rf {TARGET}.o
*/
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
#include <linux/major.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/8xx_immap.h>
#define DEVICE_NAME "mmc"
#define DEVICE_NR(device) (MINOR(device))
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
#define MAJOR_NR 121
#include <linux/blk.h>
MODULE_AUTHOR("Madsuk/Rohde/TaGana");
MODULE_DESCRIPTION("Driver MMC/SD-Cards");
MODULE_SUPPORTED_DEVICE("Nokia dbox2 on com2");
MODULE_LICENSE("GPL");
// dbox2 connection sheme and driver update by TaGana/2006
//
// |
// _----------------------------------------
// | | dbox2 tuner |
// ~----------------------------------------
// |
// |
// | 1 3 5 7 9 11 13 15 17 19
// | 2 4 6 8 10 12 14 16 18 20
// |
#define SD_DO 0x0100 // pin 14 (on SD/MMC card pin 7)
#define SD_DI 0x1000 // pin 17 (on SD/MMC card pin 2)
#define SD_CLK 0x0200 // pin 18 (on SD/MMC card pin 5)
#define SD_CS 0x0100 // pin 5 (on SD/MMC card pin 1)
// GND // pin 10 (on SD/MMC card pin 3+6)
// VCC (3V) // pin 16 (on SD/MMC card pin 4)
//
// Also connect a pullup resistor 100 KOhm from pin14 (SD_DO) to pin16 (VCC)
//
// ----------------
// / 1 2 3 4 5 6 7 x| MMC/SC Card
// |x |
//
immap_t *immap=(immap_t *)IMAP_ADDR ;
/* we have only one device */
static int hd_sizes[1<<6];
static int hd_blocksizes[1<<6];
static int hd_hardsectsizes[1<<6];
static int hd_maxsect[1<<6];
static struct hd_struct hd[1<<6];
static struct timer_list mmc_timer;
static int mmc_media_detect = 0;
static int mmc_media_changed = 1;
typedef unsigned int uint32;
static void mmc_spi_cs_low(void)
{
cpm8xx_t *cp = (cpm8xx_t *) &immap->im_cpm;
cp->cp_pbdat &= ~(SD_CS);
}
static void mmc_spi_cs_high(void)
{
cpm8xx_t *cp = (cpm8xx_t *) &immap->im_cpm;
cp->cp_pbdat |= SD_CS;
}
static unsigned char bitarray[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
static unsigned char mmc_spi_io(unsigned char data_out)
{
int i;
unsigned char result = 0;
cpm8xx_t *cp = (cpm8xx_t *) &immap->im_cpm;
iop8xx_t *cpi = (iop8xx_t *) &immap->im_ioport;
for(i=0; i<8; i++) {
if (data_out & bitarray[i])
cp->cp_pbdat |= SD_DI;
else
cp->cp_pbdat &= ~SD_DI;
cp->cp_pbdat |= SD_CLK;
if (cpi->iop_padat & SD_DO) result |= bitarray[i];
cp->cp_pbdat &= ~SD_CLK;
}
return(result);
}
static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
{
unsigned int address;
unsigned char r = 0;
unsigned char ab0, ab1, ab2, ab3;
int i;
address = dest_addr;
ab3 = 0xff & (address >> 24);
ab2 = 0xff & (address >> 16);
ab1 = 0xff & (address >> 8);
ab0 = 0xff & address;
mmc_spi_cs_low();
for (i = 0; i < 4; i++) mmc_spi_io(0xff);
mmc_spi_io(0x58);
mmc_spi_io(ab3); /* msb */
mmc_spi_io(ab2);
mmc_spi_io(ab1);
mmc_spi_io(ab0); /* lsb */
mmc_spi_io(0xff);
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0x00) break;
}
if (r != 0x00)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(1);
}
mmc_spi_io(0xfe);
for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
for (i = 0; i < 2; i++) mmc_spi_io(0xff);
for (i = 0; i < 1000000; i++)
{
r = mmc_spi_io(0xff);
if (r == 0xff) break;
}
if (r != 0xff)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(3);
}
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(0);
}
static int mmc_read_block(unsigned char *data, unsigned int src_addr)
{
unsigned int address;
unsigned char r = 0;
unsigned char ab0, ab1, ab2, ab3;
int i;
address = src_addr;
ab3 = 0xff & (address >> 24);
ab2 = 0xff & (address >> 16);
ab1 = 0xff & (address >> 8);
ab0 = 0xff & address;
mmc_spi_cs_low();
for (i = 0; i < 4; i++) mmc_spi_io(0xff);
mmc_spi_io(0x51);
mmc_spi_io(ab3); /* msb */
mmc_spi_io(ab2);
mmc_spi_io(ab1);
mmc_spi_io(ab0); /* lsb */
mmc_spi_io(0xff);
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0x00) break;
}
if (r != 0x00)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(1);
}
for (i = 0; i < 100000; i++)
{
r = mmc_spi_io(0xff);
if (r == 0xfe) break;
}
if (r != 0xfe)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(2);
}
for (i = 0; i < 512; i++)
{
r = mmc_spi_io(0xff);
data[i] = r;
}
for (i = 0; i < 2; i++)
{
r = mmc_spi_io(0xff);
}
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(0);
}
static void mmc_request(request_queue_t *q)
{
unsigned int mmc_address;
unsigned char *buffer_address;
int nr_sectors;
int i;
int cmd;
int rc, code;
(void)q;
while (1)
{
code = 1; // Default is success
INIT_REQUEST;
mmc_address = (CURRENT->sector + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
buffer_address = CURRENT->buffer;
nr_sectors = CURRENT->current_nr_sectors;
cmd = CURRENT->cmd;
if (((CURRENT->sector + CURRENT->current_nr_sectors + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) || (mmc_media_detect == 0))
{
code = 0;
}
else if (cmd == READ)
{
spin_unlock_irq(&io_request_lock);
for (i = 0; i < nr_sectors; i++)
{
rc = mmc_read_block(buffer_address, mmc_address);
if (rc != 0)
{
printk("mmc: error in mmc_read_block (%d)\n", rc);
code = 0;
break;
}
else
{
mmc_address += hd_hardsectsizes[0];
buffer_address += hd_hardsectsizes[0];
}
}
spin_lock_irq(&io_request_lock);
}
else if (cmd == WRITE)
{
spin_unlock_irq(&io_request_lock);
for (i = 0; i < nr_sectors; i++)
{
rc = mmc_write_block(mmc_address, buffer_address);
if (rc != 0)
{
printk("mmc: error in mmc_write_block (%d)\n", rc);
code = 0;
break;
}
else
{
mmc_address += hd_hardsectsizes[0];
buffer_address += hd_hardsectsizes[0];
}
}
spin_lock_irq(&io_request_lock);
}
else
{
code = 0;
}
end_request(code);
}
}
static int mmc_open(struct inode *inode, struct file *filp)
{
//int device;
(void)filp;
if (mmc_media_detect == 0) return -ENODEV;
#if defined(MODULE)
MOD_INC_USE_COUNT;
#endif
return 0;
}
static int mmc_release(struct inode *inode, struct file *filp)
{
(void)filp;
fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
#if defined(MODULE)
MOD_DEC_USE_COUNT;
#endif
return 0;
}
extern struct gendisk hd_gendisk;
static int mmc_revalidate(kdev_t dev)
{
int target, max_p, start, i;
if (mmc_media_detect == 0) return -ENODEV;
target = DEVICE_NR(dev);
max_p = hd_gendisk.max_p;
start = target << 6;
for (i = max_p - 1; i >= 0; i--) {
int minor = start + i;
invalidate_device(MKDEV(MAJOR_NR, minor), 1);
hd_gendisk.part[minor].start_sect = 0;
hd_gendisk.part[minor].nr_sects = 0;
}
grok_partitions(&hd_gendisk, target, 1 << 6,
hd_sizes[0] * 2);
return 0;
}
static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
if (!inode || !inode->i_rdev)
return -EINVAL;
switch(cmd) {
case BLKGETSIZE:
return put_user(hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
case BLKGETSIZE64:
return put_user((u64)hd[MINOR(inode->i_rdev)].
nr_sects, (u64 *) arg);
case BLKRRPART:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return mmc_revalidate(inode->i_rdev);
case HDIO_GETGEO:
{
struct hd_geometry *loc, g;
loc = (struct hd_geometry *) arg;
if (!loc)
return -EINVAL;
g.heads = 4;
g.sectors = 16;
g.cylinders = hd[0].nr_sects / (4 * 16);
g.start = hd[MINOR(inode->i_rdev)].start_sect;
return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
}
default:
return blk_ioctl(inode->i_rdev, cmd, arg);
}
}
static int mmc_card_init(void)
{
unsigned char r = 0;
short i, j;
unsigned long flags;
save_flags(flags);
cli();
printk("mmc Card init\n");
mmc_spi_cs_high();
for (i = 0; i < 1000; i++) mmc_spi_io(0xff);
mmc_spi_cs_low();
mmc_spi_io(0x40);
for (i = 0; i < 4; i++) mmc_spi_io(0x00);
mmc_spi_io(0x95);
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0x01) break;
}
mmc_spi_cs_high();
mmc_spi_io(0xff);
if (r != 0x01)
{
restore_flags(flags);
return(1);
}
printk("mmc Card init *1*\n");
for (j = 0; j < 30000; j++)
{
mmc_spi_cs_low();
mmc_spi_io(0x41);
for (i = 0; i < 4; i++) mmc_spi_io(0x00);
mmc_spi_io(0xff);
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0x00) break;
}
mmc_spi_cs_high();
mmc_spi_io(0xff);
if (r == 0x00)
{
restore_flags(flags);
printk("mmc Card init *2*\n");
return(0);
}
}
restore_flags(flags);
return(2);
}
static int mmc_card_config(void)
{
unsigned char r = 0;
short i;
unsigned char csd[32];
unsigned int c_size;
unsigned int c_size_mult;
unsigned int mult;
unsigned int read_bl_len;
unsigned int blocknr = 0;
unsigned int block_len = 0;
unsigned int size = 0;
mmc_spi_cs_low();
for (i = 0; i < 4; i++) mmc_spi_io(0xff);
mmc_spi_io(0x49);
for (i = 0; i < 4; i++) mmc_spi_io(0x00);
mmc_spi_io(0xff);
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0x00) break;
}
if (r != 0x00)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(1);
}
for (i = 0; i < 8; i++)
{
r = mmc_spi_io(0xff);
if (r == 0xfe) break;
}
if (r != 0xfe)
{
mmc_spi_cs_high();
mmc_spi_io(0xff);
return(2);
}
for (i = 0; i < 16; i++)
{
r = mmc_spi_io(0xff);
csd[i] = r;
}
for (i = 0; i < 2; i++)
{
r = mmc_spi_io(0xff);
}
mmc_spi_cs_high();
mmc_spi_io(0xff);
if (r == 0x00) return(3);
c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
c_size >>= 6;
c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
c_size_mult >>= 7;
read_bl_len = csd[5] & 0x0f;
mult = 1;
mult <<= c_size_mult + 2;
blocknr = (c_size + 1) * mult;
block_len = 1;
block_len <<= read_bl_len;
size = block_len * blocknr;
size >>= 10;
for(i=0; i<(1<<6); i++) {
hd_blocksizes[i] = 1024;
hd_hardsectsizes[i] = block_len;
hd_maxsect[i] = 256;
}
hd_sizes[0] = size;
hd[0].nr_sects = blocknr;
printk("Size = %d, hardsectsize = %d, sectors = %d\n",
size, block_len, blocknr);
return 0;
}
static int mmc_hardware_init(void)
{
cpm8xx_t *cp = (cpm8xx_t *) &immap->im_cpm;
iop8xx_t *cpi = (iop8xx_t *) &immap->im_ioport;
printk("mmc Hardware init\n");
cp->cp_pbpar &= ~(SD_CLK | SD_DI | SD_CS);
cp->cp_pbodr &= ~(SD_CLK | SD_DI | SD_CS);
cp->cp_pbdir |= (SD_CLK | SD_DI | SD_CS);
cpi->iop_papar &= ~SD_DO;
cpi->iop_paodr &= ~SD_DO;
cpi->iop_padir &= ~SD_DO;
// Clock low
cp->cp_pbdat &= ~(SD_CLK | SD_DI | SD_CS);
return 0;
}
/*
static int mmc_check_media_change(kdev_t dev)
{
(void)dev;
if (mmc_media_changed == 1)
{
mmc_media_changed = 0;
return 1;
}
else return 0;
}
*/
static struct block_device_operations mmc_bdops =
{
open: mmc_open,
release: mmc_release,
ioctl: mmc_ioctl,
#if 0
check_media_change: mmc_check_media_change,
revalidate: mmc_revalidate,
#endif
};
static struct gendisk hd_gendisk = {
major: MAJOR_NR,
major_name: DEVICE_NAME,
minor_shift: 6,
max_p: 1 << 6,
part: hd,
sizes: hd_sizes,
fops: &mmc_bdops,
};
static int mmc_init(void)
{
int rc;
rc = mmc_hardware_init();
if ( rc != 0)
{
printk("mmc: error in mmc_hardware_init (%d)\n", rc);
return -1;
}
rc = mmc_card_init();
if ( rc != 0)
{
// Give it an extra shot
rc = mmc_card_init();
if ( rc != 0)
{
printk("mmc: error in mmc_card_init (%d)\n", rc);
return -1;
}
}
memset(hd_sizes, 0, sizeof(hd_sizes));
rc = mmc_card_config();
if ( rc != 0)
{
printk("mmc: error in mmc_card_config (%d)\n", rc);
return -1;
}
blk_size[MAJOR_NR] = hd_sizes;
memset(hd, 0, sizeof(hd));
hd[0].nr_sects = hd_sizes[0]*2;
blksize_size[MAJOR_NR] = hd_blocksizes;
hardsect_size[MAJOR_NR] = hd_hardsectsizes;
max_sectors[MAJOR_NR] = hd_maxsect;
hd_gendisk.nr_real = 1;
register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,&mmc_bdops, hd_sizes[0]*2);
return 0;
}
static void mmc_exit(void)
{
blk_size[MAJOR_NR] = NULL;
blksize_size[MAJOR_NR] = NULL;
hardsect_size[MAJOR_NR] = NULL;
max_sectors[MAJOR_NR] = NULL;
hd[0].nr_sects = 0;
}
static void mmc_check_media(void)
{
int old_state;
int rc;
old_state = mmc_media_detect;
// TODO: Add card detection here
mmc_media_detect = 1;
if (old_state != mmc_media_detect)
{
mmc_media_changed = 1;
if (mmc_media_detect == 1)
{
rc = mmc_init();
if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
}
else
{
mmc_exit();
}
}
/* del_timer(&mmc_timer);
mmc_timer.expires = jiffies + 10*HZ;
add_timer(&mmc_timer); */
}
static int __init mmc_driver_init(void)
{
int rc;
rc = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
if (rc < 0)
{
printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
return rc;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
read_ahead[MAJOR_NR] = 8;
add_gendisk(&hd_gendisk);
mmc_check_media();
/*init_timer(&mmc_timer);
mmc_timer.expires = jiffies + HZ;
mmc_timer.function = (void *)mmc_check_media;
add_timer(&mmc_timer);*/
return 0;
}
static void __exit mmc_driver_exit(void)
{
int i;
del_timer(&mmc_timer);
for (i = 0; i < (1 << 6); i++)
fsync_dev(MKDEV(MAJOR_NR, i));
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
del_gendisk(&hd_gendisk);
devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
mmc_exit();
}
module_init(mmc_driver_init);
module_exit(mmc_driver_exit);
-
- Einsteiger
- Beiträge: 232
- Registriert: Sonntag 17. März 2002, 22:14
-
- Interessierter
- Beiträge: 96
- Registriert: Samstag 6. Oktober 2001, 00:00
Noch zu erwähnen ... die I/O Leitungen wurden so gewählt das die SD/MMC karte parallel zuEdit: anderen Erweiterungen laufen kann.
Also com2 ist neben der SD karte weiterhin voll funktionsfähig, samt RTS/DTR/CTS und selbstverständlich TX/RX.
Theroretisch könnte man die SD karte noch im SD modus betreiben (4 bit datenbreite), die zwei zusätzlich benötigte I/O Leitungen sind auch noch da, das würde den durchsatz noch weiter beschleunigen und die CPU entlasten, wenn doch das protokoll verfügbar währe ... ist leider NDA.
Also com2 ist neben der SD karte weiterhin voll funktionsfähig, samt RTS/DTR/CTS und selbstverständlich TX/RX.
Theroretisch könnte man die SD karte noch im SD modus betreiben (4 bit datenbreite), die zwei zusätzlich benötigte I/O Leitungen sind auch noch da, das würde den durchsatz noch weiter beschleunigen und die CPU entlasten, wenn doch das protokoll verfügbar währe ... ist leider NDA.
-
- Tuxboxer
- Beiträge: 2067
- Registriert: Mittwoch 6. März 2002, 15:29
cool, danke!TaGana hat geschrieben:Noch zu erwähnen ... die I/O Leitungen wurden so gewählt das die SD/MMC karte parallel zuEdit: anderen Erweiterungen laufen kann.
Also com2 ist neben der SD karte weiterhin voll funktionsfähig, samt RTS/DTR/CTS und selbstverständlich TX/RX.
Theroretisch könnte man die SD karte noch im SD modus betreiben (4 bit datenbreite), die zwei zusätzlich benötigte I/O Leitungen sind auch noch da, das würde den durchsatz noch weiter beschleunigen und die CPU entlasten, wenn doch das protokoll verfügbar währe ... ist leider NDA.
---
Huch, TaGana höchstselbtpersönlich...
-
- Tuxboxer
- Beiträge: 5873
- Registriert: Samstag 23. Februar 2002, 22:46
Wie kann ich mir das dann vorstellen? Wird die Speicherkarte dann als zustzliches "Laufwerk" gemountet oder wird der freie Speicher dem des Flashs "hinzugefügt"?
Welche Speicher sind zu bevorzugen (vor und Nachteile).
Als Kartenadapter werde ich wohl einen USB Leser ausschlachten oder gibts entsprechende "Fassungen" auch einzeln?
Gruß Gorcon
Welche Speicher sind zu bevorzugen (vor und Nachteile).
Als Kartenadapter werde ich wohl einen USB Leser ausschlachten oder gibts entsprechende "Fassungen" auch einzeln?
Gruß Gorcon
-
- Interessierter
- Beiträge: 96
- Registriert: Samstag 6. Oktober 2001, 00:00
> Wird die Speicherkarte dann als zustzliches "Laufwerk" gemountet
ja,
Nur der kernel müsste mal recompiliert werden mit den richtigen Einstellungen um das neue "Laufwerk" zu unterstützen.
> oder gibts entsprechende "Fassungen" auch einzeln?
Bei Farnell für 1-2 Euro.
http://de.farnell.com/jsp/endecaSearch/ ... 186182&N=0
ja,
Nur der kernel müsste mal recompiliert werden mit den richtigen Einstellungen um das neue "Laufwerk" zu unterstützen.
> oder gibts entsprechende "Fassungen" auch einzeln?
Bei Farnell für 1-2 Euro.
http://de.farnell.com/jsp/endecaSearch/ ... 186182&N=0
Zuletzt geändert von TaGana am Freitag 3. März 2006, 00:10, insgesamt 1-mal geändert.
-
- Tuxboxer
- Beiträge: 2067
- Registriert: Mittwoch 6. März 2002, 15:29
von reichelt so einen 8in1 usb-kartenleser schlachten (6,90€).Gorcon hat geschrieben:Welche Speicher sind zu bevorzugen (vor und Nachteile).
Als Kartenadapter werde ich wohl einen USB Leser ausschlachten oder gibts entsprechende "Fassungen" auch einzeln?Gruß Gorcon
sonstige sd/mmc-cardfassungen sind imho quasi alle teurer.
-
- Tuxboxer
- Beiträge: 5873
- Registriert: Samstag 23. Februar 2002, 22:46
-
- Einsteiger
- Beiträge: 123
- Registriert: Montag 28. November 2005, 11:31
Es geht auch anders: Du bekommst teilweise die etwa halb so grossen miniSD Cards zusammen mit einem Adapter auf SD Card für einen geringen oder keinen Aufpreis.Gorcon hat geschrieben:Als Kartenadapter werde ich wohl einen USB Leser ausschlachten oder gibts entsprechende "Fassungen" auch einzeln?
Den Adapter kannst Du dann fest einlöten und die miniSD dort bei Bedarf ein-/ausstecken:)
http://images-eu.amazon.com/images/P/B0 ... ZZZZZZ.jpg