Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf783f4dce | ||
|
|
b339ff35d1 | ||
|
|
b018ae6f78 | ||
|
|
a823badfe0 | ||
|
|
13aa3536b4 | ||
|
|
f4d5451fec | ||
|
|
e1567d81da | ||
|
|
82f8229c8f |
@@ -30,16 +30,11 @@ SIZE = avr-size
|
|||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
LDFLAGS = -Wl,-u,vfprintf -lprintf_flt
|
LDFLAGS = -Wl,-u,vfprintf -lprintf_flt
|
||||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o mmc.o fat.o
|
||||||
main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o \
|
|
||||||
dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o \
|
|
||||||
command.o mmc.o fat.o file.o dir.o testing.o
|
|
||||||
else
|
else
|
||||||
LDFLAGS = -Wl,-u
|
LDFLAGS = -Wl,-u
|
||||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o
|
||||||
uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o \
|
|
||||||
info.o shared_memory.o command.o
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "requests.h"
|
|
||||||
#include "sram.h"
|
|
||||||
#include "info.h"
|
|
||||||
|
|
||||||
extern uint32_t req_bank_size;
|
|
||||||
|
|
||||||
|
|
||||||
void send_reset()
|
|
||||||
{
|
|
||||||
info("Reset Snes\n");
|
|
||||||
snes_reset_on();
|
|
||||||
snes_reset_lo();
|
|
||||||
_delay_ms(2);
|
|
||||||
snes_reset_hi();
|
|
||||||
snes_reset_off();
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_irq()
|
|
||||||
{
|
|
||||||
snes_irq_on();
|
|
||||||
snes_irq_lo();
|
|
||||||
_delay_us(20);
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_rom_mode()
|
|
||||||
{
|
|
||||||
if (req_bank_size == 0x8000) {
|
|
||||||
snes_lorom();
|
|
||||||
info("Set Snes lowrom \n");
|
|
||||||
} else {
|
|
||||||
snes_hirom();
|
|
||||||
info("Set Snes hirom \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __COMMAND_H__
|
|
||||||
#define __COMMAND_H__
|
|
||||||
|
|
||||||
void send_reset();
|
|
||||||
void send_irq();
|
|
||||||
void set_rom_mode();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -27,9 +27,8 @@
|
|||||||
#define DEBUG_USB_TRANS 4
|
#define DEBUG_USB_TRANS 4
|
||||||
#define DEBUG_SRAM 8
|
#define DEBUG_SRAM 8
|
||||||
#define DEBUG_SRAM_RAW 16
|
#define DEBUG_SRAM_RAW 16
|
||||||
#define DEBUG_FAT 32
|
#define DEBUG_SREG 32
|
||||||
#define DEBUG_CRC 64
|
#define DEBUG_CRC 64
|
||||||
#define DEBUG_SHM 128
|
|
||||||
|
|
||||||
#define REQ_STATUS_IDLE 0x01
|
#define REQ_STATUS_IDLE 0x01
|
||||||
#define REQ_STATUS_UPLOAD 0x02
|
#define REQ_STATUS_UPLOAD 0x02
|
||||||
|
|||||||
@@ -91,13 +91,31 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void crc_check_memory(uint32_t bottom_addr,uint32_t top_addr,uint32_t bank_size,uint8_t *buffer)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint32_t addr;
|
||||||
|
uint8_t req_bank = 0;
|
||||||
|
for (addr = bottom_addr; addr < top_addr; addr += TRANSFER_BUFFER_SIZE) {
|
||||||
|
if (addr && addr % bank_size == 0) {
|
||||||
|
debug(DEBUG_CRC,"crc_check_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||||
|
req_bank,addr,crc);
|
||||||
|
req_bank++;
|
||||||
|
crc = 0;
|
||||||
|
}
|
||||||
|
sram_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
|
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)
|
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
||||||
sram_bulk_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
sram_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
||||||
uint16_t do_crc(uint8_t * data,uint16_t size);
|
uint16_t do_crc(uint8_t * data,uint16_t size);
|
||||||
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
||||||
|
void crc_check_memory(uint32_t bottom_addr,uint32_t top_addr,uint32_t bank_size,uint8_t *buffer);
|
||||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer);
|
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer);
|
||||||
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t bank_size,uint32_t top_addr);
|
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t bank_size,uint32_t top_addr);
|
||||||
|
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "dir.h"
|
|
||||||
#include "file.h"
|
|
||||||
#include "fat.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "sram.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t position = 0;
|
|
||||||
|
|
||||||
extern struct File file;
|
|
||||||
|
|
||||||
void dir_entry_start(){
|
|
||||||
position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dir_entry_dump(uint32_t addr, dir_ent_t* ent){
|
|
||||||
debug(DEBUG_FAT,"dir_entry_dump: addr=0x%06lx id=%li name=%s size=%li attr=%i\n", addr, ent->id, ent->file_name,
|
|
||||||
ent->file_size, ent->file_attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dir_entry_add(uint32_t id, uint8_t* file_name,uint32_t file_size,uint8_t file_attr){
|
|
||||||
uint32_t addr;
|
|
||||||
dir_ent_t ent;
|
|
||||||
strncpy(ent.file_name,file_name,13);
|
|
||||||
ent.id = id;
|
|
||||||
ent.file_size = file_size;
|
|
||||||
ent.file_attr = file_attr;
|
|
||||||
addr = DIR_ENTRY_LOC + (position << DIR_ENTRY_SIZE_SHIFT );
|
|
||||||
sram_bulk_copy(addr, (uint8_t *) &ent, DIR_ENTRY_SIZE );
|
|
||||||
dir_entry_dump(addr, &ent);
|
|
||||||
position++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dir_entry_header(uint16_t idx, uint8_t * header){
|
|
||||||
uint32_t addr;
|
|
||||||
addr = DIR_ENTRY_LOC + ( idx << DIR_ENTRY_SIZE_SHIFT ) + DIR_ENTRY_HEADER_OFF;
|
|
||||||
sram_bulk_copy(addr, (uint8_t *) header, DIR_ENTRY_HEADER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t dir_entry_get(uint32_t idx, dir_ent_t* ent){
|
|
||||||
uint32_t addr;
|
|
||||||
addr = DIR_ENTRY_LOC + ( idx << DIR_ENTRY_SIZE_SHIFT );
|
|
||||||
sram_bulk_read_buffer( addr, (uint8_t *) ent, DIR_ENTRY_SIZE);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dir_entry_loop(){
|
|
||||||
uint8_t i;
|
|
||||||
uint8_t j;
|
|
||||||
uint32_t addr;
|
|
||||||
dir_ent_t ent;
|
|
||||||
for (i=0; i< position; i++){
|
|
||||||
addr = dir_entry_get(i,&ent);
|
|
||||||
dir_entry_dump(addr,&ent);
|
|
||||||
ffopen( ent.file_name );
|
|
||||||
if (file.length != 524288){
|
|
||||||
ffclose();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//ffseek(0x7fc0);
|
|
||||||
for (j=0; j< 64; j++)
|
|
||||||
printf ("0x%02x " ,ffread());
|
|
||||||
printf("\n");
|
|
||||||
ffclose();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __DIR_H__
|
|
||||||
#define __DIR_H__
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define DIR_ENTRY_LOC 0x010000
|
|
||||||
#define DIR_ENTRY_SIZE 64
|
|
||||||
#define DIR_ENTRY_SIZE_SHIFT 6
|
|
||||||
#define DIR_ENTRY_HEADER_SIZE 44
|
|
||||||
#define DIR_ENTRY_HEADER_OFF 20
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t id; // 4
|
|
||||||
uint8_t file_name[13]; // 8.3 = 12 + 1 = 13
|
|
||||||
uint32_t file_size; // 4
|
|
||||||
uint8_t file_attr; // 1
|
|
||||||
uint8_t snes_header[41]; // 41
|
|
||||||
} dir_ent_t; // 64
|
|
||||||
|
|
||||||
void dir_entry_start();
|
|
||||||
void dir_entry_add(uint32_t id, uint8_t* file_name,uint32_t file_size,uint8_t file_attr);
|
|
||||||
void dir_entry_header(uint16_t position, uint8_t * header);
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
lo:
|
|
||||||
0x7fc0
|
|
||||||
0x7fc0 + 0x200
|
|
||||||
|
|
||||||
hi:
|
|
||||||
0xffc0
|
|
||||||
0xffc0 + 0x200
|
|
||||||
|
|
||||||
emulated reset vector MSB must be set
|
|
||||||
|
|
||||||
sei
|
|
||||||
clc
|
|
||||||
xce
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -31,4 +31,4 @@ void dump_memory(uint32_t bottom_addr, uint32_t top_addr);
|
|||||||
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1,668 +1,192 @@
|
|||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
#include "file.h"
|
|
||||||
#include "mmc.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
struct Fat fat; // wichtige daten/variablen der fat
|
uint8_t cluster_size;
|
||||||
struct File file; // wichtige dateibezogene daten/variablen
|
uint16_t fat_offset;
|
||||||
|
uint16_t cluster_offset;
|
||||||
|
uint16_t volume_boot_record_addr;
|
||||||
|
|
||||||
|
void fat_init(uint8_t * Buffer)
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// schreibt sektor nummer:sec auf die karte (puffer:sector) !!
|
|
||||||
// setzt bufferFlag=0 da puffer nicht dirty sein kann nach schreiben !
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_writeSector(uint32_t sec)
|
|
||||||
{
|
{
|
||||||
|
struct BootSec *bootp;
|
||||||
fat.bufferDirty = 0; // buffer kann nicht dirty sein weil wird geschrieben
|
mmc_read_sector(MASTER_BOOT_RECORD, Buffer);
|
||||||
return (mmc_write_sector(sec, fat.sector)); // schreiben von sektor puffer
|
if (Buffer[510] == 0x55 && Buffer[511] == 0xAA) {
|
||||||
}
|
FAT_DEBUG("MBR Signatur found!\r\n");
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// umrechnung cluster auf 1.sektor des clusters (möglicherweise mehrere sektoren/cluster) !
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint32_t fat_clustToSec(uint32_t clust)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (fat.dataDirSec + 2 + ((clust - 2) * fat.secPerClust)); // errechnet den 1. sektor der sektoren des clusters
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// umrechnung sektor auf cluster (nicht die position im cluster selber!!)
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint32_t fat_secToClust(uint32_t sec)
|
|
||||||
{
|
|
||||||
|
|
||||||
return ((sec - fat.dataDirSec - 2 + 2 * fat.secPerClust) / fat.secPerClust); // umkerhrfunktion von fat_clustToSec
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// läd sektor:sec auf puffer:sector zum bearbeiten im ram !
|
|
||||||
// setzt currentSectorNr auf richtigen wert (also den sektor der gepuffert ist). es wird geprüft
|
|
||||||
// ob der gepufferte sektor geändert wurde, wenn ja muss erst geschrieben werden, um diese daten nicht zu verlieren !
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_loadSector(uint32_t sec)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (sec != fat.currentSectorNr) { // nachladen nötig
|
|
||||||
#if (WRITE==1)
|
|
||||||
if (fat.bufferDirty == 1)
|
|
||||||
fat_writeSector(fat.currentSectorNr); // puffer diry, also vorher schreiben
|
|
||||||
#endif
|
|
||||||
mmc_read_sector(sec, fat.sector); // neuen sektor laden
|
|
||||||
fat.currentSectorNr = sec; // aktualisiert sektor nummer (nummer des gepufferten sektors)
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return (0); // alles ok, daten sind schon da (sec==fat.currentSectorNr)
|
|
||||||
|
|
||||||
return (1); // fehler
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// datei lesen funktionen:
|
|
||||||
|
|
||||||
// fat_loadSector -> fat_loadRowOfSector -> fat_loadFileDataFromCluster -> fat_loadFileDataFromDir -> fat_loadFileDataFromDir -> fat_cd
|
|
||||||
// "daten chain"
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// läd die reihe:row des gepufferten sektors auf das struct:file. dort stehen dann
|
|
||||||
// alle wichgigen daten wie: 1.cluster,länge bei dateien, name des eintrags, reihen nummer (im sektor), attribut use...
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_loadRowOfSector(uint16_t row)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
row = row << 5; // multipliziert mit 32 um immer auf zeilen anfang zu kommen (zeile 0=0,zeile 1=32,zeile 2=62 usw).
|
|
||||||
|
|
||||||
void *vsector; // void, damit man schoen umbiegen kann :)
|
|
||||||
|
|
||||||
for (i = 0; i < 11; i++)
|
|
||||||
file.name[i] = fat.sector[row + i]; // datei name, ersten 10 bytes vom 32 byte eintrag.
|
|
||||||
|
|
||||||
file.attrib = fat.sector[row + 11]; // datei attribut, byte 11.
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 26]; // low word von fist.cluster
|
|
||||||
file.firstCluster = *(uint16_t *) vsector;
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 20]; // high word von first.cluster
|
|
||||||
file.firstCluster |= (*(uint16_t *) vsector) << 16;
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 28]; // 4 byte von file.length
|
|
||||||
file.length = *(uint32_t *) vsector;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// geht reihen weise durch sektoren des clusters mit dem startsektor:sec, und sucht nach der datei mit dem
|
|
||||||
// namen:name. es werden die einzelnen sektoren nachgeladen auf puffer:sector vor dem bearbeiten.
|
|
||||||
// wird die datei in dem cluster gefunden ist return 0 , sonst return1.
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_loadFileDataFromCluster(uint32_t sec, char name[])
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t r;
|
|
||||||
uint8_t s = 0;
|
|
||||||
|
|
||||||
do { // sektoren des clusters prüfen
|
|
||||||
r = 0; // neuer sektor, dann reihen von 0 an.
|
|
||||||
mmc_read_sector(sec + s, fat.sector); // läd den sektor sec auf den puffer fat.sector
|
|
||||||
fat.currentSectorNr = sec + s; // setzen des aktuellen sektors
|
|
||||||
do { // reihen des sektors prüfen
|
|
||||||
fat_loadRowOfSector(r); // zeile 0-15 auf struct file laden
|
|
||||||
if (file.name[0] == 0) { // wenn man auf erste 0 stößt müsste der rest auch leer sein!
|
|
||||||
file.row = r; // zeile sichern.
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (0 == strncmp((char *) file.name, name, 10)) { // zeile r ist gesuchte
|
|
||||||
file.row = r; // zeile sichern.
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
r++;
|
|
||||||
} while (r < 16); // zählt zeilennummer (16(zeilen) * 32(spalten) == 512 bytes des sektors)
|
|
||||||
s++;
|
|
||||||
} while (s < fat.secPerClust); // geht durch sektoren des clusters
|
|
||||||
|
|
||||||
return (1); // fehler (datei nicht gefunden, oder fehler beim lesen)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// wenn dir == 0 dann wird das root direktory durchsucht, wenn nicht wird der ordner cluster-chain gefolgt, um
|
|
||||||
// die datei zu finden. es wird das komplette directory in dem man sich befindet durchsucht.
|
|
||||||
// bei fat16 wird der rootDir berreich durchsucht, bei fat32 die cluster chain des rootDir.
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_loadFileDataFromDir(char name[])
|
|
||||||
{
|
|
||||||
|
|
||||||
uint16_t s;
|
|
||||||
|
|
||||||
if (fat.dir == 0 && fat.fatType == 16) { // IM ROOTDIR. fat16
|
|
||||||
for (s = 0; s < (uint16_t) (fat.dataDirSec + 2 - fat.rootDir); s++) { // zählt durch RootDir sektoren (errechnet anzahl
|
|
||||||
// rootDir sektoren).
|
|
||||||
if (0 == fat_loadFileDataFromCluster(fat.rootDir + s, name))
|
|
||||||
return (0); // sucht die datei, wenn da, läd daten (1.cluster usw)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
uint32_t i;
|
FAT_DEBUG("MBR Signatur not found!\r\n");
|
||||||
if (fat.dir == 0 && fat.fatType == 32)
|
while (1);
|
||||||
i = fat.rootDir; // IM ROOTDIR. fat32
|
}
|
||||||
else
|
volume_boot_record_addr = Buffer[VBR_ADDR] + (Buffer[VBR_ADDR + 1] << 8);
|
||||||
i = fat.dir; // NICHT ROOTDIR
|
mmc_read_sector(volume_boot_record_addr, Buffer);
|
||||||
while (!((i == 0xfffffff && fat.fatType == 32) || (i == 0xffff && fat.fatType == 16))) { // prüft ob weitere sektoren zum
|
if (Buffer[510] == 0x55 && Buffer[511] == 0xAA) {
|
||||||
// lesen da sind (fat32||fat16)
|
FAT_DEBUG("VBR Signatur found!\r\n");
|
||||||
if (0 == fat_loadFileDataFromCluster(fat_clustToSec(i), name))
|
|
||||||
return (0); // lät die daten der datei auf struct:file. datei gefunden (umrechnung auf absoluten sektor)
|
|
||||||
i = fat_getNextCluster(i); // liest nächsten cluster des dir-eintrags (unterverzeichniss größer 16 einträge)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (1); // datei/verzeichniss nicht gefunden
|
else {
|
||||||
|
FAT_DEBUG("VBR Signatur not found!\r\n");
|
||||||
|
volume_boot_record_addr = MASTER_BOOT_RECORD;
|
||||||
|
mmc_read_sector(MASTER_BOOT_RECORD, Buffer);
|
||||||
|
}
|
||||||
|
bootp = (struct BootSec *) Buffer;
|
||||||
|
cluster_size = bootp->BPB_SecPerClus;
|
||||||
|
fat_offset = bootp->BPB_RsvdSecCnt;
|
||||||
|
cluster_offset = ((bootp->BPB_BytesPerSec * 32) / BlockSize);
|
||||||
|
cluster_offset += fat_root_dir_addr(Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t fat_root_dir_addr(uint8_t * Buffer)
|
||||||
|
{
|
||||||
|
struct BootSec *bootp;
|
||||||
|
uint16_t FirstRootDirSecNum;
|
||||||
|
|
||||||
|
|
||||||
|
mmc_read_sector(volume_boot_record_addr, Buffer);
|
||||||
|
bootp = (struct BootSec *) Buffer;
|
||||||
|
|
||||||
|
|
||||||
|
FirstRootDirSecNum = (bootp->BPB_RsvdSecCnt +
|
||||||
|
(bootp->BPB_NumFATs * bootp->BPB_FATSz16));
|
||||||
|
FirstRootDirSecNum += volume_boot_record_addr;
|
||||||
|
return (FirstRootDirSecNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (SMALL_FILE_SYSTEM==0)
|
uint16_t fat_read_dir_ent(uint16_t dir_cluster,
|
||||||
|
uint8_t Entry_Count,
|
||||||
// ***************************************************************************************************************
|
uint32_t * Size,
|
||||||
// start immer im root Dir. start in root dir (dir==0).
|
uint8_t * Dir_Attrib, uint8_t * Buffer)
|
||||||
// es MUSS in das direktory gewechselt werden, in dem die datei zum lesen/anhängen ist (außer root, da startet mann)!
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint8_t fat_cd(char name[])
|
|
||||||
{
|
{
|
||||||
|
uint8_t *pointer;
|
||||||
if (name[0] == 0) { // ZUM ROOTDIR FAT16/32
|
uint16_t TMP_Entry_Count = 0;
|
||||||
fat.dir = 0; // root dir
|
uint32_t Block = 0;
|
||||||
return (0);
|
struct DirEntry *dir;
|
||||||
|
uint16_t blk;
|
||||||
|
uint16_t a;
|
||||||
|
uint8_t b;
|
||||||
|
pointer = Buffer;
|
||||||
|
if (dir_cluster == 0) {
|
||||||
|
Block = fat_root_dir_addr(Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == fat_loadFileDataFromDir(name)) { // NICHT ROOTDIR (fat16/32)
|
else {
|
||||||
fat.dir = file.firstCluster; // zeigt auf 1.cluster des dir (fat16/32)
|
fat_load(dir_cluster, &Block, Buffer);
|
||||||
return (0);
|
Block = ((Block - 2) * cluster_size) + cluster_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (1); // dir nicht gewechselt (nicht da?) !!
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
for (blk = Block;; blk++) {
|
||||||
|
mmc_read_sector(blk, Buffer);
|
||||||
|
for (a = 0; a < BlockSize; a = a + 32) {
|
||||||
|
dir = (struct DirEntry *) &Buffer[a];
|
||||||
|
if (dir->DIR_Name[0] == 0) {
|
||||||
|
return (0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dir->DIR_Attr != ATTR_LONG_NAME) &&
|
||||||
|
(dir->DIR_Name[0] != DIR_ENTRY_IS_FREE)) {
|
||||||
|
|
||||||
|
|
||||||
|
if (TMP_Entry_Count == Entry_Count) {
|
||||||
|
|
||||||
|
|
||||||
|
for (b = 0; b < 11; b++) {
|
||||||
|
if (dir->DIR_Name[b] != SPACE) {
|
||||||
|
if (b == 8) {
|
||||||
|
*pointer++ = '.';
|
||||||
|
}
|
||||||
|
*pointer++ = dir->DIR_Name[b];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pointer++ = '\0';
|
||||||
|
*Dir_Attrib = dir->DIR_Attr;
|
||||||
|
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
// datei anlegen funktionen :
|
*Size = dir->DIR_FileSize;
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// sucht leeren eintrag (zeile) im cluster mit dem startsektor:secStart.
|
|
||||||
// wird dort kein freier eintrag gefunden ist return (1).
|
|
||||||
// wird ein freier eintrag gefunden, ist die position der freien reihe auf file.row abzulesen und return (0).
|
|
||||||
// der sektor mit der freien reihe ist auf dem puffer:sector gepuffert.
|
|
||||||
// ****************************************************************************************************************
|
|
||||||
uint8_t fat_getFreeRowOfCluster(unsigned long secStart)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint16_t b; // zum durchgenen der sektor bytes
|
dir_cluster = dir->DIR_FstClusLO;
|
||||||
uint8_t s = 0; // sektoren des clusters.
|
|
||||||
|
|
||||||
do {
|
|
||||||
file.row = 0; // neuer sektor(oder 1.sektor), reihen von vorne.
|
return (dir_cluster);
|
||||||
if (0 == fat_loadSector(secStart + s)) { // laed sektor auf puffer fat.sector
|
}
|
||||||
for (b = 0; b < 512; b = b + 32) { // zaehlt durch zeilen (0-15).
|
TMP_Entry_Count++;
|
||||||
if (fat.sector[b] == 0x00 || fat.sector[b] == 0xE5)
|
|
||||||
return (0); // prueft auf freihen eintrag (leer oder geloescht == OK!).
|
|
||||||
file.row++; // zählt reihe hoch (nächste reihe im sektor).
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s++; // sektoren des clusters ++ weil einen geprüft.
|
|
||||||
} while (s < fat.secPerClust); // geht die sektoren des clusters durch (moeglicherweise auch nur 1. sektor).
|
|
||||||
return (1); // nicht gefunden in diesem cluster (== nicht OK!).
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// sucht leeren eintrag (zeile) im directory mit dem startcluster:dir.
|
|
||||||
// geht die cluster chain des direktories durch. dabei werden auch alle sektoren der cluster geprüft.
|
|
||||||
// wird dort kein freier eintrag gefunden, wird ein neuer leerer cluster gesucht, verkettet und der
|
|
||||||
// 1. sektor des freien clusters geladen. die reihe wird auf den ersten eintrag gesetzt, da frei.
|
|
||||||
// anhand der reihe kann man nun den direktory eintrag vornehmen, und auf die karte schreiben.
|
|
||||||
// ****************************************************************************************************************
|
|
||||||
void fat_getFreeRowOfDir(uint32_t dir)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t start = dir;
|
|
||||||
|
|
||||||
// solange bis ende cluster chain.
|
|
||||||
while (!
|
|
||||||
((dir == 0xfffffff && fat.fatType == 32)
|
|
||||||
|| (dir == 0xffff && fat.fatType == 16))) {
|
|
||||||
if (0 == fat_getFreeRowOfCluster(fat_clustToSec(dir)))
|
|
||||||
return; // freien eintrag in clustern, des dir gefunden !!
|
|
||||||
start = dir;
|
|
||||||
dir = fat_getNextCluster(dir);
|
|
||||||
} // wenn aus schleife raus, kein freier eintrag da -> neuer cluster nötig.
|
|
||||||
|
|
||||||
dir = fat_secToClust(fat.startSectors); // dir ist jetzt neuer cluster zum verketten !
|
|
||||||
fat_setCluster(start, dir); // cluster-chain mit neuem cluster verketten
|
|
||||||
fat_setCluster(dir, 0x0fffffff); // cluster-chain ende markieren
|
|
||||||
|
|
||||||
// es muessen neue gesucht werden, weil der bekannte aus file.c ja grade verkettet wurden. datei eintrag passte nicht mehr ins dir...
|
|
||||||
fat_getFreeClustersInRow(2); // neue freie cluster suchen, für datei.
|
|
||||||
file.firstCluster = fat_secToClust(fat.startSectors); // 1. cluster der datei
|
|
||||||
file.lastCluster = fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
|
|
||||||
|
|
||||||
fat.currentSectorNr = fat_clustToSec(dir); // setzen des richtigen sektors, also auf den 1. der neu verketteten
|
|
||||||
|
|
||||||
uint16_t j = 511;
|
|
||||||
do {
|
|
||||||
fat.sector[j] = 0x00; // schreibt puffer fat.sector voll mit 0x00==leer
|
|
||||||
} while (j--);
|
|
||||||
|
|
||||||
uint8_t i = 1; // ab 1 weil der 1.sektor des clusters eh noch beschrieben wird...
|
|
||||||
do {
|
|
||||||
fat_writeSector(fat.currentSectorNr + i); // löschen des cluster (überschreibt mit 0x00), wichtig bei ffls,
|
|
||||||
i++;
|
|
||||||
} while (i < fat.secPerClust);
|
|
||||||
|
|
||||||
file.row = 0; // erste reihe frei, weil grad neuen cluster verkettet !
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// erstellt 32 byte eintrag einer datei, oder verzeichnisses im puffer:sector.
|
|
||||||
// erstellt eintrag in reihe:row, mit namen:name usw... !!
|
|
||||||
// muss noch auf die karte geschrieben werden ! nicht optimiert auf geschwindigkeit.
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_makeRowDataEntry(uint16_t row, char name[], uint8_t attrib,
|
|
||||||
uint32_t cluster, uint32_t length)
|
|
||||||
{
|
|
||||||
|
|
||||||
fat.bufferDirty = 1; // puffer beschrieben, also neue daten darin(vor lesen muss geschrieben werden)
|
|
||||||
|
|
||||||
row = row << 5; // multipliziert mit 32 um immer auf zeilen anfang zu kommen (zeile 0=0,zeile 1=32,zeile 2=62 ... zeile
|
|
||||||
// 15=480)
|
|
||||||
|
|
||||||
uint8_t i; // byte zähler in reihe von sektor (32byte eintrag)
|
|
||||||
uint8_t *bytesOfSec = &fat.sector[row]; // zeiger auf sector bytes
|
|
||||||
void *vsector;
|
|
||||||
|
|
||||||
for (i = 0; i < 11; i++)
|
|
||||||
*bytesOfSec++ = name[i]; // namen schreiben
|
|
||||||
|
|
||||||
*bytesOfSec++ = attrib; // attrib schreiben
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 12];
|
|
||||||
*(uint32_t *) vsector++ = 0x01010101; // unnoetige felder beschreiben
|
|
||||||
*(uint32_t *) vsector = 0x01010101;
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 20];
|
|
||||||
*(uint16_t *) vsector = (cluster & 0xffff0000) >> 16; // low word von cluster
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 22];
|
|
||||||
*(uint32_t *) vsector = 0x01010101; // unnoetige felder beschreiben
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 26];
|
|
||||||
*(uint16_t *) vsector = (cluster & 0x0000ffff); // high word von cluster
|
|
||||||
|
|
||||||
vsector = &fat.sector[row + 28];
|
|
||||||
*(uint32_t *) vsector = length; // laenge
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// macht den datei eintrag im jetzigen verzeichniss (fat.dir).
|
|
||||||
// file.row enthält die reihen nummer des leeren eintrags, der vorher gesucht wurde, auf puffer:sector ist der gewünschte
|
|
||||||
// sektor gepuffert. für fat16 im root dir muss andere funktion genutzt werden, als fat_getFreeRowOfDir (durchsucht nur dirs).
|
|
||||||
// fat.rootDir enthält bei fat32 den start cluster des directory, bei fat16 den 1. sektor des rootDir bereichs!
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_makeFileEntry(char name[], uint8_t attrib,
|
|
||||||
uint32_t length)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint16_t s; // zähler für root dir sektoren fat16
|
|
||||||
|
|
||||||
if (fat.dir == 0 && fat.fatType == 32)
|
|
||||||
fat_getFreeRowOfDir(fat.rootDir); // IM ROOT DIR (fat32)
|
|
||||||
|
|
||||||
else if (fat.dir == 0 && fat.fatType == 16) { // IM ROOT DIR (fat16)
|
|
||||||
for (s = 0; s < (uint16_t) (fat.dataDirSec + 2 - fat.rootDir); s++) { // zählt durch RootDir sektoren (errechnet anzahl
|
|
||||||
// rootDir sektoren).
|
|
||||||
if (0 == fat_getFreeRowOfCluster(fat.rootDir + s))
|
|
||||||
break; // geht durch sektoren des root dir.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return (0xFFFF);
|
||||||
else
|
|
||||||
fat_getFreeRowOfDir(fat.dir); // NICHT ROOT DIR fat32/fat16
|
|
||||||
|
|
||||||
fat_makeRowDataEntry(file.row, name, attrib, file.firstCluster, length); // schreibt file eintrag auf puffer
|
|
||||||
fat_writeSector(fat.currentSectorNr); // schreibt puffer auf karte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void fat_load(uint16_t Cluster, uint32_t * Block, uint8_t * TMP_Buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// fat funktionen:
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// sucht nötige folge Cluster aus der fat !
|
|
||||||
// erster daten cluster = 2, ende einer cluster chain 0xFFFF (fat16) oder 0xFFFFFFF, 0xFFFFFF8 (fat32),
|
|
||||||
// stelle des clusters in der fat, hat als wert, den nächsten cluster. (1:1 gemapt)!
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
uint32_t fat_getNextCluster(uint32_t oneCluster)
|
|
||||||
{
|
{
|
||||||
|
uint16_t FAT_Block_Store = 0;
|
||||||
|
uint16_t FAT_Byte_Addresse;
|
||||||
|
uint16_t FAT_Block_Addresse;
|
||||||
|
uint16_t a;
|
||||||
|
|
||||||
// FAT 16**************FAT 16
|
for (a = 0;; a++) {
|
||||||
if (fat.fatType == 16) {
|
if (a == *Block) {
|
||||||
uint32_t i = oneCluster >> 8;; // (i=oneCluster/256)errechnet den sektor der fat in dem oneCluster ist (rundet immer ab)
|
*Block = (0x0000FFFF & Cluster);
|
||||||
uint32_t j = (oneCluster << 1) - (i << 9); // (j=(oneCluster-256*i)*2 == 2*oneCluster-512*i)errechnet das low byte von
|
return;
|
||||||
// oneCluster
|
|
||||||
|
|
||||||
if (0 == fat_loadSector(i + fat.fatSec)) { // ob neu laden nötig, wird von fat_loadSector geprüft
|
|
||||||
void *bytesOfSec = &fat.sector[j]; // zeiger auf puffer
|
|
||||||
return *(uint16_t *) bytesOfSec; // da der ram auch little endian ist, kann einfach gecastet werden und gut :)
|
|
||||||
}
|
}
|
||||||
}
|
if (Cluster == 0xFFFF) {
|
||||||
// FAT 32**************FAT 32
|
|
||||||
else {
|
|
||||||
uint32_t i = oneCluster >> 7; // (i=oneCluster/128)errechnet den sektor der fat in dem oneCluster ist (rundet immer ab)
|
|
||||||
uint32_t j = (oneCluster << 2) - (i << 9); // (j=(oneCluster-128*i)*4 == oneCluster*4-512*i)errechnet das low byte von
|
|
||||||
// oneCluster
|
|
||||||
|
|
||||||
if (0 == fat_loadSector(i + fat.fatSec)) { // ob neu laden nötig wird von fat_loadSector geprüft
|
|
||||||
void *bytesOfSec = &fat.sector[j]; // zeiger auf puffer
|
|
||||||
return *(uint32_t *) bytesOfSec; // da der ram auch little endian ist, kann einfach gecastet werden und gut :)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// sucht verkettete cluster einer datei, die in einer reihe liegen. worst case: nur ein cluster.
|
|
||||||
// sieht in der fat ab dem cluster offsetCluster nach. sucht die anzahl von MAX_CLUSTERS_IN_ROW,
|
|
||||||
// am stück,falls möglich. prüft ob der cluster neben offsetCluster dazu gehört...
|
|
||||||
// setzt dann fat.endSectors und fat.startSectors. das -1 weil z.b. [95,98] = {95,96,97,98} = 4 sektoren
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_getFatChainClustersInRow(uint32_t offsetCluster)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint16_t i = 0;
|
|
||||||
fat.startSectors = fat_clustToSec(offsetCluster); // setzen des 1. sektors der datei
|
|
||||||
fat.endSectors = fat.startSectors;
|
|
||||||
do {
|
|
||||||
if ((offsetCluster + 1 + i) == fat_getNextCluster(offsetCluster + i))
|
|
||||||
fat.endSectors += fat.secPerClust; // zählen der zusammenhängenden sektoren
|
|
||||||
else {
|
|
||||||
file.lastCluster = offsetCluster + i; // cluster daneben gehört nicht dazu, somit ist offset+i der letzte bekannte
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (i++ < MAX_CLUSTERS_IN_ROW);
|
|
||||||
fat.endSectors += fat.secPerClust - 1;
|
FAT_Byte_Addresse = (Cluster * 2) % BlockSize;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (WRITE==1)
|
FAT_Block_Addresse =
|
||||||
|
((Cluster * 2) / BlockSize) + volume_boot_record_addr + fat_offset;
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
if (FAT_Block_Addresse != FAT_Block_Store) {
|
||||||
// sucht freie zusammenhängende cluster aus der fat. maximal MAX_CLUSTERS_IN_ROW am stück.
|
FAT_Block_Store = FAT_Block_Addresse;
|
||||||
// erst wir der erste frei cluster gesucht, ab offsetCluster(iklusive) und dann wird geschaut, ob der
|
mmc_read_sector(FAT_Block_Addresse, TMP_Buffer);
|
||||||
// daneben auch frei ist. setzt dann fat.endSectors und fat.startSectors. das -1 weil z.b. [95,98] = {95,96,97,98} = 4 sektoren
|
}
|
||||||
// ***************************************************************************************************************
|
Cluster =
|
||||||
void fat_getFreeClustersInRow(uint32_t offsetCluster)
|
(TMP_Buffer[FAT_Byte_Addresse + 1] << 8) +
|
||||||
{
|
TMP_Buffer[FAT_Byte_Addresse];
|
||||||
|
|
||||||
uint16_t i = 1; // variable für anzahl der zu suchenden sektoren
|
|
||||||
while (fat_getNextCluster(offsetCluster))
|
|
||||||
offsetCluster++; // suche des 1. freien clusters
|
|
||||||
|
|
||||||
fat.startSectors = fat_clustToSec(offsetCluster); // setzen des startsektors der freien sektoren (umrechnen von cluster zu sektoren)
|
|
||||||
fat.endSectors = fat.startSectors;
|
|
||||||
|
|
||||||
do { // suche der nächsten freien
|
|
||||||
if (0 == fat_getNextCluster(offsetCluster + i))
|
|
||||||
fat.endSectors += fat.secPerClust; // zählen der zusammenhängenden sektoren
|
|
||||||
else
|
|
||||||
break; // cluster daneben ist nicht frei
|
|
||||||
} while (i++ < MAX_CLUSTERS_IN_ROW);
|
|
||||||
|
|
||||||
fat.endSectors += fat.secPerClust - 1; // -1 weil der erste sektor schon mit zählt z.b. [95,98] = 4 sektoren
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// verkettet ab startCluster bis einschließlich endCluster. verkettet auch den letzten bekannten mit den neu übergebenen !
|
|
||||||
// es ist wegen der fragmentierung der fat nötig, sich den letzten bekannten cluster zu merken,
|
|
||||||
// damit man bei weiteren cluster in einer reihe die alten cluster noch dazu verketten kann (so sind lücken im verketten möglich).
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_setClusterChain(uint32_t startCluster,
|
|
||||||
uint16_t endCluster)
|
|
||||||
{
|
|
||||||
|
|
||||||
fat_setCluster(file.lastCluster, startCluster); // ende der chain setzen, bzw verketten der ketten
|
|
||||||
|
|
||||||
while (startCluster != endCluster) {
|
|
||||||
startCluster++;
|
|
||||||
fat_setCluster(startCluster - 1, startCluster); // verketten der cluster der neuen kette
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
fat_setCluster(startCluster, 0xfffffff); // ende der chain setzen
|
|
||||||
file.lastCluster = endCluster; // ende cluster der kette updaten
|
|
||||||
fat_writeSector(fat.currentSectorNr); // schreiben des fat sektors auf die karte
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fat_read_file(uint16_t Cluster, uint8_t * Buffer, uint32_t BlockCount)
|
||||||
// ***************************************************************************************************************
|
|
||||||
// setzt den cluster inhalt. errechnet den sektor der fat in dem cluster ist, errechnet das low byte von
|
|
||||||
// cluster und setzt dann byteweise den inhalt:content.
|
|
||||||
// prüft ob buffer dirty (zu setztender cluster nicht in jetzt gepuffertem).
|
|
||||||
// prüfung erfolgt in fat_loadSector, dann wird alter vorher geschrieben, sonst gehen dort daten verloren !!
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_setCluster(uint32_t cluster, uint32_t content)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// FAT 16**************FAT 16
|
uint32_t Block = (BlockCount / cluster_size);
|
||||||
if (fat.fatType == 16) {
|
fat_load(Cluster, &Block, Buffer);
|
||||||
uint32_t i = cluster >> 8; // (i=cluster/256)errechnet den sektor der fat in dem cluster ist (rundet immer ab)
|
Block = ((Block - 2) * cluster_size) + cluster_offset;
|
||||||
uint32_t j = (cluster << 1) - (i << 9); // (j=(cluster-256*i)*2 == 2*cluster-512*i)errechnet das low byte von
|
Block += (BlockCount % cluster_size);
|
||||||
// cluster
|
mmc_read_sector(Block, Buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (0 == fat_loadSector(i + fat.fatSec)) { // neu laden (fat_loadSector prüft ob schon gepuffert)
|
void fat_write_file(uint16_t cluster, uint8_t * buffer, uint32_t blockCount)
|
||||||
void *bytesOfSec = &fat.sector[j]; // init des zeigers auf unterste adresse
|
{
|
||||||
*(uint16_t *) bytesOfSec = content; // weil ram auch little endian geht das so :)
|
uint8_t tmp_buffer[513];
|
||||||
fat.bufferDirty = 1; // zeigt an, dass im aktuellen sector geschrieben wurde
|
uint32_t block = (blockCount / cluster_size);
|
||||||
}
|
fat_load(cluster, &block, tmp_buffer);
|
||||||
}
|
block = ((block - 2) * cluster_size) + cluster_offset;
|
||||||
// FAT 32**************FAT 32
|
block += (blockCount % cluster_size);
|
||||||
else {
|
mmc_write_sector(block, buffer);
|
||||||
uint32_t i = cluster >> 7; // (i=cluster/128)errechnet den sektor der fat in dem cluster ist (rundet immer ab)
|
return;
|
||||||
uint32_t j = (cluster << 2) - (i << 9); // (j=(cluster-128*i)*4 == cluster*4-512*i)errechnet das low byte von
|
}
|
||||||
// cluster
|
|
||||||
|
uint8_t fat_search_file(uint8_t * File_Name,
|
||||||
if (0 == fat_loadSector(i + fat.fatSec)) { // neu laden (fat_loadSector prüft ob schon gepuffert)
|
uint16_t * Cluster,
|
||||||
void *bytesOfSec = &fat.sector[j]; // init des zeigers auf unterste adresse
|
uint32_t * Size, uint8_t * Dir_Attrib, uint8_t * Buffer)
|
||||||
*(uint32_t *) bytesOfSec = content; // weil ram auch little endian geht das so :)
|
{
|
||||||
fat.bufferDirty = 1; // zeigt an, dass im aktuellen sector geschrieben wurde
|
uint16_t Dir_Cluster_Store = *Cluster;
|
||||||
|
uint8_t a;
|
||||||
|
for (a = 0; a < 100; a++) {
|
||||||
|
*Cluster =
|
||||||
|
fat_read_dir_ent(Dir_Cluster_Store, a, Size, Dir_Attrib, Buffer);
|
||||||
|
if (*Cluster == 0xffff) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (strcasecmp((char *) File_Name, (char *) Buffer) == 0) {
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// löscht cluster chain, beginnend ab dem startCluster.
|
|
||||||
// sucht cluster, setzt inhalt usw.. abschließend noch den cluster-chain ende markierten cluster löschen.
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
void fat_delClusterChain(uint32_t startCluster)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t nextCluster = startCluster; // tmp variable, wegen verketteter cluster..
|
|
||||||
|
|
||||||
do {
|
|
||||||
startCluster = nextCluster;
|
|
||||||
nextCluster = fat_getNextCluster(startCluster);
|
|
||||||
fat_setCluster(startCluster, 0x00000000);
|
|
||||||
} while (!
|
|
||||||
((nextCluster == 0xfffffff && fat.fatType == 32)
|
|
||||||
|| (nextCluster == 0xffff && fat.fatType == 16)));
|
|
||||||
fat_writeSector(fat.currentSectorNr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************************************************
|
|
||||||
// Initialisiert die Fat(16/32) daten, wie: root directory sektor, daten sektor, fat sektor...
|
|
||||||
// siehe auch Fatgen103.pdf. ist NICHT auf performance optimiert!
|
|
||||||
// byte/sector, byte/cluster, anzahl der fats, sector/fat ... (halt alle wichtigen daten zum lesen ders datei systems!)
|
|
||||||
// *****************************************************************<**********************************************
|
|
||||||
uint8_t fat_loadFatData(uint32_t sec)
|
|
||||||
{
|
|
||||||
|
|
||||||
// offset,size
|
|
||||||
uint16_t rootEntCnt; // 17,2 größe die eine fat belegt
|
|
||||||
uint16_t fatSz16; // 22,2 sectors occupied by one fat16
|
|
||||||
uint32_t fatSz32; // 36,4 sectors occupied by one fat32
|
|
||||||
|
|
||||||
void *vsector;
|
|
||||||
|
|
||||||
if (0 == mmc_read_sector(sec, fat.sector)) { // lesen von fat sector und bestimmen der wichtigen berreiche
|
|
||||||
|
|
||||||
fat.bufferDirty = 0; // init wert des flags
|
|
||||||
|
|
||||||
fat.secPerClust = fat.sector[13]; // fat.secPerClust, 13 only (power of 2)
|
|
||||||
|
|
||||||
vsector = &fat.sector[14];
|
|
||||||
fat.fatSec = *(uint16_t *) vsector;
|
|
||||||
|
|
||||||
vsector = &fat.sector[17];
|
|
||||||
rootEntCnt = *(uint16_t *) vsector;
|
|
||||||
|
|
||||||
vsector = &fat.sector[22];
|
|
||||||
fatSz16 = *(uint16_t *) vsector;
|
|
||||||
|
|
||||||
fat.rootDir = (((rootEntCnt << 5) + 512) / 512) - 1; // ist 0 bei fat 32, sonst der root dir sektor
|
|
||||||
|
|
||||||
if (fat.rootDir == 0) { // FAT32 spezifisch (die prüfung so, ist nicht spezifikation konform !).
|
|
||||||
|
|
||||||
vsector = &fat.sector[36];
|
|
||||||
fatSz32 = *(uint32_t *) vsector;
|
|
||||||
|
|
||||||
vsector = &fat.sector[44];
|
|
||||||
fat.rootDir = *(uint32_t *) vsector;
|
|
||||||
|
|
||||||
fat.dataDirSec = fat.fatSec + (fatSz32 * fat.sector[16]); // data sector (beginnt mit cluster 2)
|
|
||||||
fat.fatType = 32; // fat typ
|
|
||||||
}
|
|
||||||
|
|
||||||
else { // FAT16 spezifisch
|
|
||||||
fat.dataDirSec = fat.fatSec + (fatSz16 * fat.sector[16]) + fat.rootDir; // data sektor (beginnt mit cluster 2)
|
|
||||||
fat.rootDir = fat.dataDirSec - fat.rootDir; // root dir sektor, da nicht im datenbereich (cluster)
|
|
||||||
fat.rootDir += sec; // addiert den startsektor auf "
|
|
||||||
fat.fatType = 16; // fat typ
|
|
||||||
}
|
|
||||||
|
|
||||||
fat.fatSec += sec; // addiert den startsektor auf
|
|
||||||
fat.dataDirSec += sec; // addiert den startsektor auf (umrechnung von absolut auf real)
|
|
||||||
fat.dataDirSec -= 2; // zeigt auf 1. cluster
|
|
||||||
fat.dir = 0; // dir auf '0'==root dir, sonst 1.Cluster des dir
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (1); // sector nicht gelesen, fat nicht initialisiert!!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************************************<<***************
|
|
||||||
// int fat sucht den 1. cluster des dateisystems (fat16/32) auch VBR genannt,
|
|
||||||
// ************************************************************************************************<<***************
|
|
||||||
uint8_t fat_initfat(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t secOfFirstPartition = 0; // ist 1. sektor der 1. partition aus dem MBR
|
|
||||||
|
|
||||||
if (0 == mmc_read_sector(0, fat.sector)) {
|
|
||||||
|
|
||||||
void *vsector = &fat.sector[454]; // startsektor bestimmen
|
|
||||||
secOfFirstPartition = *(uint32_t *) vsector;
|
|
||||||
|
|
||||||
// prüfung ob man schon im VBR gelesen hat (0x6964654d = "Medi")
|
|
||||||
if (secOfFirstPartition == 0x6964654d)
|
|
||||||
return fat_loadFatData(0); // ist superfloppy
|
|
||||||
|
|
||||||
else {
|
|
||||||
return fat_loadFatData(secOfFirstPartition);
|
|
||||||
} // ist partitioniert...
|
|
||||||
}
|
|
||||||
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (SMALL_FILE_SYSTEM==0)
|
|
||||||
|
|
||||||
// *****************************************************************************************************************
|
|
||||||
// bereitet str so auf, dass man es auf die mmc/sd karte schreiben kann.
|
|
||||||
// wandelt z.b. "t.txt" -> "T TXT" oder "main.c" in "MAIN C " => also immer 8.3 und upper case letter
|
|
||||||
// VORSICHT es werden keine Prüfungen gemacht !
|
|
||||||
// *****************************************************************************************************************
|
|
||||||
char *fat_str(char *str)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
uint8_t j = 0;
|
|
||||||
uint8_t c;
|
|
||||||
char tmp[12]; // tmp string zum einfacheren umwandeln
|
|
||||||
|
|
||||||
strcpy(tmp, str);
|
|
||||||
|
|
||||||
for (i = 0; i < 11; i++)
|
|
||||||
str[i] = ' '; // als vorbereitung alles mit leerzeichen füllen
|
|
||||||
str[11] = '\0';
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
c = toupper(tmp[j]);
|
|
||||||
if (c == '\0')
|
|
||||||
return str;
|
|
||||||
if (c != '.')
|
|
||||||
str[i] = c;
|
|
||||||
else
|
|
||||||
i = 7;
|
|
||||||
i++;
|
|
||||||
j++;
|
|
||||||
} while (i < 12);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,78 +1,103 @@
|
|||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _FAT_H
|
#ifndef _FAT_H_
|
||||||
|
#define _FAT_H_
|
||||||
|
#include <string.h>
|
||||||
|
#include "mmc.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
#define _FAT_H
|
#define FAT_DEBUG uart_puts
|
||||||
|
|
||||||
// **************************************************************************************************************************
|
|
||||||
// WICHTIGE SCHLATER: -> hier kann die code größe angepasst werden, zu lasten der funktionalität !
|
|
||||||
// die fat nicht fragmentiert ist !
|
|
||||||
|
|
||||||
#define SMALL_FILE_SYSTEM 0 // wenn 1 dann ist kleines file system, wenn 0 dann komplette file unterstützung !
|
|
||||||
#define WRITE 0 // wenn 1 dann ist write an, wenn 0 dann read only !
|
|
||||||
#define OVER_WRITE 0 // wenn 1 dann kann ffwrite dateien überschreiben (nicht performant), wenn 0 dann nur normales schreiben !
|
|
||||||
#define MAX_CLUSTERS_IN_ROW 256 // gibt an wie viele cluster am stück ohne fat lookup geschrieben bzw gelesen werden können, wenn die fat nicht fragmentiert ist !
|
|
||||||
|
|
||||||
// 1. fat_getFreeRowOfCluster -> fat_getFreeRowOfDir -> fat_makeRowDataEntry -> fat_makeFileEntry -> fat_writeSector "eintrag gemacht !!"
|
|
||||||
// 2. fat_loadSector -> fat_loadRowOfSector -> fat_loadFileDataFromCluster -> fat_loadFileDataFromDir (-> fat_cd) "daten chain"
|
|
||||||
|
|
||||||
// **************************************************************************************************************************
|
|
||||||
// funktionen
|
|
||||||
|
|
||||||
extern uint32_t fat_clustToSec(uint32_t); // rechnet cluster zu 1. sektor des clusters um
|
|
||||||
extern uint32_t fat_secToClust(uint32_t sec); // rechnet sektor zu cluster um!
|
|
||||||
extern uint32_t fat_getNextCluster(uint32_t oneCluster); // fat auf nächsten, verketteten cluster durchsuchen
|
|
||||||
extern uint8_t fat_initfat(void); // initalisierung (durchsucht MBR oder nicht)
|
|
||||||
extern uint8_t fat_writeSector(uint32_t sec); // schreibt sektor auf karte
|
|
||||||
extern void fat_setCluster(uint32_t cluster, uint32_t content); // setzt cluster inhalt in der fat
|
|
||||||
extern void fat_delClusterChain(uint32_t startCluster); // löscht cluster-chain in der fat
|
|
||||||
extern void fat_getFreeRowOfDir(uint32_t dir); // durchsucht directory nach feiem eintrag
|
|
||||||
extern void fat_makeFileEntry(char name[], uint8_t attrib,
|
|
||||||
uint32_t length);
|
|
||||||
extern uint8_t fat_loadSector(uint32_t sec); // läd übergebenen absoluten sektor
|
|
||||||
extern uint8_t fat_loadFileDataFromDir(char name[]); // durchsucht das aktuelle directory
|
|
||||||
extern uint8_t fat_cd(char *); // wechselt directory (start im rootDir)
|
|
||||||
extern uint8_t fat_loadFatData(uint32_t); // läd fat daten
|
|
||||||
extern uint8_t fat_getFreeRowOfCluster(unsigned long secStart); // durchsucht cluster nach freiem eintrag
|
|
||||||
extern void fat_getFreeClustersInRow(uint32_t offsetCluster); // sucht zusammenhängende freie cluster aus der fat
|
|
||||||
extern void fat_getFatChainClustersInRow(uint32_t offsetCluster); // sucht fat-chain cluster die zusammenhängen
|
|
||||||
extern void fat_makeRowDataEntry(uint16_t row, char name[],
|
|
||||||
uint8_t attrib,
|
|
||||||
uint32_t cluster,
|
|
||||||
uint32_t length);
|
|
||||||
extern uint8_t fat_loadRowOfSector(uint16_t); // läd reihe des geladen sektors auf struct:file
|
|
||||||
extern uint8_t fat_loadFileDataFromCluster(uint32_t sec, char name[]); // durchsucht die reihen des geladenen sektors
|
|
||||||
extern void fat_setClusterChain(uint32_t newOffsetCluster,
|
|
||||||
uint16_t length);
|
|
||||||
extern char *fat_str(char *str); // wandelt einen string so, dass er der fat konvention entspricht !
|
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************************************************************************
|
|
||||||
// variablen
|
|
||||||
|
|
||||||
extern struct Fat { // fat daten (1.cluster, root-dir, dir usw.)
|
extern uint16_t fat_root_dir_addr(uint8_t *);
|
||||||
uint8_t sector[512]; // der puffer für sektoren !
|
extern uint16_t fat_read_dir_ent(uint16_t, uint8_t,
|
||||||
uint8_t bufferDirty; // puffer wurde beschrieben, sector muss geschrieben werden bevor er neu geladen wird
|
uint32_t *, uint8_t *, uint8_t *);
|
||||||
uint32_t currentSectorNr; // aktuell geladener Sektor (in sector) //beschleunigt wenn z.b 2* 512 byte puffer vorhanden, oder
|
extern void fat_load(uint16_t, uint32_t *, uint8_t *);
|
||||||
// bei fat operationen im gleichen sektor
|
extern void fat_read_file(uint16_t, uint8_t *, uint32_t);
|
||||||
uint32_t dir; // Direktory zeiger rootDir=='0' sonst(1.Cluster des dir; start auf root)
|
extern void fat_write_file(uint16_t, uint8_t *, uint32_t);
|
||||||
uint32_t rootDir; // Sektor(f16)/Cluster(f32) nr root directory
|
extern void fat_init(uint8_t * Buffer);
|
||||||
uint32_t dataDirSec; // Sektor nr data area
|
extern uint8_t fat_search_file(uint8_t *, uint16_t *,
|
||||||
uint32_t fatSec; // Sektor nr fat area
|
uint32_t *, uint8_t *, uint8_t *);
|
||||||
uint32_t startSectors; // der erste sektor in einer reihe (freie oder verkettete)
|
|
||||||
uint32_t endSectors;
|
|
||||||
uint8_t secPerClust; // anzahl der sektoren pro cluster
|
|
||||||
uint8_t fatType; // fat16 oder fat32 (16 oder 32)
|
|
||||||
} fat;
|
|
||||||
|
|
||||||
extern struct File { // datei infos
|
|
||||||
uint16_t cntOfBytes; // -nicht direkt aus dem dateisystem- zäht geschriebene bytes eines sektors
|
#define BlockSize 512
|
||||||
uint8_t name[13]; // 0,10 datei Name.ext (8.3 = max 11)(MUSS uint8_t weil E5)
|
|
||||||
uint8_t attrib; // 11,1 datei Attribut: 8=value name, 32=datei, 16=Verzeichniss, 15=linux kleingeschrieben eintrag
|
|
||||||
uint8_t row; // reihe im sektor in der die datei infos stehen (reihe 0-15)
|
#define MASTER_BOOT_RECORD 0
|
||||||
uint32_t firstCluster; // 20,2 /26,2 datei 1.cluster hi,low(möglicherweise der einzige) (4-byte)
|
|
||||||
uint32_t length; // 28,4 datei Länge (4-byte)
|
|
||||||
uint32_t lastCluster; // -nicht direkt aus dem dateisystem- letzter cluster der ersten kette
|
#define VBR_ADDR 0x1C6
|
||||||
uint32_t seek; // schreib position in der datei
|
|
||||||
} file;
|
|
||||||
|
#define SPACE 0x20
|
||||||
|
#define DIR_ENTRY_IS_FREE 0xE5
|
||||||
|
#define FIRST_LONG_ENTRY 0x01
|
||||||
|
#define SECOND_LONG_ENTRY 0x42
|
||||||
|
|
||||||
|
|
||||||
|
#define ATTR_LONG_NAME 0x0F
|
||||||
|
#define ATTR_READ_ONLY 0x01
|
||||||
|
#define ATTR_HIDDEN 0x02
|
||||||
|
#define ATTR_SYSTEM 0x04
|
||||||
|
#define ATTR_VOLUME_ID 0x08
|
||||||
|
#define ATTR_DIRECTORY 0x10
|
||||||
|
#define ATTR_ARCHIVE 0x20
|
||||||
|
struct BootSec {
|
||||||
|
uint8_t BS_jmpBoot[3];
|
||||||
|
uint8_t BS_OEMName[8];
|
||||||
|
uint16_t BPB_BytesPerSec;
|
||||||
|
uint8_t BPB_SecPerClus;
|
||||||
|
uint16_t BPB_RsvdSecCnt;
|
||||||
|
uint8_t BPB_NumFATs;
|
||||||
|
uint16_t BPB_RootEntCnt;
|
||||||
|
uint16_t BPB_TotSec16;
|
||||||
|
uint8_t BPB_Media;
|
||||||
|
uint16_t BPB_FATSz16;
|
||||||
|
uint16_t BPB_SecPerTrk;
|
||||||
|
uint16_t BPB_NumHeads;
|
||||||
|
uint32_t BPB_HiddSec;
|
||||||
|
uint32_t BPB_TotSec32;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define BS_DRVNUM 36
|
||||||
|
#define BS_RESERVED1 37
|
||||||
|
#define BS_BOOTSIG 38
|
||||||
|
#define BS_VOLID 39
|
||||||
|
#define BS_VOLLAB 43
|
||||||
|
#define BS_FILSYSTYPE 54
|
||||||
|
|
||||||
|
|
||||||
|
#define BPB_FATSZ32 36
|
||||||
|
#define BPB_EXTFLAGS 40
|
||||||
|
#define BPB_FSVER 42
|
||||||
|
#define BPB_ROOTCLUS 44
|
||||||
|
#define BPB_FSINFO 48
|
||||||
|
#define BPB_BKBOOTSEC 50
|
||||||
|
#define BPB_RESERVED 52
|
||||||
|
|
||||||
|
#define FAT32_BS_DRVNUM 64
|
||||||
|
#define FAT32_BS_RESERVED1 65
|
||||||
|
#define FAT32_BS_BOOTSIG 66
|
||||||
|
#define FAT32_BS_VOLID 67
|
||||||
|
#define FAT32_BS_VOLLAB 71
|
||||||
|
#define FAT32_BS_FILSYSTYPE 82
|
||||||
|
|
||||||
|
struct DirEntry {
|
||||||
|
uint8_t DIR_Name[11];
|
||||||
|
uint8_t DIR_Attr;
|
||||||
|
uint8_t DIR_NTRes;
|
||||||
|
uint8_t DIR_CrtTimeTenth;
|
||||||
|
uint16_t DIR_CrtTime;
|
||||||
|
uint16_t DIR_CrtDate;
|
||||||
|
uint16_t DIR_LastAccDate;
|
||||||
|
uint16_t DIR_FstClusHI;
|
||||||
|
uint16_t DIR_WrtTime;
|
||||||
|
uint16_t DIR_WrtDate;
|
||||||
|
uint16_t DIR_FstClusLO;
|
||||||
|
uint32_t DIR_FileSize;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,525 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "mmc.h"
|
|
||||||
#include "fat.h"
|
|
||||||
#include "file.h"
|
|
||||||
#include "dir.h"
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// 2 möglichkeiten beim öffnen, datei existiert(return 1) oder muss angelegt werden(return 2)
|
|
||||||
// zuerst wird geprüft ob es die datei im verzeichniss gibt. danach wird entschieden, ob die datei geöffnet wird oder angelegt.
|
|
||||||
// -beim offnen werden die bekannten cluster gesucht maximal MAX_CLUSTERS_IN_ROW in reihe. dann wird der 1. sektor der datei auf
|
|
||||||
// den puffer fat.sector geladen. jetzt kann man ffread lesen...
|
|
||||||
// -beim anlegen werden freie cluster gesucht, maximal MAX_CLUSTERS_IN_ROW in reihe. dann wird das struct file gefüllt.
|
|
||||||
// danach wird der dateieintrag gemacht(auf karte). dort wird auch geprüft ob genügend platz im aktuellen verzeichniss existiert.
|
|
||||||
// möglicherweise wird der 1. cluster der datei nochmal geändert. jetzt ist der erste frei sektor bekannt und es kann geschrieben werden.
|
|
||||||
//*******************************************************************************************************************************
|
|
||||||
unsigned char ffopen(char name[]){
|
|
||||||
|
|
||||||
unsigned char file_flag=fat_loadFileDataFromDir(name); //prüfung ob datei vorhanden und evetuelles laden des file struct
|
|
||||||
|
|
||||||
if( file_flag==0 ){ /** Datei existiert, anlegen nicht nötig! **/
|
|
||||||
fat_getFatChainClustersInRow( file.firstCluster ); // verkettete cluster aus der fat-chain suchen.
|
|
||||||
fat_loadSector( fat_clustToSec(file.firstCluster) ); // lät die ersten 512 bytes der datei auf puffer:sector.
|
|
||||||
file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#if (WRITE==1) // anlegen ist schreiben !
|
|
||||||
else{ /** Datei existiert nicht, also anlegen ! (nur wenn schreiben option an ist)**/
|
|
||||||
fat_getFreeClustersInRow(2); // leere cluster suchen, ab cluster 2.
|
|
||||||
strcpy((char*)file.name,(char*)name); // --- füllen des file struct, zum abschließenden schreiben.
|
|
||||||
file.firstCluster=fat_secToClust(fat.startSectors); // 1. cluster der datei
|
|
||||||
file.lastCluster=file.firstCluster;//fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
|
|
||||||
file.attrib=32; // --- file.row wird in der funktion fat_getFreeRowOfDir geschrieben !!
|
|
||||||
file.length=0; // damit da nix drin steht ^^
|
|
||||||
fat_makeFileEntry((char *)file.name,file.attrib,0); // DATEI ANLEGEN auf karte
|
|
||||||
fat.currentSectorNr=fat_clustToSec(file.firstCluster); // setzen des ersten sektors
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************************************************************************************************
|
|
||||||
// schließt die datei operation ab. eigentlich nur nötig wenn geschrieben wurde. es gibt 2 möglichkeiten :
|
|
||||||
// 1. die datei wird geschlossen und es wurde über die alte datei länge hinaus geschrieben.
|
|
||||||
// 2. die datei wird geschlossen und man war innerhalb der datei größe, dann muss nur der aktuelle sektor geschrieben werden.
|
|
||||||
// der erste fall ist komplizierter, weil ermittelt werden muss wie viele sektoren neu beschrieben wurden um diese zu verketten
|
|
||||||
// und die neue datei länge muss ermitt weden. abschließend wird entweder (fall 2) nur der aktuelle sektor geschrieben, oder
|
|
||||||
// der aktuallisierte datei eintrag und die cluster (diese werden verkettet, siehe fileUpdate() ).
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
uint8_t ffclose(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if (WRITE==1) /** 2 möglichkeiten beim schließen !! (lesend spielt keine rolle, nichts muss geupdatet werden) **/
|
|
||||||
|
|
||||||
if (file.length < (file.seek + file.cntOfBytes))
|
|
||||||
fileUpdate(); /** 1.) es wurde über die alte datei größe hinaus geschrieben **/
|
|
||||||
|
|
||||||
else if (fat.bufferDirty == 1)
|
|
||||||
fat_writeSector(fat.currentSectorNr); /** 2.) nicht über alte datei länge hinaus **/
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file.cntOfBytes = 0; // init werte der nötigen zähler
|
|
||||||
file.seek = 0;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// updatet datei eintrag auf der karte und verkettet die dazugehörigen fat cluster.
|
|
||||||
// füllt den aktuell beschriebenen sektor mit 0x00, da sonst die datei nicht richtig angezeigt wird.
|
|
||||||
// darf nur während schreibe operationen aufgerufen werden !
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
void fileUpdate(void){
|
|
||||||
|
|
||||||
unsigned int comp_cntOfBytes=file.cntOfBytes; // sicher nötig wegen schleife...
|
|
||||||
while( comp_cntOfBytes < 512 ){ // sektor ist beschrieben worden, daher nötigenfalls mit 00 füllen
|
|
||||||
fat.sector[comp_cntOfBytes]=0x00; // beschreibt ungenutzte bytes mit 0x00
|
|
||||||
comp_cntOfBytes++;
|
|
||||||
}
|
|
||||||
char name[13]; // zum sichern des dateinamens
|
|
||||||
unsigned long int save_length = file.cntOfBytes + file.seek; // muss gesichert werden, wird sonst von der karte geladen und verändert !
|
|
||||||
strcpy(name,(char *)file.name); // muss gesichert werden, wird sonst von der karte geladen und verändert !
|
|
||||||
|
|
||||||
fat_setClusterChain(fat_secToClust(fat.startSectors),fat_secToClust(fat.currentSectorNr)); // verketten der geschriebenen cluster
|
|
||||||
fat_loadFileDataFromDir(name); // läd sektor, des datei eintrags, und läd daten von karte auf struct file!
|
|
||||||
fat_makeRowDataEntry(file.row,name,32,file.firstCluster,save_length); // macht eintrag im puffer
|
|
||||||
|
|
||||||
fat_writeSector(fat.currentSectorNr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// offset byte wird übergeben. es wird durch die sektoren der datei gespult (gerechnet), bis der sektor mit dem offset byte erreicht
|
|
||||||
// ist, dann wird der sektor geladen und der zähler für die bytes eines sektors gesetzt. wenn das byte nicht in den sektoren ist,
|
|
||||||
// die "vorgesucht" wurden, müssen noch weitere sektoren der datei gesucht werden (sec > fat.endSectors).
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
void ffseek(unsigned long int offset){
|
|
||||||
|
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
#if (OVER_WRITE==1) // man muss den dateieintrag updaten, um die daten zu retten !!
|
|
||||||
if( file.seek > file.length ) fileUpdate(); // fat verketten und datei update auf der karte !
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fat_getFatChainClustersInRow(file.firstCluster); // suchen von anfang der cluster chain aus !
|
|
||||||
unsigned long int sec=fat.startSectors; // sektor variable zum durchgehen durch die sektoren
|
|
||||||
file.seek=0; // weil auch von anfang an der chain gesucht wird mit 0 initialisiert
|
|
||||||
|
|
||||||
while(offset>=512){ /** suchen des sektors in dem offset ist **/
|
|
||||||
sec++; // da byte nicht in diesem sektor ist, muss hochgezählt werden
|
|
||||||
offset-=512; // ein sektor weniger in dem das byte sein kann
|
|
||||||
file.seek+=512; // file.seek update, damit bei ffclose() die richtige file.length herauskommt
|
|
||||||
if ( sec > fat.endSectors ){ // es müssen mehr sektoren der datei gesucht werden
|
|
||||||
fat_getFatChainClustersInRow(fat_getNextCluster( file.lastCluster ) ); // nachladen von clustern in der chain
|
|
||||||
sec=fat.startSectors; // setzen des 1. sektors der neu geladenen, zum weitersuchen !
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
|
|
||||||
fat_loadSector(sec); // sektor mit offset byte laden
|
|
||||||
file.cntOfBytes = offset; // setzen des lese zählers
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (SMALL_FILE_SYSTEM==0)
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// wechselt verzeichniss. start immer im root Dir.
|
|
||||||
// MUSS in das direktory gewechselt werden, in dem die datei zum lesen/schreiben ist !
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
uint8_t ffcd(char name[])
|
|
||||||
{
|
|
||||||
return (fat_cd(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// zeigt reihen eines clusters an, wird für ffls benötigt !
|
|
||||||
// es wird ab dem start sektor start_sec, der dazugehörige cluster angezeigt. geprüft wird ob es ein richtiger
|
|
||||||
// eintrag in der reihe ist (nicht gelöscht, nicht frei usw). die sektoren des clusters werden nachgeladen.
|
|
||||||
// die dateien werden mit namen und datei größe angezeigt.
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
|
|
||||||
void lsRowsOfClust(uint32_t start_sec)
|
|
||||||
{
|
|
||||||
uint8_t row; // reihen
|
|
||||||
uint8_t sec = 0; // sektoren
|
|
||||||
do {
|
|
||||||
fat_loadSector(start_sec + sec); // sektoren des clusters laden
|
|
||||||
for (row = 0; row < 16; row++) { // geht durch reihen des sektors
|
|
||||||
fat_loadRowOfSector(row); // reihe eines sektors (auf dem puffer) laden
|
|
||||||
if ((file.name[0] != 0xE5 && file.name[0] != 0x00)) {
|
|
||||||
if (file.attrib == 0x20)
|
|
||||||
printf("Name: %s Size:%li\n", file.name, file.length);
|
|
||||||
if (file.attrib == 0x10)
|
|
||||||
printf("Dir: %s\n", file.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (++sec < fat.secPerClust);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ffls(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t clust; // cluster
|
|
||||||
uint16_t s; // fat16 root dir sektoren
|
|
||||||
if (fat.dir == 0 && fat.fatType == 16) { // IM ROOTDIR. fat16
|
|
||||||
for (s = 0; s < (uint16_t) (fat.dataDirSec + 2 - fat.rootDir); s++) { // zählt durch RootDir sektoren (errechnet anzahl
|
|
||||||
lsRowsOfClust(fat.rootDir + s); // zeigt reihen eines root dir clust an
|
|
||||||
}
|
|
||||||
printf("Fat16\n");
|
|
||||||
} else {
|
|
||||||
if (fat.dir == 0 && fat.fatType == 32)
|
|
||||||
clust = fat.rootDir; // IM ROOTDIR. fat32
|
|
||||||
else
|
|
||||||
clust = fat.dir; // NICHT ROOT DIR
|
|
||||||
while (!((clust == 0xfffffff && fat.fatType == 32) || (clust == 0xffff && fat.fatType == 16))) { // prüft ob weitere
|
|
||||||
lsRowsOfClust(fat_clustToSec(clust)); // zeigt reihen des clusters an
|
|
||||||
clust = fat_getNextCluster(clust); // liest nächsten cluster des dir-eintrags
|
|
||||||
}
|
|
||||||
printf("Fat32\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lsRowsOfClust_smc(uint32_t start_sec)
|
|
||||||
{
|
|
||||||
uint8_t row; // reihen
|
|
||||||
uint8_t sec = 0; // sektoren
|
|
||||||
do {
|
|
||||||
fat_loadSector(start_sec + sec); // sektoren des clusters laden
|
|
||||||
for (row = 0; row < 16; row++) { // geht durch reihen des sektors
|
|
||||||
fat_loadRowOfSector(row); // reihe eines sektors (auf dem puffer) laden
|
|
||||||
if ((file.name[0] != 0xE5 && file.name[0] != 0x00)) {
|
|
||||||
if (file.attrib == 0x20)
|
|
||||||
dir_entry_add(file.firstCluster, file.name, file.length ,file.attrib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (++sec < fat.secPerClust);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ffls_smc(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t clust; // cluster
|
|
||||||
uint16_t s; // fat16 root dir sektoren
|
|
||||||
if (fat.dir == 0 && fat.fatType == 16) { // IM ROOTDIR. fat16
|
|
||||||
for (s = 0; s < (uint16_t) (fat.dataDirSec + 2 - fat.rootDir); s++) { // zählt durch RootDir sektoren (errechnet anzahl
|
|
||||||
lsRowsOfClust_smc(fat.rootDir + s); // zeigt reihen eines root dir clust an
|
|
||||||
}
|
|
||||||
printf("Fat16\n");
|
|
||||||
} else {
|
|
||||||
if (fat.dir == 0 && fat.fatType == 32)
|
|
||||||
clust = fat.rootDir; // IM ROOTDIR. fat32
|
|
||||||
else
|
|
||||||
clust = fat.dir; // NICHT ROOT DIR
|
|
||||||
while (!((clust == 0xfffffff && fat.fatType == 32) || (clust == 0xffff && fat.fatType == 16))) { // prüft ob weitere
|
|
||||||
lsRowsOfClust_smc(fat_clustToSec(clust)); // zeigt reihen des clusters an
|
|
||||||
clust = fat_getNextCluster(clust); // liest nächsten cluster des dir-eintrags
|
|
||||||
}
|
|
||||||
printf("Fat32\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// wechselt in das parent verzeichniss (ein verzeichniss zurück !)
|
|
||||||
// die variable fat.dir enthält den start cluster des direktory in dem man sich grade befindet, anhand diesem,
|
|
||||||
// kann der "." bzw ".." eintrag im ersten sektor des direktory ausgelesen und das parent direktory bestimmt werden.
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
uint8_t ffcdLower(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (fat.dir == 0)
|
|
||||||
return (1); // im root dir, man kann nicht höher !
|
|
||||||
|
|
||||||
fat_loadSector(fat_clustToSec(fat.dir)); // läd 1. sektor des aktuellen direktory.
|
|
||||||
fat_loadRowOfSector(1); // ".." eintrag (parent dir) ist 0 wenn parent == root
|
|
||||||
fat.dir = file.firstCluster; // dir setzen
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __AVR_ATmega8__
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// erstellt einen dir eintrag im aktuellen verzeichniss.
|
|
||||||
// prüft ob es den den dir-namen schon gibt, dann wird nichts angelegt.
|
|
||||||
// wenn ok, dann wird ein freier cluster gesucht, als ende markiert, der eintrag ins dir geschrieben.
|
|
||||||
// dann wird der cluster des dirs aufbereitet. der erste sektor des clusters enthält den "." und ".." eintrag.
|
|
||||||
// der "." hat den 1. cluster des eigenen dirs. der ".." eintrag ist der 1. cluster des parent dirs.
|
|
||||||
// ein dir wird immer mit 0x00 initialisiert ! also alle einträge der sektoren des clusters ( bis auf . und .. einträge)!
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
void ffmkdir(char name[]){
|
|
||||||
|
|
||||||
unsigned char i;
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
if(0==fat_loadFileDataFromDir(name))return ; // prüft ob dirname im dir schon vorhanden, wenn ja, abbruch !
|
|
||||||
|
|
||||||
// cluster in fat setzen, und ordner eintrg im aktuellen verzeichniss machen.
|
|
||||||
fat_getFreeClustersInRow(2); // holt neue freie cluster, ab cluster 2 ...
|
|
||||||
fat_setCluster(fat_secToClust(fat.startSectors),0x0fffffff); // fat16/32 cluster chain ende setzen. (neuer ordner in fat)
|
|
||||||
file.firstCluster=fat_secToClust(fat.startSectors); // dammit fat_makeFileEntry den cluster richtig setzen kann
|
|
||||||
fat_makeFileEntry(name,0x10,0); // macht dir eintrag im aktuellen verzeichniss (legt ordner im partent verzeichniss an)
|
|
||||||
|
|
||||||
// aufbereiten des puffers
|
|
||||||
j=511;
|
|
||||||
do{
|
|
||||||
fat.sector[j]=0x00; //schreibt puffer fat.sector voll mit 0x00==leer
|
|
||||||
}while(j--);
|
|
||||||
|
|
||||||
// aufbereiten des clusters
|
|
||||||
for(i=1;i<fat.secPerClust;i++){ // ein dir cluster muss mit 0x00 initialisiert werden !
|
|
||||||
fat_writeSector(fat.startSectors+i); // löschen des cluster (überschreibt mit 0x00), wichtig bei ffls!
|
|
||||||
}
|
|
||||||
|
|
||||||
// aufbereiten des neuen dir sektors mit "." und ".." eintraegen !
|
|
||||||
fat_makeRowDataEntry(0,". ",0x10,file.firstCluster,0); // macht "." eintrag des dirs
|
|
||||||
fat_makeRowDataEntry(1,".. ",0x10,fat.dir,0); // macht ".." eintrag des dirs
|
|
||||||
fat_writeSector(fat_clustToSec(file.firstCluster)); // schreibt einträge auf karte !
|
|
||||||
}
|
|
||||||
#endif //WRITE
|
|
||||||
#endif // ffmkdir wegen atmega8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (WRITE==1)
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// löscht datei/ordner aus aktuellem verzeichniss, wenn es die datei gibt.
|
|
||||||
// löscht dateien und ordner rekursiv !
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
uint8_t ffrm(char name[])
|
|
||||||
{
|
|
||||||
|
|
||||||
if (0 == fat_loadFileDataFromDir(name)) { // datei oder ordner ist vorhanden, nur dann lösch operation
|
|
||||||
|
|
||||||
if (file.attrib != 0x10) { // ist datei.
|
|
||||||
fat.sector[file.row << 5] = 0xE5; // datei gelöscht markieren (file.row*32, damit man auf reihen anfang kommt)
|
|
||||||
if ((file.row - 1) >= 0) { // gibt es einen eintrag davor ?
|
|
||||||
if (fat.sector[(file.row << 5) - 21] == 0x0f)
|
|
||||||
fat.sector[(file.row << 5) - 32] = 0xE5; // langer datei eintag auch gelöscht.
|
|
||||||
}
|
|
||||||
fat.bufferDirty = 1; // eintrag in puffer gemacht.
|
|
||||||
if (0 == fat_getNextCluster(file.firstCluster))
|
|
||||||
return (0); // 1.cluster ist leer ?!?
|
|
||||||
fat_delClusterChain(file.firstCluster); // löscht die zu der datei gehörige cluster-chain aus der fat.
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
// TODO noch nicht optimal. zu viele schreib vorgänge beim löschen von datei einträgen. max bis zu 16/sektor !
|
|
||||||
else { // ist ordner, dann rekursiv löschen !!
|
|
||||||
#ifndef __AVR_ATmega8__ // mega8 zu klein für die funktionalität....
|
|
||||||
uint32_t parent;
|
|
||||||
uint32_t own;
|
|
||||||
uint32_t clustsOfDir; // um durch die cluster chain eines dirs zu gehen.
|
|
||||||
uint8_t cntSecOfClust = 0;
|
|
||||||
uint8_t i = 0;
|
|
||||||
|
|
||||||
fat.sector[file.row << 5] = 0xE5; // löscht dir eintrag
|
|
||||||
if ((file.row - 1) >= 0) { // gibt es einen eintrag davor (langer datei eintrag)?
|
|
||||||
if (fat.sector[(file.row << 5) - 21] == 0x0f)
|
|
||||||
fat.sector[(file.row << 5) - 32] = 0xE5; // langer datei eintag auch gelöscht
|
|
||||||
}
|
|
||||||
fat.bufferDirty = 1; // puffer eintrag gemacht
|
|
||||||
|
|
||||||
parent = fat.dir; // der ordner in dem der zu löschende ordner ist.
|
|
||||||
own = file.firstCluster; // der 1. cluster des ordners der zu löschen ist.
|
|
||||||
clustsOfDir = file.firstCluster; // die "cluster" des zu löschenden ordners
|
|
||||||
|
|
||||||
do { // geht durch cluster des dirs
|
|
||||||
fat_loadSector(fat_clustToSec(clustsOfDir)); // sektor des dirs laden
|
|
||||||
do { // geht durch sektoren des clusters
|
|
||||||
do { // geht durch reihen des sektors
|
|
||||||
fat_loadRowOfSector(i);
|
|
||||||
|
|
||||||
if (file.attrib != 0x10 && file.attrib != 0x00 && file.name[0] != 0xE5) { // ist kein ordner,noch nicht
|
|
||||||
// gelöscht, kein freier eintrag
|
|
||||||
fat.sector[i << 5] = 0xE5; // erster eintrag der reihe als gelöscht markiert
|
|
||||||
fat.bufferDirty = 1; // puffer eintrag gemacht
|
|
||||||
if (file.attrib == 0x20) { // ist datei!
|
|
||||||
fat_delClusterChain(file.firstCluster); // ist datei, dann cluster-chain der datei löschen
|
|
||||||
fat_loadSector(fat_clustToSec(clustsOfDir) + cntSecOfClust); // sektor neu laden, weil löschen der
|
|
||||||
// chain, den puffer nutzt.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.attrib == 0x10 && file.name[0] == '.') { // "." oder ".." eintrag erkannt, löschen !
|
|
||||||
fat.sector[i << 5] = 0xE5; // eintrag als gelöscht markiert
|
|
||||||
fat.bufferDirty = 1; // puffer eintrag gemacht
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.attrib == 0x10 && file.name[0] != '.' && file.name[0] != 0xE5 && file.name[0] != 0) { // ordner erkannt !
|
|
||||||
fat.sector[i << 5] = 0xE5; // dir eintrag als gelöscht markiert
|
|
||||||
fat.bufferDirty = 1; // puffer eintrag gemacht
|
|
||||||
fat_loadSector(fat_clustToSec(file.firstCluster)); // sektor des dirs laden
|
|
||||||
clustsOfDir = file.firstCluster; // eigenes dir ist file.firstCluster
|
|
||||||
own = file.firstCluster; // eigener start cluster/dir
|
|
||||||
fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen
|
|
||||||
parent = file.firstCluster; // parent sichern.
|
|
||||||
cntSecOfClust = 0; // init von gelesenen sektoren und reihen !
|
|
||||||
i = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.name[0] == 0x00) { // ende des dirs erreicht, wenn nicht voll !!
|
|
||||||
if (parent == fat.dir) { // erfolgreich alles gelöscht
|
|
||||||
fat_delClusterChain(own); // cluster chain des ordners löschen
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
fat_delClusterChain(own); // cluster chain des ordners löschen
|
|
||||||
clustsOfDir = parent; // parent ist jetzt wieder arbeisverzeichniss.
|
|
||||||
own = parent; // arbeitsverzeichniss setzten
|
|
||||||
fat_loadSector(fat_clustToSec(own)); // sektor des dirs laden
|
|
||||||
fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen
|
|
||||||
parent = file.firstCluster; // parent sichern.
|
|
||||||
cntSecOfClust = 0; // init von gelesenen sektoren und reihen !
|
|
||||||
i = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
} while (i < 16); // geht durch reihen des sektors.
|
|
||||||
|
|
||||||
i = 0; // neuer sektor -> reihen von vorne.
|
|
||||||
cntSecOfClust++;
|
|
||||||
fat_loadSector(fat_clustToSec(clustsOfDir) + cntSecOfClust); // läd sektoren des clusters nach
|
|
||||||
} while (cntSecOfClust < fat.secPerClust); // geht durch sektoren des clusters.
|
|
||||||
|
|
||||||
cntSecOfClust = 0; // neuer cluster -> sektoren von vorne.
|
|
||||||
clustsOfDir = fat_getNextCluster(clustsOfDir); // sucht neuen cluster der cluster-chain.
|
|
||||||
} while (!((clustsOfDir == 0xfffffff && fat.fatType == 32) || (clustsOfDir == 0xffff && fat.fatType == 16))); // geht
|
|
||||||
// durch
|
|
||||||
// cluster
|
|
||||||
// des
|
|
||||||
// dirs.
|
|
||||||
fat_delClusterChain(own); // hier landet man, wenn der ordner voll war (auf cluster "ebene")!!
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (1); // fehler, nicht gefunden?
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// liest 512 bytes aus dem puffer fat.sector. dann werden neue 512 bytes der datei geladen, sind nicht genügend verkettete
|
|
||||||
// sektoren in einer reihe bekannt, wird in der fat nachgeschaut. dann werden weiter bekannte nachgeladen...
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
inline uint8_t ffread(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (file.cntOfBytes == 512) { /** EINEN SEKTOR GLESEN (ab hier 2 möglichkeiten !) **/
|
|
||||||
file.cntOfBytes = 0; // byte zähler zurück setzen
|
|
||||||
if (fat.currentSectorNr == fat.endSectors) { /** 1.) nötig mehr sektoren der chain zu laden (mit ein bisschen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes)**/
|
|
||||||
fat_getFatChainClustersInRow(fat_getNextCluster(fat_secToClust(fat.endSectors))); // nachladen von clustern in der chain
|
|
||||||
fat.currentSectorNr = fat.startSectors - 1; // setzen des nächsten sektors um weiter lesen zu können..
|
|
||||||
}
|
|
||||||
fat_loadSector(fat.currentSectorNr + 1); /** 2.) die bekannten in einer reihe reichen noch.(nur alle 512 bytes)**/
|
|
||||||
}
|
|
||||||
|
|
||||||
return fat.sector[file.cntOfBytes++]; // rückgabe, byte des sektors (NACH rückgabe erhöhen von zähler ! )
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (WRITE==1)
|
|
||||||
#if (OVER_WRITE==0) // nicht überschreibende write funktion
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// schreibt 512 byte blöcke auf den puffer fat.sector. dann wird dieser auf die karte geschrieben. wenn genügend feie
|
|
||||||
// sektoren zum beschreiben bekannt sind(datenmenge zu groß), muss nicht in der fat nachgeschaut werden. sollten nicht genügend
|
|
||||||
// zusammenhängende sektoren bekannt sein, werden die alten verkettet und neue gesucht. es ist nötig sich den letzten bekannten
|
|
||||||
// einer kette zu merken -> file.lastCluster, um auch nicht zusammenhängende cluster verketten zu können (fat_setClusterChain macht das)!
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
inline void ffwrite(uint8_t c)
|
|
||||||
{
|
|
||||||
|
|
||||||
fat.sector[file.cntOfBytes++] = c; // schreiben des chars auf den puffer sector und zähler erhöhen (pre-increment)
|
|
||||||
fat.bufferDirty = 1; // puffer dirty weil geschrieben und noch nicht auf karte.
|
|
||||||
|
|
||||||
if (file.cntOfBytes == 512) { /** SEKTOR VOLL ( 2 möglichkeiten ab hier !) **/
|
|
||||||
file.cntOfBytes = 0; // rücksetzen des sektor byte zählers
|
|
||||||
mmc_write_sector(fat.currentSectorNr, fat.sector); /** 1.) vollen sektor auf karte schreiben **/
|
|
||||||
fat.bufferDirty = 0; // puffer jetzt clear, weil grade alles geschrieben.
|
|
||||||
file.seek += 512; // position in der datei erhöhen, weil grade 512 bytes geschrieben
|
|
||||||
if (fat.currentSectorNr == fat.endSectors) { /** 2.) es ist nötig, neue freie zu suchen und die alten zu verketten (mit ein bischen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes) **/
|
|
||||||
fat_setClusterChain(fat_secToClust(fat.startSectors), fat_secToClust(fat.endSectors)); // verketten der beschriebenen
|
|
||||||
fat_getFreeClustersInRow(file.lastCluster); // suchen von leeren sektoren.
|
|
||||||
fat.currentSectorNr = fat.startSectors - 1; // setzen des 1. sektors der neuen reihe zum schreiben.
|
|
||||||
}
|
|
||||||
fat.currentSectorNr++; // nächsten sektor zum beschreiben.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (OVER_WRITE==1) // überschreibende write funktion, nicht performant, weil immer auch noch ein sektor geladen werden muss
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// schreibt 512 byte blöcke auf den puffer fat.sector. dann wird dieser auf die karte geschrieben. wenn genügend feie
|
|
||||||
// sektoren zum beschreiben bekannt sind, muss nicht in der fat nachgeschaut werden. sollten nicht genügend zusammenhängende
|
|
||||||
// sektoren bekannt sein(datenmenge zu groß), werden die alten verkettet und neue gesucht. es ist nötig sich den letzten bekannten einer
|
|
||||||
// kette zu merken -> file.lastCluster, um auch nicht zusammenhängende cluster verketten zu können (fat_setClusterChain macht das)!
|
|
||||||
// es ist beim überschreiben nötig, die schon beschriebenen sektoren der datei zu laden, damit man die richtigen daten
|
|
||||||
// hat. das ist blöd, weil so ein daten overhead von 50% entsteht. da lesen aber schneller als schreiben geht, verliert man nicht 50% an
|
|
||||||
// geschwindigkeit.
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
inline void ffwrite(uint8_t c)
|
|
||||||
{
|
|
||||||
|
|
||||||
fat.sector[file.cntOfBytes++] = c; // schreiben des chars auf den puffer sector und zähler erhöhen (pre-increment)
|
|
||||||
fat.bufferDirty = 1; // puffer dirty weil geschrieben und noch nicht auf karte.
|
|
||||||
|
|
||||||
if (file.cntOfBytes == 512) { /** SEKTOR VOLL ( 2 möglichkeiten ab hier !) **/
|
|
||||||
file.cntOfBytes = 0; // rücksetzen des sektor byte zählers.
|
|
||||||
mmc_write_sector(fat.currentSectorNr, fat.sector); /** 1.) vollen sektor auf karte schreiben**/
|
|
||||||
fat.bufferDirty = 0; // puffer jetzt clear, weil grade alles geschrieben.
|
|
||||||
file.seek += 512; // position in der datei erhöhen, weil grade 512 bytes geschrieben.
|
|
||||||
if (fat.currentSectorNr == fat.endSectors) { /** 2.) es ist nötig, neue freie zu suchen und die alten zu verketten (mit ein bischen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes) **/
|
|
||||||
if (file.seek > file.length) { // außerhalb der datei !!
|
|
||||||
fat_setClusterChain(fat_secToClust(fat.startSectors), fat_secToClust(fat.endSectors)); // verketten der beschriebenen.
|
|
||||||
fat_getFreeClustersInRow(file.lastCluster); // neue leere sektoren benötigt, also suchen.
|
|
||||||
} else {
|
|
||||||
fat_getFatChainClustersInRow(fat_getNextCluster(file.lastCluster)); // noch innerhalb der datei, deshlab verkettete
|
|
||||||
// suchen.
|
|
||||||
}
|
|
||||||
fat.currentSectorNr = fat.startSectors - 1; // setzen des 1. sektors der neuen reihe zum schreiben.
|
|
||||||
}
|
|
||||||
fat.currentSectorNr++; // nächsten sektor zum beschreiben.
|
|
||||||
mmc_read_sector(fat.currentSectorNr, fat.sector); // wegen überschreiben, muss der zu beschreibende sektor geladen werden...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
// schreibt string auf karte, siehe ffwrite()
|
|
||||||
// *******************************************************************************************************************************
|
|
||||||
inline void ffwrites(const char *s)
|
|
||||||
{
|
|
||||||
while (*s)
|
|
||||||
ffwrite(*s++);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _FILE_H
|
|
||||||
|
|
||||||
#define _FILE_H
|
|
||||||
|
|
||||||
// **************************************************************************************************************************
|
|
||||||
// funktionen
|
|
||||||
|
|
||||||
extern inline uint8_t ffread(void); // liest byte-weise aus der datei (puffert immer 512 bytes zwischen)
|
|
||||||
extern inline void ffwrite(uint8_t c); // schreibt ein byte in die geöffnete datei
|
|
||||||
extern inline void ffwrites(const char *s); // schreibt string auf karte
|
|
||||||
|
|
||||||
extern uint8_t ffopen(char name[]); // kann immer nur 1 datei bearbeiten.
|
|
||||||
extern uint8_t ffclose(void); // muss aufgerufen werden bevor neue datei bearbeitet wird.
|
|
||||||
|
|
||||||
extern void ffseek(uint32_t offset); // setzt zeiger:bytesOfSec auf position in der geöffneten datei.
|
|
||||||
extern uint8_t ffcd(char name[]); // wechselt direktory
|
|
||||||
extern void ffls(void); // zeigt direktory inhalt an
|
|
||||||
extern void ffls_smc(void); // zeigt direktory inhalt an
|
|
||||||
extern uint8_t ffcdLower(void); // geht ein direktory zurück, also cd.. (parent direktory)
|
|
||||||
extern uint8_t ffrm(char name[]); // löscht datei aus aktuellem verzeichniss.
|
|
||||||
extern void ffmkdir(char name[]); // legt ordner in aktuellem verzeichniss an.
|
|
||||||
void lsRowsOfClust(uint32_t start_sec); // zeigt reihen eines clusters an, ab start_sec
|
|
||||||
void fileUpdate(void); // updatet datei eintrag auf karte
|
|
||||||
|
|
||||||
// **************************************************************************************************************************//
|
|
||||||
// #######################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _HARDWARE_H
|
|
||||||
/*
|
|
||||||
hier sind die beiden hardware abhängigen bibliotheken zu includen !
|
|
||||||
welchen umfang diese haben müssen (an funktionen), muss man in den bibliotheken nachsehen.
|
|
||||||
*/
|
|
||||||
#define _HARDWARE_H
|
|
||||||
#include "uart.h"
|
|
||||||
#include "mmc.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
File: main.smc
|
File: main.smc
|
||||||
Time: Sun, 09 Aug 2009 11:41:19
|
Time: Thu, 06 Aug 2009 08:37:50
|
||||||
*/
|
*/
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <loader.h>
|
#include <loader.h>
|
||||||
|
|||||||
@@ -21,16 +21,16 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
#include <util/delay.h>
|
#include <util/delay.h> /* for _delay_ms() */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
|
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "oddebug.h"
|
#include "oddebug.h" /* This is also an example for using debug macros */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "requests.h"
|
#include "requests.h" /* The custom request numbers we use */
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@@ -42,16 +42,16 @@
|
|||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
#include "rle.h"
|
#include "rle.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "command.h"
|
|
||||||
#include "shared_memory.h"
|
#include "shared_memory.h"
|
||||||
#include "testing.h"
|
#include "mmc.h"
|
||||||
|
#include "fat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern const char _rom[] PROGMEM;
|
extern const char _rom[] PROGMEM;
|
||||||
extern FILE uart_stdout;
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC | DEBUG_FAT);
|
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC);
|
||||||
|
|
||||||
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||||
uint32_t req_addr = 0;
|
uint32_t req_addr = 0;
|
||||||
@@ -60,8 +60,6 @@ uint32_t req_size;
|
|||||||
uint8_t req_bank;
|
uint8_t req_bank;
|
||||||
uint32_t req_bank_size;
|
uint32_t req_bank_size;
|
||||||
uint16_t req_bank_cnt;
|
uint16_t req_bank_cnt;
|
||||||
uint8_t req_percent;
|
|
||||||
uint8_t req_percent_last;
|
|
||||||
uint8_t req_state = REQ_STATUS_IDLE;
|
uint8_t req_state = REQ_STATUS_IDLE;
|
||||||
uint8_t rx_remaining = 0;
|
uint8_t rx_remaining = 0;
|
||||||
uint8_t tx_remaining = 0;
|
uint8_t tx_remaining = 0;
|
||||||
@@ -79,8 +77,76 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
usbRequest_t *rq = (void *) data;
|
usbRequest_t *rq = (void *) data;
|
||||||
uint8_t ret_len = 0;
|
uint8_t ret_len = 0;
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
if (rq->bRequest == USB_UPLOAD_INIT) {
|
||||||
|
|
||||||
if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
if (req_state != REQ_STATUS_IDLE) {
|
||||||
|
debug(DEBUG_USB,
|
||||||
|
"USB_UPLOAD_INIT: ERROR state is not REQ_STATUS_IDLE\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_bank = 0;
|
||||||
|
rx_remaining = 0;
|
||||||
|
req_bank_size = (uint32_t) 1 << rq->wValue.word;
|
||||||
|
sync_errors = 0;
|
||||||
|
crc = 0;
|
||||||
|
debug(DEBUG_USB, "USB_UPLOAD_INIT: bank_size=0x%08lx\n", req_bank_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_UPLOAD_ADDR) {
|
||||||
|
|
||||||
|
req_state = REQ_STATUS_UPLOAD;
|
||||||
|
req_addr = rq->wValue.word;
|
||||||
|
req_addr = req_addr << 16;
|
||||||
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
|
if (rx_remaining) {
|
||||||
|
sync_errors++;
|
||||||
|
debug
|
||||||
|
(DEBUG_USB,
|
||||||
|
"USB_UPLOAD_ADDR: Out of sync addr=0x%lx remain=%i packet=%i sync_error=%i\n",
|
||||||
|
req_addr, rx_remaining, rq->wLength.word, sync_errors);
|
||||||
|
ret_len = 0;
|
||||||
|
}
|
||||||
|
rx_remaining = rq->wLength.word;
|
||||||
|
ret_len = USB_MAX_TRANS;
|
||||||
|
|
||||||
|
|
||||||
|
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||||
|
debug(DEBUG_USB,
|
||||||
|
"USB_UPLOAD_ADDR: bank=0x%02x addr=0x%08lx crc=%04x\n",
|
||||||
|
req_bank, req_addr, crc_check_bulk_memory(req_addr - 0x1000,
|
||||||
|
req_addr,
|
||||||
|
req_bank_size));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (req_addr && req_addr % req_bank_size == 0) {
|
||||||
|
debug(DEBUG_USB, "USB_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx\n",
|
||||||
|
req_bank, req_addr);
|
||||||
|
|
||||||
|
req_bank++;
|
||||||
|
// shared_memory_put(SHARED_MEM_CMD_UPLOAD_PROGESS,req_bank);
|
||||||
|
}
|
||||||
|
ret_len = USB_MAX_TRANS;
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_DOWNLOAD_INIT) {
|
||||||
|
debug(DEBUG_USB, "USB_DOWNLOAD_INIT\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_DOWNLOAD_ADDR) {
|
||||||
|
debug(DEBUG_USB, "USB_DOWNLOAD_ADDR\n");
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
||||||
|
|
||||||
req_bank = 0;
|
req_bank = 0;
|
||||||
rx_remaining = 0;
|
rx_remaining = 0;
|
||||||
@@ -89,14 +155,13 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
||||||
req_bank_cnt = rq->wIndex.word;
|
req_bank_cnt = rq->wIndex.word;
|
||||||
req_addr_end = (uint32_t) req_bank_size *req_bank_cnt;
|
req_addr_end = (uint32_t) req_bank_size *req_bank_cnt;
|
||||||
req_percent = 0;
|
|
||||||
req_percent_last = 0;
|
|
||||||
sync_errors = 0;
|
sync_errors = 0;
|
||||||
debug(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
"USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n",
|
"USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n",
|
||||||
req_bank_size, req_bank_cnt, req_addr_end);
|
req_bank_size, req_bank_cnt, req_addr_end);
|
||||||
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, req_bank_cnt);
|
shared_memory_put(SHARED_MEM_CMD_BANK_COUNT, req_bank_cnt);
|
||||||
if (req_addr == 0x000000) {
|
if (req_addr == 0x000000) {
|
||||||
timer_start();
|
timer_start();
|
||||||
}
|
}
|
||||||
@@ -111,7 +176,6 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_addr = req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
rx_remaining = rq->wLength.word;
|
rx_remaining = rq->wLength.word;
|
||||||
|
|
||||||
|
|
||||||
if (req_addr && req_addr % req_bank_size == 0) {
|
if (req_addr && req_addr % req_bank_size == 0) {
|
||||||
#ifdef FLT_DEBUG
|
#ifdef FLT_DEBUG
|
||||||
debug(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
@@ -123,7 +187,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_bank, req_addr, timer_stop_int());
|
req_bank, req_addr, timer_stop_int());
|
||||||
#endif
|
#endif
|
||||||
req_bank++;
|
req_bank++;
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_bank);
|
shared_memory_put(SHARED_MEM_CMD_UPLOAD_PROGESS, req_bank);
|
||||||
sram_bulk_write_start(req_addr);
|
sram_bulk_write_start(req_addr);
|
||||||
timer_start();
|
timer_start();
|
||||||
|
|
||||||
@@ -142,16 +206,6 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_addr = req_addr << 16;
|
req_addr = req_addr << 16;
|
||||||
req_addr = req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
rx_remaining = rq->wLength.word;
|
rx_remaining = rq->wLength.word;
|
||||||
|
|
||||||
req_percent = (uint32_t)( 100 * req_addr ) / req_addr_end;
|
|
||||||
if (req_percent!=req_percent_last){
|
|
||||||
//debug(DEBUG_USB,
|
|
||||||
// "USB_BULK_UPLOAD_ADDR: precent=%i\n", req_percent);
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_percent);
|
|
||||||
sram_bulk_write_start(req_addr);
|
|
||||||
}
|
|
||||||
req_percent_last = req_percent;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (req_addr && (req_addr % 0x1000) == 0) {
|
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||||
debug(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
@@ -175,7 +229,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
#endif
|
#endif
|
||||||
req_bank++;
|
req_bank++;
|
||||||
timer_start();
|
timer_start();
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_CURRENT, req_bank);
|
shared_memory_put(SHARED_MEM_CMD_BANK_CURRENT, req_bank);
|
||||||
sram_bulk_write_start(req_addr);
|
sram_bulk_write_start(req_addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -192,7 +246,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
debug(DEBUG_USB, "USB_BULK_UPLOAD_END:\n");
|
debug(DEBUG_USB, "USB_BULK_UPLOAD_END:\n");
|
||||||
req_state = REQ_STATUS_IDLE;
|
req_state = REQ_STATUS_IDLE;
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
shared_memory_put(SHARED_MEM_CMD_UPLOAD_END, 0);
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -258,6 +312,174 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
#define ENABLE_TEST
|
||||||
|
#ifdef ENABLE_TEST
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t buffer[512];
|
||||||
|
|
||||||
|
void test_sdcard(){
|
||||||
|
uint16_t fat_cluster = 0;
|
||||||
|
uint8_t fat_attrib = 0;
|
||||||
|
uint32_t fat_size = 0;
|
||||||
|
uint32_t rom_addr = 0;
|
||||||
|
uint8_t bank_cnt = 0;
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint16_t block_cnt;
|
||||||
|
uint16_t clustervar;
|
||||||
|
uint8_t dir_attrib = 0;
|
||||||
|
uint32_t file_size = 0;
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
#define FILENAME "mrdo.smc" //failed
|
||||||
|
#define ROMSIZE 2 // 4 == 4mbit == 512kb
|
||||||
|
#define BUFFER_SIZE 512
|
||||||
|
#define BLOCKS (ROMSIZE << 8)
|
||||||
|
|
||||||
|
while ( mmc_init() !=0) {
|
||||||
|
info("No sdcard...\n");
|
||||||
|
}
|
||||||
|
info("MMC Init done\n");
|
||||||
|
fat_init(read_buffer);
|
||||||
|
info("FAT Init done.\n");
|
||||||
|
|
||||||
|
|
||||||
|
info("\r\nDirectory\r\n");
|
||||||
|
for (i = 1;i < 240;i++){
|
||||||
|
clustervar = fat_read_dir_ent(0,i,&file_size,&dir_attrib,buffer);
|
||||||
|
if (clustervar == 0xffff){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
info("Cluster = %4x DirA = %2x FileName = %s size=%li\n",clustervar,dir_attrib,buffer,file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
info("Look for %s\n",FILENAME);
|
||||||
|
|
||||||
|
if (fat_search_file((uint8_t*)FILENAME,
|
||||||
|
&fat_cluster,
|
||||||
|
&fat_size,
|
||||||
|
&fat_attrib,
|
||||||
|
read_buffer) == 1) {
|
||||||
|
|
||||||
|
|
||||||
|
for (block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
|
||||||
|
fat_read_file (fat_cluster,read_buffer,block_cnt);
|
||||||
|
|
||||||
|
if (block_cnt && block_cnt % 64 == 0){
|
||||||
|
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
||||||
|
bank_cnt++;
|
||||||
|
crc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
|
||||||
|
printf("Done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_read_write()
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
uint32_t addr;
|
||||||
|
avr_bus_active();
|
||||||
|
addr = 0x000000;
|
||||||
|
i = 1;
|
||||||
|
while (addr++ <= 0x0000ff) {
|
||||||
|
sram_write(addr, i++);
|
||||||
|
}
|
||||||
|
addr = 0x000000;
|
||||||
|
while (addr++ <= 0x0000ff) {
|
||||||
|
info("read addr=0x%08lx %x\n", addr, sram_read(addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_bulk_read_write()
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
uint32_t addr;
|
||||||
|
avr_bus_active();
|
||||||
|
addr = 0x000000;
|
||||||
|
i = 0;
|
||||||
|
sram_bulk_write_start(addr);
|
||||||
|
while (addr++ <= 0x8000) {
|
||||||
|
sram_bulk_write(i++);
|
||||||
|
sram_bulk_write_next();
|
||||||
|
}
|
||||||
|
sram_bulk_write_end();
|
||||||
|
|
||||||
|
addr = 0x000000;
|
||||||
|
sram_bulk_read_start(addr);
|
||||||
|
while (addr <= 0x8000) {
|
||||||
|
info("addr=0x%08lx %x\n", addr, sram_bulk_read());
|
||||||
|
sram_bulk_read_next();
|
||||||
|
addr++;
|
||||||
|
}
|
||||||
|
sram_bulk_read_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
||||||
|
{
|
||||||
|
uint32_t addr = 0;
|
||||||
|
uint8_t c;
|
||||||
|
sram_bulk_read_start(bottom_addr);
|
||||||
|
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
|
c = sram_bulk_read();
|
||||||
|
if (c != 0xff)
|
||||||
|
info("addr=0x%08lx c=0x%x\n", addr, c);
|
||||||
|
sram_bulk_read_next();
|
||||||
|
}
|
||||||
|
sram_bulk_read_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_crc()
|
||||||
|
{
|
||||||
|
info("test_crc: clear\n");
|
||||||
|
avr_bus_active();
|
||||||
|
sram_bulk_set(0x000000, 0x10000, 0xff);
|
||||||
|
info("test_crc: crc\n");
|
||||||
|
crc_check_bulk_memory(0x000000, 0x10000, 0x8000);
|
||||||
|
info("test_crc: check\n");
|
||||||
|
test_non_zero_memory(0x000000, 0x10000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void send_reset()
|
||||||
|
{
|
||||||
|
info("Reset Snes\n");
|
||||||
|
snes_reset_on();
|
||||||
|
snes_reset_lo();
|
||||||
|
_delay_ms(2);
|
||||||
|
snes_reset_hi();
|
||||||
|
snes_reset_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_irq()
|
||||||
|
{
|
||||||
|
snes_irq_on();
|
||||||
|
snes_irq_lo();
|
||||||
|
_delay_us(20);
|
||||||
|
snes_irq_hi();
|
||||||
|
snes_irq_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_rom_mode()
|
||||||
|
{
|
||||||
|
if (req_bank_size == 0x8000) {
|
||||||
|
snes_lorom();
|
||||||
|
info("Set Snes lowrom \n");
|
||||||
|
} else {
|
||||||
|
snes_hirom();
|
||||||
|
info("Set Snes hirom \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void usb_connect()
|
void usb_connect()
|
||||||
@@ -283,15 +505,21 @@ void usb_connect()
|
|||||||
void boot_startup_rom()
|
void boot_startup_rom()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
info("Activate AVR bus\n");
|
info("Activate AVR bus\n");
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
|
|
||||||
|
|
||||||
info("IRQ off\n");
|
info("IRQ off\n");
|
||||||
snes_irq_lo();
|
snes_irq_lo();
|
||||||
snes_irq_off();
|
snes_irq_off();
|
||||||
|
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
info("Set Snes lowrom \n");
|
info("Set Snes lowrom \n");
|
||||||
|
|
||||||
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
||||||
dump_memory(0x10000 - 0x100, 0x10000);
|
dump_memory(0x10000 - 0x100, 0x10000);
|
||||||
|
|
||||||
snes_reset_hi();
|
snes_reset_hi();
|
||||||
snes_reset_off();
|
snes_reset_off();
|
||||||
snes_irq_lo();
|
snes_irq_lo();
|
||||||
@@ -302,46 +530,46 @@ void boot_startup_rom()
|
|||||||
info("Disable snes WR\n");
|
info("Disable snes WR\n");
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
info("Activate Snes bus\n");
|
info("Activate Snes bus\n");
|
||||||
_delay_ms(20);
|
_delay_ms(100);
|
||||||
|
info("Reset Snes\n");
|
||||||
send_reset();
|
send_reset();
|
||||||
_delay_ms(200);
|
_delay_ms(100);
|
||||||
|
#if 0
|
||||||
|
uint8_t i = 0;
|
||||||
|
i = 20;
|
||||||
|
info("Wait");
|
||||||
|
while (--i) {
|
||||||
|
_delay_ms(500);
|
||||||
|
info(".");
|
||||||
|
}
|
||||||
|
info("\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
uart_init();
|
uart_init();
|
||||||
stdout = &uart_stdout;
|
stdout = &uart_stdout;
|
||||||
|
|
||||||
|
|
||||||
info("Sytem start\n");
|
info("Sytem start\n");
|
||||||
system_init();
|
system_init();
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
avr_bus_active();
|
|
||||||
info("Activate AVR bus\n");
|
|
||||||
info("IRQ off\n");
|
|
||||||
snes_irq_lo();
|
|
||||||
snes_irq_off();
|
|
||||||
info("Set Snes lowrom\n");
|
|
||||||
snes_lorom();
|
|
||||||
info("Disable snes WR\n");
|
|
||||||
snes_wr_disable();
|
|
||||||
test_sdcard();
|
test_sdcard();
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
test_read_write();
|
||||||
|
test_bulk_read_write();
|
||||||
|
test_crc();
|
||||||
|
while (1);
|
||||||
|
#endif
|
||||||
|
|
||||||
info("Boot startup rom\n");
|
info("Boot startup rom\n");
|
||||||
boot_startup_rom();
|
boot_startup_rom();
|
||||||
|
|
||||||
|
|
||||||
usbInit();
|
usbInit();
|
||||||
usb_connect();
|
usb_connect();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
info("Activate AVR bus\n");
|
info("Activate AVR bus\n");
|
||||||
info("IRQ off\n");
|
info("IRQ off\n");
|
||||||
@@ -356,18 +584,25 @@ int main(void)
|
|||||||
while (req_state != REQ_STATUS_SNES) {
|
while (req_state != REQ_STATUS_SNES) {
|
||||||
usbPoll();
|
usbPoll();
|
||||||
}
|
}
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
shared_memory_put(SHARED_MEM_CMD_TERMINATE, 0);
|
||||||
info("USB poll done\n");
|
info("USB poll done\n");
|
||||||
|
snes_reset_hi();
|
||||||
|
snes_reset_off();
|
||||||
|
snes_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
info("IRQ off\n");
|
||||||
set_rom_mode();
|
set_rom_mode();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
info("Disable snes WR\n");
|
info("Disable snes WR\n");
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
info("Activate Snes bus\n");
|
info("Activate Snes bus\n");
|
||||||
_delay_ms(100);
|
_delay_ms(100);
|
||||||
|
info("Reset Snes\n");
|
||||||
send_reset();
|
send_reset();
|
||||||
|
|
||||||
info("Poll\n");
|
info("Poll\n");
|
||||||
while (req_state != REQ_STATUS_AVR) {
|
while (req_state != REQ_STATUS_AVR) {
|
||||||
|
|
||||||
usbPoll();
|
usbPoll();
|
||||||
|
|
||||||
#ifdef DO_IRQ
|
#ifdef DO_IRQ
|
||||||
@@ -405,8 +640,6 @@ int main(void)
|
|||||||
info("Read 0x3000=%c\n", c);
|
info("Read 0x3000=%c\n", c);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
info("Boot startup rom\n");
|
|
||||||
boot_startup_rom();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,32 +1,5 @@
|
|||||||
/*
|
|
||||||
* ####################################################################################### Connect AVR to MMC/SD
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Ulrich Radig
|
|
||||||
*
|
|
||||||
* Bei Fragen und Verbesserungen wendet euch per EMail an
|
|
||||||
*
|
|
||||||
* mail@ulrichradig.de
|
|
||||||
*
|
|
||||||
* oder im Forum meiner Web Page : www.ulrichradig.de
|
|
||||||
*
|
|
||||||
* Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software
|
|
||||||
* Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder
|
|
||||||
* späteren Version.
|
|
||||||
*
|
|
||||||
* Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
|
|
||||||
* sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU
|
|
||||||
* General Public License.
|
|
||||||
*
|
|
||||||
* Sie sollten eine Kopie der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
* #######################################################################################
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
|
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
uint8_t mmc_init()
|
uint8_t mmc_init()
|
||||||
{
|
{
|
||||||
@@ -63,6 +36,7 @@ uint8_t mmc_init()
|
|||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mmc_write_command(uint8_t * cmd)
|
uint8_t mmc_write_command(uint8_t * cmd)
|
||||||
{
|
{
|
||||||
uint8_t tmp = 0xff;
|
uint8_t tmp = 0xff;
|
||||||
|
|||||||
@@ -1,44 +1,29 @@
|
|||||||
/*
|
#ifndef _MMC_H_
|
||||||
* ####################################################################################### Connect ARM to MMC/SD
|
#define _MMC_H_
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Ulrich Radig #######################################################################################
|
#include <avr/io.h>
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _MMC_H
|
#define MMC_WRITE PORTB
|
||||||
#define _MMC_H
|
#define MMC_READ PINB
|
||||||
|
|
||||||
|
|
||||||
#define SPI_Mode 0 // 1 = Hardware SPI | 0 = Software SPI
|
|
||||||
|
|
||||||
#define MMC_WRITE PORTB
|
|
||||||
#define MMC_READ PINB
|
|
||||||
#define MMC_REG DDRB
|
|
||||||
|
|
||||||
#define MMC_CS PB4
|
|
||||||
#define MMC_DO PB6
|
|
||||||
#define MMC_DI PB5
|
|
||||||
#define MMC_CLK PB7
|
|
||||||
|
|
||||||
#define MMC_WRITE PORTB // Port an der die MMC/SD-Karte angeschlossen ist also des SPI
|
|
||||||
#define MMC_READ PINB
|
|
||||||
#define MMC_REG DDRB
|
#define MMC_REG DDRB
|
||||||
|
|
||||||
|
#define MMC_CS PB4
|
||||||
|
#define MMC_DO PB6
|
||||||
|
#define MMC_DI PB5
|
||||||
|
#define MMC_CLK PB7
|
||||||
extern uint8_t mmc_read_byte(void);
|
extern uint8_t mmc_read_byte(void);
|
||||||
extern void mmc_write_byte(uint8_t);
|
extern void mmc_write_byte(uint8_t);
|
||||||
extern void mmc_read_block(uint8_t *, uint8_t *, unsigned in);
|
extern void mmc_read_block(uint8_t *, uint8_t *, unsigned in);
|
||||||
extern uint8_t mmc_init(void);
|
extern uint8_t mmc_init(void);
|
||||||
extern uint8_t mmc_read_sector(unsigned long, uint8_t *);
|
extern uint8_t mmc_read_sector(uint32_t, uint8_t *);
|
||||||
extern uint8_t mmc_write_sector(unsigned long, uint8_t *);
|
extern uint8_t mmc_write_sector(uint32_t, uint8_t *);
|
||||||
extern uint8_t mmc_write_command(uint8_t *);
|
extern uint8_t mmc_write_command(uint8_t *);
|
||||||
|
extern uint8_t mmc_read_csd(uint8_t *);
|
||||||
|
extern uint8_t mmc_read_cid(uint8_t *);
|
||||||
|
|
||||||
#define mmc_disable() MMC_WRITE|= (1<<MMC_CS);
|
#define mmc_disable() MMC_WRITE|= (1<<MMC_CS);
|
||||||
|
|
||||||
#define mmc_enable() MMC_WRITE&=~(1<<MMC_CS);
|
#define mmc_enable() MMC_WRITE&=~(1<<MMC_CS);
|
||||||
|
|
||||||
#define nop() __asm__ __volatile__ ("nop" ::)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,21 +38,20 @@ uint8_t scratchpad_state;
|
|||||||
uint8_t scratchpad_cmd;
|
uint8_t scratchpad_cmd;
|
||||||
uint8_t scratchpad_payload;
|
uint8_t scratchpad_payload;
|
||||||
|
|
||||||
void shared_memory_scratchpad_tx_save()
|
void shared_memory_scratchpad_save()
|
||||||
{
|
{
|
||||||
scratchpad_state = sram_read(SHARED_MEM_TX_LOC_STATE);
|
scratchpad_state = sram_read(SHARED_MEM_LOC_STATE);
|
||||||
scratchpad_cmd = sram_read(SHARED_MEM_TX_LOC_CMD);
|
scratchpad_cmd = sram_read(SHARED_MEM_LOC_CMD);
|
||||||
scratchpad_payload = sram_read(SHARED_MEM_TX_LOC_PAYLOAD);
|
scratchpad_payload = sram_read(SHARED_MEM_LOC_PAYLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_scratchpad_tx_restore()
|
void shared_memory_scratchpad_restore()
|
||||||
{
|
{
|
||||||
sram_write(SHARED_MEM_TX_LOC_STATE, scratchpad_state);
|
sram_write(SHARED_MEM_LOC_STATE, scratchpad_state);
|
||||||
sram_write(SHARED_MEM_TX_LOC_CMD, scratchpad_cmd);
|
sram_write(SHARED_MEM_LOC_CMD, scratchpad_cmd);
|
||||||
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, scratchpad_payload);
|
sram_write(SHARED_MEM_LOC_PAYLOAD, scratchpad_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_irq_hook()
|
void shared_memory_irq_hook()
|
||||||
{
|
{
|
||||||
irq_addr_lo = sram_read(SHARED_IRQ_LOC_LO);
|
irq_addr_lo = sram_read(SHARED_IRQ_LOC_LO);
|
||||||
@@ -67,33 +66,24 @@ void shared_memory_irq_restore()
|
|||||||
sram_write(SHARED_IRQ_LOC_HI, irq_addr_hi);
|
sram_write(SHARED_IRQ_LOC_HI, irq_addr_hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_write(uint8_t cmd, uint8_t value)
|
void shared_memory_put(uint8_t cmd, uint8_t value)
|
||||||
{
|
{
|
||||||
|
|
||||||
debug(DEBUG_SHM,"shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n",
|
info("Write shared memory 0x%04x=0x%02x 0x%04x=0x%02x \n",
|
||||||
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
SHARED_MEM_LOC_CMD, cmd, SHARED_MEM_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
sram_bulk_addr_save();
|
shared_memory_scratchpad_save();
|
||||||
shared_memory_scratchpad_tx_save();
|
|
||||||
shared_memory_irq_hook();
|
shared_memory_irq_hook();
|
||||||
|
|
||||||
sram_write(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_SNES_ACK);
|
sram_write(SHARED_MEM_LOC_STATE, SHARED_MEM_SNES_ACK);
|
||||||
sram_write(SHARED_MEM_TX_LOC_CMD, cmd);
|
sram_write(SHARED_MEM_LOC_CMD, cmd);
|
||||||
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, value);
|
sram_write(SHARED_MEM_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
|
_delay_ms(50);
|
||||||
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
|
||||||
snes_irq_on();
|
|
||||||
snes_irq_lo();
|
|
||||||
_delay_us(20);
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
#else
|
|
||||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
snes_irq_lo();
|
snes_irq_lo();
|
||||||
@@ -101,62 +91,7 @@ void shared_memory_write(uint8_t cmd, uint8_t value)
|
|||||||
snes_lorom();
|
snes_lorom();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
|
|
||||||
shared_memory_scratchpad_tx_restore();
|
shared_memory_scratchpad_restore();
|
||||||
shared_memory_irq_restore();
|
shared_memory_irq_restore();
|
||||||
sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_memory_yield()
|
|
||||||
{
|
|
||||||
|
|
||||||
snes_hirom();
|
|
||||||
snes_wr_disable();
|
|
||||||
snes_bus_active();
|
|
||||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
|
||||||
avr_bus_active();
|
|
||||||
snes_lorom();
|
|
||||||
snes_wr_disable();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
|
||||||
{
|
|
||||||
uint8_t state;
|
|
||||||
|
|
||||||
|
|
||||||
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
|
||||||
if (state != SHARED_MEM_RX_AVR_ACK){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
sram_bulk_addr_save();
|
|
||||||
|
|
||||||
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
|
||||||
*len = sram_read(SHARED_MEM_RX_LOC_LEN);
|
|
||||||
debug(DEBUG_SHM,"shared_memory_read: 0x%04x=0x%02x 0x%04x=0x%02x \n",
|
|
||||||
SHARED_MEM_RX_LOC_CMD, *cmd, SHARED_MEM_RX_LOC_LEN, *len);
|
|
||||||
|
|
||||||
sram_bulk_read_buffer(SHARED_MEM_RX_LOC_PAYLOAD,buffer, *len);
|
|
||||||
sram_write(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_AVR_RTS);
|
|
||||||
|
|
||||||
snes_hirom();
|
|
||||||
snes_wr_disable();
|
|
||||||
snes_bus_active();
|
|
||||||
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
|
||||||
snes_irq_on();
|
|
||||||
snes_irq_lo();
|
|
||||||
_delay_us(20);
|
|
||||||
snes_irq_hi();
|
|
||||||
snes_irq_off();
|
|
||||||
#else
|
|
||||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
avr_bus_active();
|
|
||||||
snes_lorom();
|
|
||||||
snes_wr_disable();
|
|
||||||
sram_bulk_addr_restore();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,45 +22,30 @@
|
|||||||
#define __SHARED_MEMORY_H__
|
#define __SHARED_MEMORY_H__
|
||||||
|
|
||||||
|
|
||||||
#define SHARED_MEM_SWITCH_IRQ 0
|
#define SHARED_MEM_SNES_ACK 0xa5
|
||||||
#define SHARED_MEM_SWITCH_DELAY 20
|
#define SHARED_MEM_SNES_RTS 0x5a
|
||||||
|
|
||||||
#define SHARED_MEM_TX_SNES_ACK 0xa5
|
|
||||||
#define SHARED_MEM_TX_SNES_RTS 0x5a
|
|
||||||
|
|
||||||
#define SHARED_MEM_TX_CMD_BANK_COUNT 0x00
|
|
||||||
#define SHARED_MEM_TX_CMD_BANK_CURRENT 0x01
|
|
||||||
|
|
||||||
#define SHARED_MEM_TX_CMD_UPLOAD_START 0x03
|
|
||||||
#define SHARED_MEM_TX_CMD_UPLOAD_END 0x04
|
|
||||||
#define SHARED_MEM_TX_CMD_UPLOAD_PROGESS 0x05
|
|
||||||
#define SHARED_MEM_TX_CMD_TERMINATE 0x06
|
|
||||||
|
|
||||||
#define SHARED_MEM_TX_LOC_STATE 0x000000
|
|
||||||
#define SHARED_MEM_TX_LOC_CMD 0x000001
|
|
||||||
#define SHARED_MEM_TX_LOC_PAYLOAD 0x000002
|
|
||||||
|
|
||||||
#define SHARED_MEM_RX_AVR_ACK 0xa5
|
|
||||||
#define SHARED_MEM_RX_AVR_RTS 0x5a
|
|
||||||
|
|
||||||
#define SHARED_MEM_RX_CMD_PRINFT 0x00
|
|
||||||
#define SHARED_MEM_RX_CMD_FILESEL 0x01
|
|
||||||
|
|
||||||
#define SHARED_MEM_RX_LOC_STATE 0x001000
|
|
||||||
#define SHARED_MEM_RX_LOC_CMD 0x001001
|
|
||||||
#define SHARED_MEM_RX_LOC_LEN 0x001002
|
|
||||||
#define SHARED_MEM_RX_LOC_PAYLOAD 0x001003
|
|
||||||
|
|
||||||
#define SHARED_IRQ_LOC_LO 0x00fffe
|
|
||||||
#define SHARED_IRQ_LOC_HI 0x00ffff
|
|
||||||
|
|
||||||
/* Use COP IRQ LOC for hooked IRQ handler */
|
|
||||||
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
|
||||||
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
|
||||||
|
|
||||||
|
|
||||||
|
#define SHARED_MEM_CMD_BANK_COUNT 0
|
||||||
|
#define SHARED_MEM_CMD_BANK_CURRENT 1
|
||||||
|
|
||||||
void shared_memory_write(uint8_t cmd, uint8_t value);
|
#define SHARED_MEM_CMD_UPLOAD_START 3
|
||||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer);
|
#define SHARED_MEM_CMD_UPLOAD_END 4
|
||||||
|
#define SHARED_MEM_CMD_UPLOAD_PROGESS 5
|
||||||
|
#define SHARED_MEM_CMD_TERMINATE 6
|
||||||
|
|
||||||
|
|
||||||
|
#define SHARED_MEM_LOC_STATE 0x000000
|
||||||
|
#define SHARED_MEM_LOC_CMD 0x000001
|
||||||
|
#define SHARED_MEM_LOC_PAYLOAD 0x000002
|
||||||
|
|
||||||
|
#define SHARED_IRQ_LOC_LO 0x00fffe
|
||||||
|
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||||
|
|
||||||
|
|
||||||
|
#define SHARED_IRQ_HANDLER_LO 0x00
|
||||||
|
#define SHARED_IRQ_HANDLER_HI 0x10
|
||||||
|
|
||||||
|
void shared_memory_put(uint8_t cmd, uint8_t value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h> /* for _delay_ms() */
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
@@ -30,10 +31,6 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
|
||||||
uint32_t addr_current = 0;
|
|
||||||
uint32_t addr_stash = 0;
|
|
||||||
|
|
||||||
|
|
||||||
void system_init(void)
|
void system_init(void)
|
||||||
{
|
{
|
||||||
/*-------------------------------------------------*/
|
/*-------------------------------------------------*/
|
||||||
@@ -96,19 +93,19 @@ void system_init(void)
|
|||||||
void sreg_set(uint32_t addr)
|
void sreg_set(uint32_t addr)
|
||||||
{
|
{
|
||||||
uint8_t i = 24;
|
uint8_t i = 24;
|
||||||
debug(DEBUG_SRAM,"sreg_set: addr=0x%08lx\n",addr);
|
debug(DEBUG_SREG,"sreg_set: addr=0x%08lx",addr);
|
||||||
while(i--) {
|
while(i--) {
|
||||||
if ((addr & ( 1L << i))){
|
if ((addr & ( 1L << i))){
|
||||||
debug(DEBUG_SRAM,"1");
|
debug(DEBUG_SREG,"1");
|
||||||
AVR_ADDR_SER_PORT |= ( 1 << AVR_ADDR_SER_PIN);
|
AVR_ADDR_SER_PORT |= ( 1 << AVR_ADDR_SER_PIN);
|
||||||
} else {
|
} else {
|
||||||
AVR_ADDR_SER_PORT &= ~( 1 << AVR_ADDR_SER_PIN);
|
AVR_ADDR_SER_PORT &= ~( 1 << AVR_ADDR_SER_PIN);
|
||||||
debug(DEBUG_SRAM,"0");
|
debug(DEBUG_SREG,"0");
|
||||||
}
|
}
|
||||||
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
||||||
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
||||||
}
|
}
|
||||||
debug(DEBUG_SRAM,"\n");
|
debug(DEBUG_SREG,"\n");
|
||||||
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
||||||
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
||||||
|
|
||||||
@@ -116,23 +113,11 @@ void sreg_set(uint32_t addr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sram_bulk_addr_save()
|
|
||||||
{
|
|
||||||
addr_stash = addr_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void sram_bulk_addr_restore()
|
|
||||||
{
|
|
||||||
sreg_set(addr_stash);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sram_bulk_read_start(uint32_t addr)
|
void sram_bulk_read_start(uint32_t addr)
|
||||||
{
|
{
|
||||||
debug(DEBUG_SRAM,"sram_bulk_read_start: addr=0x%08lx\n\r", addr);
|
debug(DEBUG_SRAM,"sram_bulk_read_start: addr=0x%08lx\n\r", addr);
|
||||||
|
|
||||||
addr_current = addr;
|
|
||||||
|
|
||||||
avr_data_in();
|
avr_data_in();
|
||||||
|
|
||||||
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||||
@@ -153,7 +138,6 @@ void sram_bulk_read_start(uint32_t addr)
|
|||||||
|
|
||||||
inline void sram_bulk_read_next(void)
|
inline void sram_bulk_read_next(void)
|
||||||
{
|
{
|
||||||
addr_current++;
|
|
||||||
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
counter_up();
|
counter_up();
|
||||||
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
||||||
@@ -325,3 +309,48 @@ void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){
|
|||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sram_setr(uint32_t addr, uint32_t len,uint8_t value)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
debug(DEBUG_SRAM,"sram_clear: addr=0x%08lx len=%li\n\r", addr,len);
|
||||||
|
for (i = addr; i < (addr + len); i++) {
|
||||||
|
if (0 == i % 0xfff)
|
||||||
|
debug(DEBUG_SRAM,"sram_clear: addr=0x%08lx\n\r", i);
|
||||||
|
sram_write(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_copy(uint32_t addr, uint8_t * src, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = src;
|
||||||
|
debug(DEBUG_SRAM,"sram_copy: addr=0x%08lx src=0x%p len=%li\n\r", addr,src,len);
|
||||||
|
for (i = addr; i < (addr + len); i++)
|
||||||
|
sram_write(i, *ptr++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = dst;
|
||||||
|
debug(DEBUG_SRAM,"sram_read_buffer: addr=0x%08lx dst=0x%p len=%li\n\r", addr,dst,len);
|
||||||
|
for (i = addr; i < (addr + len); i++) {
|
||||||
|
*ptr = sram_read(i);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t sram_check(uint8_t * buffer, uint32_t len)
|
||||||
|
{
|
||||||
|
uint16_t cnt;
|
||||||
|
debug(DEBUG_SRAM,"sram_check: len=%li\n\r",len);
|
||||||
|
for (cnt = 0; cnt < len; cnt++)
|
||||||
|
if (buffer[cnt])
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ void sreg_set(uint32_t addr);
|
|||||||
|
|
||||||
uint8_t sram_read(uint32_t addr);
|
uint8_t sram_read(uint32_t addr);
|
||||||
void sram_write(uint32_t addr, uint8_t data);
|
void sram_write(uint32_t addr, uint8_t data);
|
||||||
|
void sram_set(uint32_t addr, uint32_t len, uint8_t value);
|
||||||
|
void sram_copy(uint32_t addr,uint8_t *src, uint32_t len);
|
||||||
|
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len);
|
||||||
|
|
||||||
void sram_bulk_read_start(uint32_t addr);
|
void sram_bulk_read_start(uint32_t addr);
|
||||||
inline void sram_bulk_read_next(void);
|
inline void sram_bulk_read_next(void);
|
||||||
@@ -201,9 +204,4 @@ void sram_bulk_copy(uint32_t addr, uint8_t * src, uint32_t len);
|
|||||||
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len);
|
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len);
|
||||||
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value);
|
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value);
|
||||||
|
|
||||||
inline void sram_bulk_addr_save();
|
|
||||||
inline void sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,156 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
|
|
||||||
#include "shared_memory.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "sram.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "crc.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "info.h"
|
|
||||||
|
|
||||||
#include "mmc.h"
|
|
||||||
#include "fat.h"
|
|
||||||
#include "file.h"
|
|
||||||
#include "dir.h"
|
|
||||||
|
|
||||||
|
|
||||||
void test_read_write()
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
uint32_t addr;
|
|
||||||
avr_bus_active();
|
|
||||||
addr = 0x000000;
|
|
||||||
i = 1;
|
|
||||||
while (addr++ <= 0x0000ff) {
|
|
||||||
sram_write(addr, i++);
|
|
||||||
}
|
|
||||||
addr = 0x000000;
|
|
||||||
while (addr++ <= 0x0000ff) {
|
|
||||||
info("read addr=0x%08lx %x\n", addr, sram_read(addr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void test_bulk_read_write()
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
uint32_t addr;
|
|
||||||
avr_bus_active();
|
|
||||||
addr = 0x000000;
|
|
||||||
i = 0;
|
|
||||||
sram_bulk_write_start(addr);
|
|
||||||
while (addr++ <= 0x8000) {
|
|
||||||
sram_bulk_write(i++);
|
|
||||||
sram_bulk_write_next();
|
|
||||||
}
|
|
||||||
sram_bulk_write_end();
|
|
||||||
|
|
||||||
addr = 0x000000;
|
|
||||||
sram_bulk_read_start(addr);
|
|
||||||
while (addr <= 0x8000) {
|
|
||||||
info("addr=0x%08lx %x\n", addr, sram_bulk_read());
|
|
||||||
sram_bulk_read_next();
|
|
||||||
addr++;
|
|
||||||
}
|
|
||||||
sram_bulk_read_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
|
||||||
{
|
|
||||||
uint32_t addr = 0;
|
|
||||||
uint8_t c;
|
|
||||||
sram_bulk_read_start(bottom_addr);
|
|
||||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
|
||||||
c = sram_bulk_read();
|
|
||||||
if (c != 0xff)
|
|
||||||
info("addr=0x%08lx c=0x%x\n", addr, c);
|
|
||||||
sram_bulk_read_next();
|
|
||||||
}
|
|
||||||
sram_bulk_read_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void test_crc()
|
|
||||||
{
|
|
||||||
info("test_crc: clear\n");
|
|
||||||
avr_bus_active();
|
|
||||||
sram_bulk_set(0x000000, 0x10000, 0xff);
|
|
||||||
info("test_crc: crc\n");
|
|
||||||
crc_check_bulk_memory(0x000000, 0x10000, 0x8000);
|
|
||||||
info("test_crc: check\n");
|
|
||||||
test_non_zero_memory(0x000000, 0x10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_sdcard(void){
|
|
||||||
|
|
||||||
|
|
||||||
while (mmc_init() !=0){ //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten
|
|
||||||
printf("no sdcard\n");
|
|
||||||
}
|
|
||||||
if (fat_initfat()==0){
|
|
||||||
printf("fatinit ok\n");
|
|
||||||
} else {
|
|
||||||
printf("fatinit failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Root dirlist\n");
|
|
||||||
ffls_smc();
|
|
||||||
dump_memory(DIR_ENTRY_LOC , DIR_ENTRY_LOC + (64 * 2));
|
|
||||||
dir_entry_loop();
|
|
||||||
while(1);
|
|
||||||
|
|
||||||
#if (WRITE==1)
|
|
||||||
char datei[12]="test.txt"; // hier muss platz für 11 zeichen sein (8.3), da fat_str diesen string benutzt !!
|
|
||||||
fat_str(datei);
|
|
||||||
ffrm( datei ); // löschen der datei/ordner falls vorhanden
|
|
||||||
printf("open %s\n",datei);
|
|
||||||
ffopen( datei );
|
|
||||||
printf("write %s\n",datei);
|
|
||||||
ffwrites((char*)"Hallo Datei :)");
|
|
||||||
ffwrite(0x0D);
|
|
||||||
ffwrite(0x0A);
|
|
||||||
|
|
||||||
printf("close %s\n",datei);
|
|
||||||
ffclose();
|
|
||||||
printf("open %s\n",datei);
|
|
||||||
ffopen( datei );
|
|
||||||
printf("open %s\n",datei);
|
|
||||||
unsigned long int seek=file.length; // eine variable setzen und runterzählen bis 0 geht am schnellsten !
|
|
||||||
do{
|
|
||||||
printf("%c",ffread()); // liest ein zeichen und gibt es über uart aus !
|
|
||||||
}while(--seek); // liest solange bytes da sind (von datei länge bis 0)
|
|
||||||
ffclose(); // schließt datei
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TESTING_H__
|
|
||||||
#define __TESTING_H__
|
|
||||||
|
|
||||||
|
|
||||||
void test_read_write();
|
|
||||||
void test_bulk_read_write();
|
|
||||||
void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr);
|
|
||||||
void test_crc();
|
|
||||||
void test_sdcard();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -37,4 +37,3 @@ static int uart_stream(char c, FILE *stream);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,16 @@ uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
|||||||
rx_remaining, len);
|
rx_remaining, len);
|
||||||
len = rx_remaining;
|
len = rx_remaining;
|
||||||
}
|
}
|
||||||
if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
if (req_state == REQ_STATUS_UPLOAD) {
|
||||||
|
|
||||||
|
rx_remaining -= len;
|
||||||
|
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||||
|
req_addr, len, rx_remaining);
|
||||||
|
debug(DEBUG_USB_TRANS,"usbFunctionWrite %02x %02x %02x %02x %02x %02x %02x %x\n",
|
||||||
|
data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]);
|
||||||
|
sram_copy(req_addr, data, len);
|
||||||
|
req_addr += len;
|
||||||
|
} else if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||||
|
|
||||||
rx_remaining -= len;
|
rx_remaining -= len;
|
||||||
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>currentDocument</key>
|
|
||||||
<string>avr/usbload/dir.c</string>
|
|
||||||
<key>documents</key>
|
<key>documents</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
@@ -21,558 +19,6 @@
|
|||||||
<integer>271</integer>
|
<integer>271</integer>
|
||||||
<key>metaData</key>
|
<key>metaData</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>avr/bootloader/bootloader.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>6</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>268</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>381</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/bootloader/config.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>22</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/config.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>38</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>28</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/crc.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>53</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/crc.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>26</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>25</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>26</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/dir.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>27</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>45</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/dir.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>3</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>48</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>13</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>48</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>6</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>48</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/dump.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>26</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>1</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/dump.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/fat.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>13</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>12</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>13</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/fat.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>15</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>71</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>13</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>13</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>71</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>25</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>71</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/fifo.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>19</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/file.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>20</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>33</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>1</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>16</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>33</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>20</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>33</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/file.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>20</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>20</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/main.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>320</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>313</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/mmc.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>220</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>169</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/mmc.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>39</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/shared_memory.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>111</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/shared_memory.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>48</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>51</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>14</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>44</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>51</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>52</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>51</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/sram.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>299</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>273</integer>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/sram.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>3</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>200</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>158</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>71</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>200</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>3</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>200</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/testing.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>31</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>147</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>105</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>27</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>147</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>31</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>147</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>avr/usbload/testing.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>poc/avr_sdcard/fat.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>38</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>poc/avr_sdcard/fat.h</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>4</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>63</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>23</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>1</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>63</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>9</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>63</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>poc/avr_sdcard/main.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>12</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>170</integer>
|
|
||||||
</dict>
|
|
||||||
<key>columnSelection</key>
|
|
||||||
<false/>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>137</integer>
|
|
||||||
<key>selectFrom</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>1</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>170</integer>
|
|
||||||
</dict>
|
|
||||||
<key>selectTo</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>20</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>170</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>poc/avr_sdcard/main.lst</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>poc/avr_usbload/sram.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>17</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>5</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
<key>snes/banktest/LoadGraphics.asm</key>
|
<key>snes/banktest/LoadGraphics.asm</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>caret</key>
|
<key>caret</key>
|
||||||
@@ -601,52 +47,7 @@
|
|||||||
<key>firstVisibleLine</key>
|
<key>firstVisibleLine</key>
|
||||||
<integer>211</integer>
|
<integer>211</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>tools/ucon64/2.0/src/console/snes.c</key>
|
|
||||||
<dict>
|
|
||||||
<key>caret</key>
|
|
||||||
<dict>
|
|
||||||
<key>column</key>
|
|
||||||
<integer>28</integer>
|
|
||||||
<key>line</key>
|
|
||||||
<integer>1135</integer>
|
|
||||||
</dict>
|
|
||||||
<key>firstVisibleColumn</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
<key>firstVisibleLine</key>
|
|
||||||
<integer>1952</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
<key>openDocuments</key>
|
|
||||||
<array>
|
|
||||||
<string>avr/usbload/testing.h</string>
|
|
||||||
<string>avr/usbload/testing.c</string>
|
|
||||||
<string>avr/usbload/mmc.c</string>
|
|
||||||
<string>poc/avr_sdcard/fat.c</string>
|
|
||||||
<string>poc/avr_sdcard/fat.h</string>
|
|
||||||
<string>poc/avr_sdcard/main.lst</string>
|
|
||||||
<string>avr/bootloader/config.h</string>
|
|
||||||
<string>avr/bootloader/bootloader.c</string>
|
|
||||||
<string>avr/usbload/dir.h</string>
|
|
||||||
<string>avr/usbload/dump.h</string>
|
|
||||||
<string>avr/usbload/file.c</string>
|
|
||||||
<string>avr/usbload/fat.h</string>
|
|
||||||
<string>avr/usbload/file.h</string>
|
|
||||||
<string>avr/usbload/crc.c</string>
|
|
||||||
<string>avr/usbload/fat.c</string>
|
|
||||||
<string>avr/usbload/dir.c</string>
|
|
||||||
<string>avr/usbload/dump.c</string>
|
|
||||||
<string>avr/usbload/config.h</string>
|
|
||||||
<string>tools/ucon64/2.0/src/console/snes.c</string>
|
|
||||||
<string>poc/avr_sdcard/main.c</string>
|
|
||||||
<string>poc/avr_usbload/sram.c</string>
|
|
||||||
<string>avr/usbload/sram.h</string>
|
|
||||||
<string>avr/usbload/shared_memory.h</string>
|
|
||||||
<string>avr/usbload/shared_memory.c</string>
|
|
||||||
<string>avr/usbload/fifo.h</string>
|
|
||||||
<string>avr/usbload/main.c</string>
|
|
||||||
<string>avr/usbload/sram.c</string>
|
|
||||||
<string>avr/usbload/crc.h</string>
|
|
||||||
</array>
|
|
||||||
<key>showFileHierarchyDrawer</key>
|
<key>showFileHierarchyDrawer</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>showFileHierarchyPanel</key>
|
<key>showFileHierarchyPanel</key>
|
||||||
@@ -665,13 +66,6 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>subItems</key>
|
<key>subItems</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>bootloader</key>
|
|
||||||
<dict>
|
|
||||||
<key>isExpanded</key>
|
|
||||||
<true/>
|
|
||||||
<key>subItems</key>
|
|
||||||
<dict/>
|
|
||||||
</dict>
|
|
||||||
<key>usbload</key>
|
<key>usbload</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isExpanded</key>
|
<key>isExpanded</key>
|
||||||
@@ -681,43 +75,70 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>poc</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict>
|
||||||
|
<key>avr_sdcard</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>scripts</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
|
<key>snes</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
<key>tools</key>
|
<key>tools</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isExpanded</key>
|
<key>isExpanded</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>subItems</key>
|
<key>subItems</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>ucon64</key>
|
<key>ff</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
|
<key>ffsample</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isExpanded</key>
|
<key>isExpanded</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>subItems</key>
|
<key>subItems</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>2.0</key>
|
<key>avr</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isExpanded</key>
|
<key>isExpanded</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>subItems</key>
|
<key>subItems</key>
|
||||||
<dict>
|
<dict/>
|
||||||
<key>src</key>
|
|
||||||
<dict>
|
|
||||||
<key>isExpanded</key>
|
|
||||||
<true/>
|
|
||||||
<key>subItems</key>
|
|
||||||
<dict>
|
|
||||||
<key>console</key>
|
|
||||||
<dict>
|
|
||||||
<key>isExpanded</key>
|
|
||||||
<true/>
|
|
||||||
<key>subItems</key>
|
|
||||||
<dict/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>huffman</key>
|
||||||
|
<dict>
|
||||||
|
<key>isExpanded</key>
|
||||||
|
<true/>
|
||||||
|
<key>subItems</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
|||||||
Reference in New Issue
Block a user