added USB mass storage access for data flash

This commit is contained in:
bsx 2011-06-17 12:31:42 +02:00
parent dd33c658ff
commit 0020ee5dc1
14 changed files with 422 additions and 81 deletions

View File

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

View File

@ -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
##########################################################################

View File

@ -70,3 +70,4 @@
#define CFG_HAVE_SDCARD (0)
/*=========================================================================*/
#define CFG_USBMSC (1)

View File

@ -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 *) &reg_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);

View File

@ -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 */

View File

@ -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;

36
usb/Makefile Normal file
View File

@ -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)

View File

@ -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,
};

View File

@ -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
#endif

View File

@ -35,13 +35,13 @@
/**************************************************************************/
#include <string.h>
#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;

105
usb/usbmsc.c Normal file
View File

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

46
usb/usbmsc.h Normal file
View File

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