From 0020ee5dc1b04bd379b50ae9447f71109fb0688b Mon Sep 17 00:00:00 2001 From: bsx Date: Fri, 17 Jun 2011 12:31:42 +0200 Subject: [PATCH 1/3] added USB mass storage access for data flash --- Makefile | 11 ++- core/Makefile | 2 - core/projectconfig.h | 1 + filesystem/at45db041d.c | 111 +++++++++++++++++++++++ filesystem/at45db041d.h | 4 + modules/bsx.c | 47 ++-------- usb/Makefile | 36 ++++++++ {core/usbhid-rom => usb}/usb.h | 0 {core/usbhid-rom => usb}/usbconfig.c | 129 +++++++++++++++++++++------ {core/usbhid-rom => usb}/usbconfig.h | 7 +- {core/usbhid-rom => usb}/usbhid.c | 4 +- {core/usbhid-rom => usb}/usbhid.h | 0 usb/usbmsc.c | 105 ++++++++++++++++++++++ usb/usbmsc.h | 46 ++++++++++ 14 files changed, 422 insertions(+), 81 deletions(-) create mode 100644 usb/Makefile rename {core/usbhid-rom => usb}/usb.h (100%) rename {core/usbhid-rom => usb}/usbconfig.c (67%) rename {core/usbhid-rom => usb}/usbconfig.h (95%) rename {core/usbhid-rom => usb}/usbhid.c (99%) rename {core/usbhid-rom => usb}/usbhid.h (100%) create mode 100644 usb/usbmsc.c create mode 100644 usb/usbmsc.h diff --git a/Makefile b/Makefile index c265fdd..0bf79b5 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ VPATH += OBJS += OBJS += basic/basic.o basic/reinvoke_isp.o basic/delayms.o basic/voltage.o OBJS += basic/keyin.o -LIBS += core/libcore.a lcd/liblcd.a modules/libmodules.a filesystem/libfat.a +LIBS += core/libcore.a lcd/liblcd.a modules/libmodules.a filesystem/libfat.a usb/libusb.a ########################################################################## # GNU GCC compiler flags @@ -28,8 +28,9 @@ OBJS += $(TARGET)_handlers.o LPC1xxx_startup.o ########################################################################## LDLIBS = -lm LDLIBS += -Lmodules -lmodules -LDLIBS += -Lfilesystem -lfat LDLIBS += -Llcd -llcd +LDLIBS += -Lusb -lusb +LDLIBS += -Lfilesystem -lfat LDLIBS += -Lcore -lcore OCFLAGS = --strip-unneeded @@ -54,6 +55,7 @@ clean: @cd lcd && $(MAKE) clean @cd modules && $(MAKE) clean @cd filesystem && $(MAKE) clean + @cd usb && $(MAKE) clean @cd loadable && $(MAKE) clean ### Internal targets @@ -73,6 +75,9 @@ modules/libmodules.a: filesystem/libfat.a: cd filesystem && $(MAKE) ROOT_PATH=../$(ROOT_PATH) +usb/libusb.a: + cd usb && $(MAKE) ROOT_PATH=../$(ROOT_PATH) + tools/lpcfix: cd tools && $(MAKE) @@ -95,5 +100,5 @@ $(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(LIBS) $(LPCFIX) $(LD_TEMP) -@echo "" $(LPCFIX) -c $@ -.PHONY: $(LD_TEMP) lcd/liblcd.a modules/libmodules.a filesystem/libfat.a +.PHONY: $(LD_TEMP) lcd/liblcd.a modules/libmodules.a filesystem/libfat.a usb/libusb.a diff --git a/core/Makefile b/core/Makefile index 1b8554a..ec1df9e 100644 --- a/core/Makefile +++ b/core/Makefile @@ -30,8 +30,6 @@ OBJS += timer32/timer32.o #OBJS += usbcdc/usbdesc.o #OBJS += usbcdc/usbhw.o #OBJS += usbcdc/usbuser.o -#OBJS += usbhid-rom/usbconfig.o -#OBJS += usbhid-rom/usbhid.o OBJS += wdt/wdt.o ########################################################################## diff --git a/core/projectconfig.h b/core/projectconfig.h index 7132c49..32d7a78 100644 --- a/core/projectconfig.h +++ b/core/projectconfig.h @@ -70,3 +70,4 @@ #define CFG_HAVE_SDCARD (0) /*=========================================================================*/ + #define CFG_USBMSC (1) diff --git a/filesystem/at45db041d.c b/filesystem/at45db041d.c index 546acfe..3a334be 100644 --- a/filesystem/at45db041d.c +++ b/filesystem/at45db041d.c @@ -72,6 +72,41 @@ DSTATUS dataflash_status() { return status; } +DRESULT dataflash_random_read(BYTE *buff, DWORD offset, DWORD length) { + if (!length) return RES_PARERR; + if (status & STA_NOINIT) return RES_NOTRDY; + if (offset+length > MAX_PAGE*256) return RES_PARERR; + + DWORD pages = length/256 + 1; + + do { + wait_for_ready(); + DWORD pageaddr = ((offset/256) << 9) | (offset%256); + DWORD remaining = 256 - offset%256; + if (remaining > length) { + remaining = length; + } else if (remaining > length) { + length -= remaining; + offset += remaining; + } + CS_LOW(); + xmit_spi(OP_PAGEREAD); + xmit_spi((BYTE)(pageaddr >> 16)); + xmit_spi((BYTE)(pageaddr >> 8)); + xmit_spi((BYTE)pageaddr); + xmit_spi(0x00); // follow up with 4 don't care bytes + xmit_spi(0x00); + xmit_spi(0x00); + xmit_spi(0x00); + do { + rcvr_spi_m(buff++); + } while (--remaining); + CS_HIGH(); + } while (--pages); + + return length ? RES_ERROR : RES_OK; +} + DRESULT dataflash_read(BYTE *buff, DWORD sector, BYTE count) { if (!count) return RES_PARERR; if (status & STA_NOINIT) return RES_NOTRDY; @@ -105,6 +140,73 @@ DRESULT dataflash_read(BYTE *buff, DWORD sector, BYTE count) { } #if _READONLY == 0 +DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length) { + if (!length) return RES_PARERR; + if (status & STA_NOINIT) return RES_NOTRDY; + if (offset+length > MAX_PAGE*256) return RES_PARERR; + + DWORD pages = length/256 + 1; + + do { + wait_for_ready(); + DWORD pageaddr = ((offset/256) << 9) | (offset%256); + DWORD remaining = 256 - offset%256; + if (remaining > length) { + remaining = length; + } else if (remaining > length) { + length -= remaining; + offset += remaining; + } + + // read page into the internal buffer + CS_LOW(); + xmit_spi(OP_PAGE2BUFFER1); + xmit_spi((BYTE)(pageaddr >> 16)); + xmit_spi((BYTE)(pageaddr >> 8)); + xmit_spi((BYTE)pageaddr); + CS_HIGH(); + wait_for_ready(); + + // write bytes into the dataflash buffer + CS_LOW(); + xmit_spi(OP_BUFFER1WRITE); + xmit_spi(0x00); + xmit_spi(0x00); + xmit_spi(0x00); + do { + xmit_spi(*buff++); + } while (--remaining); + CS_HIGH(); + wait_for_ready(); + + // compare buffer with target memory page + CS_LOW(); + xmit_spi(OP_BUFFER1PAGECMP); + xmit_spi((BYTE)(pageaddr >> 16)); + xmit_spi((BYTE)(pageaddr >> 8)); + xmit_spi((BYTE)pageaddr); + CS_HIGH(); + wait_for_ready(); + CS_LOW(); + BYTE reg_status = 0xFF; + xmit_spi(OP_STATUSREAD); + rcvr_spi_m((uint8_t *) ®_status); + CS_HIGH(); + + // trigger program only if data changed + if (reg_status & SB_COMP) { + CS_LOW(); + xmit_spi(OP_BUFFER1PROG); + xmit_spi((BYTE)(pageaddr >> 16)); + xmit_spi((BYTE)(pageaddr >> 8)); + xmit_spi((BYTE)pageaddr); + CS_HIGH(); + } + } while (--pages); + + return length ? RES_ERROR : RES_OK; +} + DRESULT dataflash_write(const BYTE *buff, DWORD sector, BYTE count) { if (!count) return RES_PARERR; if (status & STA_NOINIT) return RES_NOTRDY; @@ -119,6 +221,15 @@ DRESULT dataflash_write(const BYTE *buff, DWORD sector, BYTE count) { DWORD pageaddr = sector << 9; // lower 9 bits are byte address within the page DWORD remaining = 256; + // read page into the internal buffer + CS_LOW(); + xmit_spi(OP_PAGE2BUFFER1); + xmit_spi((BYTE)(pageaddr >> 16)); + xmit_spi((BYTE)(pageaddr >> 8)); + xmit_spi((BYTE)pageaddr); + CS_HIGH(); + wait_for_ready(); + // write bytes into the dataflash buffer CS_LOW(); xmit_spi(OP_BUFFER1WRITE); diff --git a/filesystem/at45db041d.h b/filesystem/at45db041d.h index 6034f2d..a19894c 100644 --- a/filesystem/at45db041d.h +++ b/filesystem/at45db041d.h @@ -1,10 +1,14 @@ #ifndef _AT45DB041D_H #define _AT45DB041D_H 1 +#include "diskio.h" + DSTATUS dataflash_initialize(); DSTATUS dataflash_status(); DRESULT dataflash_read(BYTE *buff, DWORD sector, BYTE count); +DRESULT dataflash_random_read(BYTE *buff, DWORD offset, DWORD length); DRESULT dataflash_write(const BYTE *buff, DWORD sector, BYTE count); +DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length); DRESULT dataflash_ioctl(BYTE ctrl, void *buff); #endif /* _AT45DB041D_H */ diff --git a/modules/bsx.c b/modules/bsx.c index b3df170..55a3279 100644 --- a/modules/bsx.c +++ b/modules/bsx.c @@ -6,6 +6,8 @@ #include "lcd/backlight.h" #include "lcd/allfonts.h" +#include "usb/usbmsc.h" + void ReinvokeISP(void); /**************************************************************************/ @@ -19,60 +21,21 @@ void module_bsx(void) { font = &Font_7x8; DoString(0, 0, "bsx"); - - backlightInit(); - brightness = backlightGetBrightness(); + lcdDisplay(0); + delayms(1000); + usbMSCInit(); while (1) { uint32_t results; lcdDisplay(0); delayms(10); - if(gpioGetValue(RB_BTN1)==0){ - brightness++; - if (brightness > 100) brightness = 100; - backlightSetBrightness(brightness); - } - - if(gpioGetValue(RB_BTN0)==0){ - brightness--; - if (brightness > 100) brightness = 0; - backlightSetBrightness(brightness); - } - - if (gpioGetValue(RB_BTN3) == 0) { - while(gpioGetValue(RB_BTN3)==0); - lcdInvert(); - } - if (gpioGetValue(RB_BTN4)==0) { while(gpioGetValue(RB_BTN4)==0); DoString(0,8,"Enter ISP!"); lcdDisplay(0); ReinvokeISP(); } - - dx = DoString(0, yctr, "Bright:"); - dx = DoInt(dx, yctr, brightness); - DoString(dx, yctr, "% "); - - results = adcRead(1); - dx=DoString(0,yctr+20,"Voltage:"); - results *= 10560; - results /= 1024; - DoInt(dx,yctr+20,results); - - if (results < 3500) { - DoString(0,yctr+30,"Shutdown"); - gpioSetValue (RB_PWR_GOOD, 0); - gpioSetValue (RB_LCD_BL, 0); - SCB_SCR |= SCB_SCR_SLEEPDEEP; - PMU_PMUCTRL = PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN; - __asm volatile ("WFI"); - } else { - DoString(0,yctr+30,"OK "); - } - } return; diff --git a/usb/Makefile b/usb/Makefile new file mode 100644 index 0000000..d54ddf3 --- /dev/null +++ b/usb/Makefile @@ -0,0 +1,36 @@ +########################################################################## +# User configuration and firmware specific object files +########################################################################## + +OBJS = + +OBJS += usbconfig.o +OBJS += usbhid.o +OBJS += usbmsc.o + +LIBNAME=usb + +########################################################################## +# GNU GCC compiler flags +########################################################################## +ROOT_PATH?= .. +INCLUDE_PATHS = -I$(ROOT_PATH) -I../core -I. + +include $(ROOT_PATH)/Makefile.inc + +LIBFILE=lib$(LIBNAME).a +########################################################################## +# Compiler settings, parameters and flags +########################################################################## + +all: $(LIBFILE) + +$(LIBFILE): $(OBJS) + $(AR) rcs $@ $(OBJS) + +%.o : %.c + $(CC) $(CFLAGS) -o $@ $< + +clean: + rm -f $(OBJS) $(LIBFILE) + diff --git a/core/usbhid-rom/usb.h b/usb/usb.h similarity index 100% rename from core/usbhid-rom/usb.h rename to usb/usb.h diff --git a/core/usbhid-rom/usbconfig.c b/usb/usbconfig.c similarity index 67% rename from core/usbhid-rom/usbconfig.c rename to usb/usbconfig.c index 6fa0a7f..9aa787c 100644 --- a/core/usbhid-rom/usbconfig.c +++ b/usb/usbconfig.c @@ -53,40 +53,40 @@ const uint8_t USB_HIDStringDescriptor[] = /* Index 0x04: Manufacturer */ 0x1C, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ - 'm',0, - 'i',0, - 'c',0, - 'r',0, - 'o',0, - 'B',0, - 'u',0, - 'i',0, - 'l',0, - 'd',0, - 'e',0, - 'r',0, + 'C',0, + 'C',0, + 'C',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, ' ',0, /* Index 0x20: Product */ 0x28, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ - 'L',0, - 'P',0, - 'C',0, - '1',0, - '3',0, - '4',0, - '3',0, - ' ',0, - 'R',0, - 'e',0, - 'f',0, - '.',0, - ' ',0, - 'B',0, - 'o',0, - 'a',0, 'r',0, - 'd',0, + '0',0, + 'k',0, + 'e',0, + 't',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, ' ',0, /* Index 0x48: Serial Number */ 0x1A, /* bLength */ @@ -113,3 +113,74 @@ const uint8_t USB_HIDStringDescriptor[] = ' ',0, ' ',0, }; + +/* USB String Descriptor (optional) */ +const uint8_t USB_MSCStringDescriptor[] = +{ + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0409), /* US English */ /* wLANGID */ + /* Index 0x04: Manufacturer */ + 0x1C, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'C',0, + 'C',0, + 'C',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + /* Index 0x20: Product */ + 0x28, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'r',0, + '0',0, + 'k',0, + 'e',0, + 't',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + ' ',0, + /* Index 0x48: Serial Number */ + 0x1A, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + /* Index 0x62: Interface 0, Alternate Setting 0 */ + 0x0E, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'M',0, + 'e',0, + 'm',0, + 'o',0, + 'r',0, + 'y',0, +}; diff --git a/core/usbhid-rom/usbconfig.h b/usb/usbconfig.h similarity index 95% rename from core/usbhid-rom/usbconfig.h rename to usb/usbconfig.h index 9cc9110..d35d543 100644 --- a/core/usbhid-rom/usbconfig.h +++ b/usb/usbconfig.h @@ -41,8 +41,8 @@ #include "projectconfig.h" -#define USB_VENDOR_ID CFG_USB_VID // Vendor ID -#define USB_PROD_ID CFG_USB_PID // Product ID +#define USB_VENDOR_ID 0x16c0 // Vendor ID +#define USB_PROD_ID 0x08ac // Product ID #define USB_DEVICE 0x0100 // Device ID #define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) @@ -59,8 +59,9 @@ extern const uint8_t USB_DeviceDescriptor[]; extern const uint8_t USB_ConfigDescriptor[]; extern const uint8_t USB_HIDStringDescriptor[]; +extern const uint8_t USB_MSCStringDescriptor[]; extern const uint8_t HID_ReportDescriptor[]; extern const uint16_t HID_ReportDescSize; -#endif \ No newline at end of file +#endif diff --git a/core/usbhid-rom/usbhid.c b/usb/usbhid.c similarity index 99% rename from core/usbhid-rom/usbhid.c rename to usb/usbhid.c index ce53742..5072b0b 100644 --- a/core/usbhid-rom/usbhid.c +++ b/usb/usbhid.c @@ -35,13 +35,13 @@ /**************************************************************************/ #include -#include "core/usbhid-rom/usb.h" -#include "core/usbhid-rom/usbconfig.h" #include "core/rom_drivers.h" #include "core/gpio/gpio.h" #include "core/adc/adc.h" #include "core/systick/systick.h" +#include "usb.h" +#include "usbconfig.h" #include "usbhid.h" USB_DEV_INFO DeviceInfo; diff --git a/core/usbhid-rom/usbhid.h b/usb/usbhid.h similarity index 100% rename from core/usbhid-rom/usbhid.h rename to usb/usbhid.h diff --git a/usb/usbmsc.c b/usb/usbmsc.c new file mode 100644 index 0000000..6820cf1 --- /dev/null +++ b/usb/usbmsc.c @@ -0,0 +1,105 @@ +#include "core/rom_drivers.h" +#include "core/gpio/gpio.h" +#include "filesystem/at45db041d.h" + +#include "lcd/render.h" +#include "lcd/display.h" + +#include "usb.h" +#include "usbconfig.h" +#include "usbmsc.h" + +USB_DEV_INFO DeviceInfo; +MSC_DEVICE_INFO MscDevInfo; +ROM ** rom = (ROM **)0x1fff1ff8; + +void usbMSCWrite(uint32_t offset, uint8_t src[], uint32_t length) { + uint8_t x; + x = DoString(0,0,"WOffset:"); + DoInt(x,0,offset); + x = DoString(0,10,"WLength:"); + DoInt(x,10,length); + lcdDisplay(0); + dataflash_random_write(src, offset, length); +} + +void usbMSCRead(uint32_t offset, uint8_t dst[], uint32_t length) { + uint8_t x; + x = DoString(0,20,"ROffset:"); + DoInt(x,20,offset); + x = DoString(0,30,"RLength:"); + DoInt(x,30,length); + lcdDisplay(0); + dataflash_random_read(dst, offset, length); +} + +void usbMSCInit(void) { + dataflash_initialize(); + + // Setup USB clock + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL + + SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; + + // Wait until the USB clock is updated + while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE)); + + // Set USB clock to 48MHz (12MHz x 4) + SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4); + while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked + SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT; + + // Set USB pin functions + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT + IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK; + IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus + IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK; + IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect + + // Disable internal resistor on VBUS (0.3) + gpioSetPullup(&IOCON_PIO0_3, gpioPullupMode_Inactive); + + // workaround for long connect delay + *((uint32_t *)(0x10000054)) = 0x0; + + // HID Device Info + volatile int n; + MscDevInfo.idVendor = USB_VENDOR_ID; + MscDevInfo.idProduct = USB_PROD_ID; + MscDevInfo.bcdDevice = USB_DEVICE; + MscDevInfo.StrDescPtr = (uint32_t)&USB_MSCStringDescriptor[0]; + MscDevInfo.MSCInquiryStr = (uint32_t)&"r0ket DataFlash "; // 28 char response to SCSI INQUIRY + MscDevInfo.BlockCount = 1024; + MscDevInfo.BlockSize = 512; + MscDevInfo.MemorySize = 1024*512; + MscDevInfo.MSC_Write = &usbMSCWrite; + MscDevInfo.MSC_Read = &usbMSCRead; + + DeviceInfo.DevType = USB_DEVICE_CLASS_STORAGE; + DeviceInfo.DevDetailPtr = (uint32_t)&MscDevInfo; + + /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG); + + /* Use pll and pin init function in rom */ + /* Warning: This will also set the system clock to 48MHz! */ + // (*rom)->pUSBD->init_clk_pins(); + + /* insert a delay between clk init and usb init */ + for (n = 0; n < 75; n++) {__asm("nop");} + + (*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */ + (*rom)->pUSBD->connect(true); /* USB Connect */ +} + +#ifdef CFG_USBMSC +void USB_IRQHandler() { + (*rom)->pUSBD->isr(); +} +#endif + diff --git a/usb/usbmsc.h b/usb/usbmsc.h new file mode 100644 index 0000000..20c2929 --- /dev/null +++ b/usb/usbmsc.h @@ -0,0 +1,46 @@ +/**************************************************************************/ +/*! + @file usbhid.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _USBMSC_H_ +#define _USBMSC_H_ + +#include "projectconfig.h" + +void usbMSCWrite(uint32_t offset, uint8_t src[], uint32_t length); +void usbMSCRead(uint32_t offset, uint8_t dst[], uint32_t length); +void usbMSCInit(void); + +#endif From 84433bb1d6dd58270efc2bc594f4a1027c02b26c Mon Sep 17 00:00:00 2001 From: bsx Date: Fri, 17 Jun 2011 13:12:02 +0200 Subject: [PATCH 2/3] unified dataflash access for USB and filesystem --- filesystem/at45db041d.c | 111 ++++------------------------------------ usb/usbmsc.c | 16 +----- 2 files changed, 11 insertions(+), 116 deletions(-) diff --git a/filesystem/at45db041d.c b/filesystem/at45db041d.c index 3a334be..2f3e711 100644 --- a/filesystem/at45db041d.c +++ b/filesystem/at45db041d.c @@ -77,18 +77,16 @@ DRESULT dataflash_random_read(BYTE *buff, DWORD offset, DWORD length) { if (status & STA_NOINIT) return RES_NOTRDY; if (offset+length > MAX_PAGE*256) return RES_PARERR; - DWORD pages = length/256 + 1; - do { wait_for_ready(); DWORD pageaddr = ((offset/256) << 9) | (offset%256); DWORD remaining = 256 - offset%256; if (remaining > length) { remaining = length; - } else if (remaining > length) { - length -= remaining; - offset += remaining; } + length -= remaining; + offset += remaining; + CS_LOW(); xmit_spi(OP_PAGEREAD); xmit_spi((BYTE)(pageaddr >> 16)); @@ -102,41 +100,13 @@ DRESULT dataflash_random_read(BYTE *buff, DWORD offset, DWORD length) { rcvr_spi_m(buff++); } while (--remaining); CS_HIGH(); - } while (--pages); + } while (length); return length ? RES_ERROR : RES_OK; } DRESULT dataflash_read(BYTE *buff, DWORD sector, BYTE count) { - if (!count) return RES_PARERR; - if (status & STA_NOINIT) return RES_NOTRDY; - - /* convert sector numbers to page numbers */ - sector *= 2; - count *= 2; - if (sector+count > MAX_PAGE) return RES_PARERR; - - do { - wait_for_ready(); - DWORD pageaddr = sector << 9; // lower 9 bits are byte address within the page - DWORD remaining = 256; - CS_LOW(); - xmit_spi(OP_PAGEREAD); - xmit_spi((BYTE)(pageaddr >> 16)); - xmit_spi((BYTE)(pageaddr >> 8)); - xmit_spi((BYTE)pageaddr); - xmit_spi(0x00); // follow up with 4 don't care bytes - xmit_spi(0x00); - xmit_spi(0x00); - xmit_spi(0x00); - do { - rcvr_spi_m(buff++); - } while (--remaining); - sector++; - CS_HIGH(); - } while (--count); - - return count ? RES_ERROR : RES_OK; + return dataflash_random_read(buff, sector*512, count*512); } #if _READONLY == 0 @@ -145,18 +115,15 @@ DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length) { if (status & STA_NOINIT) return RES_NOTRDY; if (offset+length > MAX_PAGE*256) return RES_PARERR; - DWORD pages = length/256 + 1; - do { wait_for_ready(); DWORD pageaddr = ((offset/256) << 9) | (offset%256); DWORD remaining = 256 - offset%256; if (remaining > length) { remaining = length; - } else if (remaining > length) { - length -= remaining; - offset += remaining; } + length -= remaining; + offset += remaining; // read page into the internal buffer CS_LOW(); @@ -202,73 +169,13 @@ DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length) { xmit_spi((BYTE)pageaddr); CS_HIGH(); } - } while (--pages); + } while (length); return length ? RES_ERROR : RES_OK; } DRESULT dataflash_write(const BYTE *buff, DWORD sector, BYTE count) { - if (!count) return RES_PARERR; - if (status & STA_NOINIT) return RES_NOTRDY; - - /* convert sector numbers to page numbers */ - sector *= 2; - count *= 2; - if (sector+count > MAX_PAGE) return RES_PARERR; - - do { - wait_for_ready(); - DWORD pageaddr = sector << 9; // lower 9 bits are byte address within the page - DWORD remaining = 256; - - // read page into the internal buffer - CS_LOW(); - xmit_spi(OP_PAGE2BUFFER1); - xmit_spi((BYTE)(pageaddr >> 16)); - xmit_spi((BYTE)(pageaddr >> 8)); - xmit_spi((BYTE)pageaddr); - CS_HIGH(); - wait_for_ready(); - - // write bytes into the dataflash buffer - CS_LOW(); - xmit_spi(OP_BUFFER1WRITE); - xmit_spi(0x00); - xmit_spi(0x00); - xmit_spi(0x00); - do { - xmit_spi(*buff++); - } while (--remaining); - sector++; - CS_HIGH(); - wait_for_ready(); - - // compare buffer with target memory page - CS_LOW(); - xmit_spi(OP_BUFFER1PAGECMP); - xmit_spi((BYTE)(pageaddr >> 16)); - xmit_spi((BYTE)(pageaddr >> 8)); - xmit_spi((BYTE)pageaddr); - CS_HIGH(); - wait_for_ready(); - CS_LOW(); - BYTE reg_status = 0xFF; - xmit_spi(OP_STATUSREAD); - rcvr_spi_m((uint8_t *) ®_status); - CS_HIGH(); - - // trigger program only if data changed - if (reg_status & SB_COMP) { - CS_LOW(); - xmit_spi(OP_BUFFER1PROG); - xmit_spi((BYTE)(pageaddr >> 16)); - xmit_spi((BYTE)(pageaddr >> 8)); - xmit_spi((BYTE)pageaddr); - CS_HIGH(); - } - } while (--count); - - return count ? RES_ERROR : RES_OK; + return dataflash_random_write(buff, sector*512, count*512); } #endif /* _READONLY */ diff --git a/usb/usbmsc.c b/usb/usbmsc.c index 6820cf1..9a34e51 100644 --- a/usb/usbmsc.c +++ b/usb/usbmsc.c @@ -14,23 +14,11 @@ MSC_DEVICE_INFO MscDevInfo; ROM ** rom = (ROM **)0x1fff1ff8; void usbMSCWrite(uint32_t offset, uint8_t src[], uint32_t length) { - uint8_t x; - x = DoString(0,0,"WOffset:"); - DoInt(x,0,offset); - x = DoString(0,10,"WLength:"); - DoInt(x,10,length); - lcdDisplay(0); - dataflash_random_write(src, offset, length); + dataflash_random_write(src, offset+1, length); } void usbMSCRead(uint32_t offset, uint8_t dst[], uint32_t length) { - uint8_t x; - x = DoString(0,20,"ROffset:"); - DoInt(x,20,offset); - x = DoString(0,30,"RLength:"); - DoInt(x,30,length); - lcdDisplay(0); - dataflash_random_read(dst, offset, length); + dataflash_random_read(dst, offset+1, length); } void usbMSCInit(void) { From c966b71e5b0494b2afee60fe4da3fb939889d072 Mon Sep 17 00:00:00 2001 From: bsx Date: Fri, 17 Jun 2011 14:29:32 +0200 Subject: [PATCH 3/3] fixed really nasty write bug --- filesystem/at45db041d.c | 9 +++++---- modules/fs.c | 5 +++++ usb/usbmsc.c | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/filesystem/at45db041d.c b/filesystem/at45db041d.c index 2f3e711..0c6fe37 100644 --- a/filesystem/at45db041d.c +++ b/filesystem/at45db041d.c @@ -117,7 +117,8 @@ DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length) { do { wait_for_ready(); - DWORD pageaddr = ((offset/256) << 9) | (offset%256); + DWORD pageaddr = (offset/256) << 9; + DWORD buffaddr = (offset%256); DWORD remaining = 256 - offset%256; if (remaining > length) { remaining = length; @@ -137,9 +138,9 @@ DRESULT dataflash_random_write(const BYTE *buff, DWORD offset, DWORD length) { // write bytes into the dataflash buffer CS_LOW(); xmit_spi(OP_BUFFER1WRITE); - xmit_spi(0x00); - xmit_spi(0x00); - xmit_spi(0x00); + xmit_spi((BYTE)(buffaddr >> 16)); + xmit_spi((BYTE)(buffaddr >> 8)); + xmit_spi((BYTE)buffaddr); do { xmit_spi(*buff++); } while (--remaining); diff --git a/modules/fs.c b/modules/fs.c index 39cf0a0..fa7a639 100644 --- a/modules/fs.c +++ b/modules/fs.c @@ -9,6 +9,8 @@ #include "filesystem/ff.h" #include "filesystem/diskio.h" +#include "usb/usbmsc.h" + #include "core/ssp/ssp.h" void incBacklight(void); @@ -44,6 +46,7 @@ const struct MENU_DEF menu_list = {"FS List", &fs_list}; const struct MENU_DEF menu_create = {"FS Create", &fs_create}; const struct MENU_DEF menu_format = {"FS format", &fs_format}; const struct MENU_DEF menu_read = {"FS read", &fs_read}; +const struct MENU_DEF menu_usb = {"USB mount", &usbMSCInit}; const struct MENU_DEF menu_nop = {"---", NULL}; static menuentry menu[] = { @@ -55,6 +58,8 @@ static menuentry menu[] = { &menu_nop, &menu_format, &menu_nop, + &menu_usb, + &menu_nop, &menu_ISP, &menu_incBL, &menu_decBL, diff --git a/usb/usbmsc.c b/usb/usbmsc.c index 9a34e51..fdb7a4c 100644 --- a/usb/usbmsc.c +++ b/usb/usbmsc.c @@ -14,11 +14,11 @@ MSC_DEVICE_INFO MscDevInfo; ROM ** rom = (ROM **)0x1fff1ff8; void usbMSCWrite(uint32_t offset, uint8_t src[], uint32_t length) { - dataflash_random_write(src, offset+1, length); + dataflash_random_write(src, offset, length); } void usbMSCRead(uint32_t offset, uint8_t dst[], uint32_t length) { - dataflash_random_read(dst, offset+1, length); + dataflash_random_read(dst, offset, length); } void usbMSCInit(void) {