Mass Storage + Fatfs Flash

660 views
Skip to first unread message

Colin

unread,
Jan 18, 2009, 9:02:57 PM1/18/09
to LUFA (Formerly MyUSB) Support
Hi Guys,
I new to programming Atmel. Currently using the USBKEY 1287. I hope
someone can help me out. I'm using LUFA's mass storage demos. I would
like to use the onboard flash to log the interrupt such as joystick
movement in a .csv file. I am using FatFs library but first I have to
establish a communication with the onboard flash in order to use it.
Anyone know where do i start?

Colin

Colin

unread,
Jan 19, 2009, 1:04:56 AM1/19/09
to LUFA (Formerly MyUSB) Support
I've manage to mount the drive by using Fatfs library through the
DataflashManager_WriteBlocks and DataflashManager_ReadBlocks. However,
when i tried to write a file, the fat file partition on the USBKey
turned into raw.

Do i need to initialise the dataflash before writing?

Colin

Colin

unread,
Jan 19, 2009, 2:11:05 AM1/19/09
to LUFA (Formerly MyUSB) Support
Sorry I was wrong. I wasnt able to mount the drive. I must have
overwritten the bootsector which causes the flash fat file system to
be corrupted.

Colin

abcmi...@gmail.com

unread,
Jan 20, 2009, 12:49:25 AM1/20/09
to LUFA (Formerly MyUSB) Support
As you've discovered, essentially all that's required is to link the
FATFS functions to read a block to and from the device to the
Dataflash block functions in DataflashManager.c. The FAT library
processes the raw blocks from the device (which can be a dataflash,
hard disk, SD card or anything else that can store data) and allows
you to read and write files.

For it to work, you need to do two things. First, you *must* use the
latest WIP code here in the downloads section of this list. The
current MassStorage demo has a few flaws in it which I've only just
found and caught, due to the OS being too smart for its own good and
hiding them from me. No doubt those flaws will play havoc on an
embedded simple FAT driver.

Second, you probably only want one single LUN (logical disk). Out of
the box the demo is designed to appear as two disks of half the total
capacity each. You should recompile with TOTAL_LUNS in MassStorage.c
set to 1 to make the dataflash a single logical disk.

Third, you need to format the dataflash on the PC to the appropriate
FAT filesystem. If your FAT library is FAT16 only, ensure that the
disk is formatted to FAT16, or it will be unable to read the
filesystem off the dataflash correctly.

- Dean

Colin

unread,
Jan 21, 2009, 1:43:36 AM1/21/09
to LUFA (Formerly MyUSB) Support
Hi Dean,
Thanks for the reply. I am using the latest LUFA and changed the LUN
to 1. The problem now is that read and write doesnt seem to work

The Fatfs needs a sector address (LBA) and number of sectors to write
(1..255) which I assume to be block address and total blocks in
DataflashManager's read and write function respectively.

The problem is Fatfs have another data parameter that contains the
item to be written which the DataflashManager does not have. Do i need
to modify the read and write function in DataflashManager so that it
writes the input argument?

Colin

abcmi...@gmail.com

unread,
Jan 21, 2009, 1:53:49 AM1/21/09
to LUFA (Formerly MyUSB) Support
Bugger, didn't think of that. The current DataflashManager.c functions
assume that the data is being sent to and from an endpoint. You have
two options:

1) FLASH memory permitting, duplicate the functions and alter them to
read and write data to a buffer given as a pointer in the function
parameters. Basically, duplicate, add in a "uint8_t* Buffer"
parameter, and change all the endpoint calls to use the buffer
instead. If you have trouble with that, I can post code.

2) Alter the existing functions to accept a buffer parameter. Inside
the function check if the pointer is NULL, if so read/write to the
endpoint. If the buffer is non-NULL, read/write to it instead. Again,
I can help if you have trouble.

- Dean

Colin

unread,
Jan 21, 2009, 3:05:32 AM1/21/09
to LUFA (Formerly MyUSB) Support
Thanks Dean,
I have duplicated the function because there would be too much to
change if i modified the existing function. I am not sure on how to
code it though.

I have simply disable anything that has anything to do with endpoint
and replaced the Dataflash_SendByte(Endpoint_Read_Byte()) with
Dataflash_SendByte(buff); for all 16 of them.

As for the read function, I have buff = Dataflash_ReceiveByte(); for
16 times. Unfortunately, it is still not working. Do you know what i
did wrongly? Thanks

abcmi...@gmail.com

unread,
Jan 21, 2009, 6:57:58 PM1/21/09
to LUFA (Formerly MyUSB) Support
That won't work, because you are assigning data to the same memory
location each time. I'm assuming you've modified the function so that
it has an extra "uint8_t* Buffer", that is, a pointer to an array of
unsigned character bytes.

What is passed to the function is only the address of the first byte
in the buffer. If you use:

buff = Dataflash_ReceiveByte();

You *should* be getting an error, as you are trying to assign the
pointer the address given by the value returned by the Dataflash byte
read function, which is a regular uint8_t value and not a pointer to a
uint8_t. I suspect you are missing the asterisk (*) from after the
uint8_t in the function parameters, which indicates that the value is
a pointer to the given type and not a value OF the given type.

Once you've sorted that out, you need to change all sets and gets of
your "buff" variable to "*(buff++)". This will de-reference the
pointer when it is accessed, giving you the data AT the location being
pointed to, and will increment the location counter by one after the
access.


- Dean

Colin

unread,
Jan 21, 2009, 11:15:32 PM1/21/09
to LUFA (Formerly MyUSB) Support
Thank you Dean, I have managed to get the program working. Thanks a
lot.

Dean Camera

unread,
May 1, 2013, 8:02:48 AM5/1/13
to LUFA Library Support List
Hi Nishant,

Try the Projects/TempDataLogger example included in LUFA, which shows
how to wire up FATFS to the dataflash functions in LUFA to read/write
files to a FAT32 partition on the USBKEY dataflash. You just need to
modify the FatFS read and write block functions to read and write one
512 byte block from your SD card to make the FatFS abstraction layer
work correctly.

Cheers!
- Dean

On Apr 25, 5:22 pm, Nishant Mistry <nish0...@gmail.com> wrote:
> Hi Dean, Do you have code for this? I am confused as to how exactly I
> should implement the disk_write and read functions.

Nishant Mistry

unread,
May 6, 2013, 5:02:34 AM5/6/13
to lufa-s...@googlegroups.com
Hi Dean,

I have looked at the temp logger example in your latest LUFA release. I noticed that the FATfs read/write functions calls the void DataflashManager_WriteBlocks_RAM/void DataflashManager_ReadBlocks_RAM functions. Is this the implementation of the FATFS library and would this directly work for the SD card. I am still rather confused. looking through the void DataflashManager_WriteBlocks_RAM function I can see that it is structured in a similar way as mentioned in this post,

(FLASH memory permitting, duplicate the functions and alter them to
read and write data to a buffer given as a pointer in the function
parameters. Basically, duplicate, add in a "uint8_t* Buffer"
parameter, and change all the endpoint calls to use the buffer
instead. If you have trouble with that, I can post code.)

Your help will be greatly appreciated

Thanks!


--
You received this message because you are subscribed to the Google Groups "LUFA Library Support List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lufa-support...@googlegroups.com.
To post to this group, send email to lufa-s...@googlegroups.com.
Visit this group at http://groups.google.com/group/lufa-support?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.



Dean Camera

unread,
May 9, 2013, 2:59:02 PM5/9/13
to LUFA Library Support List
Nishant,

The board that demos is targeted for contains an Atmel Dataflash
(well, we sold off the memory division, but at the time we made them)
device, which is just an external flash memory with a low(ish) density
of a few megabytes. The Dataflash layer just abstracts out the mass
storage control so that you can read and write 512 byte blocks of data
from either a USB endpoint or a RAM buffer. If you are using a SD
card, your SD card read/write routines would be substituted in place
of the Dataflash code to read and write the SD card blocks instead.

FatFS is from the Lib/FatFS/ folder of the project. In there is ff.c,
ff.h and integer.h, none of which you need to touch. In the same
folder is also ffconf.h use to configure the FatFS library (see the
comments in that file to see what you can alter) and diskio.c/
diskio.h, which glues your storage routines to the library. In the
TempDataLogger application I connect FatFS to the Dataflash by calling
my Dataflash routines in diskio.c, but in your case you need to change
diskio.c to point to your SD card routines. Once that's done, you
should be able to call the FatFS file read/write functions and have
FatFS in turn call your SD card routines to read out the actual files.

Cheers!
- Dean

On May 6, 11:02 am, Nishant Mistry <nish0...@gmail.com> wrote:
> Hi Dean,
>

Nishant Mistry

unread,
May 28, 2013, 6:09:03 AM5/28/13
to lufa-s...@googlegroups.com
Hi Dean,

I have a small issue that I am not able to get around, concerning LUFA. Basically I have set up a device (in the descriptor using 2 interfaces) one interface a mass storage device and the other as a USB keyboard. when my device is plugged in and starts up, both keyboard and mass storage device enumerate correctly, however later on in the application I would like to disable one of the interfaces (mass storage device) completely. Unfortunately I have only seen that I can disable the entire usb device using usb_disable() . is there a way to stop/disable a particular usb interface as opposed to all interfaces.

Also if I have multiple configurations in the descriptor.c am I able to point to which configuration I want to use from within my program? or is that only selectable from the host?  If i can use my program to select a configuration, then I was thinking of having a configuration for mass storage and a separate configuration for keyboard, then I could use a pin input jumper to check what config to use.

Please help.

Regards

Nishant




Dean Camera

unread,
May 28, 2013, 3:08:39 PM5/28/13
to LUFA Library Support List
Nishant,

I'm afraid it's not up to the device to decide - if you advertise an
interface in the configuration descriptor the host is allowed to
attempt to use it. You can specify multiple different configurations,
but it's also the host that gets to pick which one it wants to use.

In some cases you can simply ignore an interface if you wish to
deactivate it on the device side, but on others this will cause
lengthy timeout problems on the host. Instead, you can use each USB
class's mechanism to report to the host a suitable "not ready"
indicator so that the interface remains active but the host won't
attempt to use it. For example, with the Mass Storage class you can
return a SCSI failure for SCSI_CMD_TEST_UNIT_READY requests from the
host, and answer other SCSI disk read/write commands with a suitable
SCSI sense key to indicate the medium is not present. On Windows hosts
this will make the driver appear like a card reader without a card
inserted, so that access attempts through the GUI will present a
"Insert Disk" error to the user.

Cheers!
- Dean

On May 28, 12:09 pm, Nishant Mistry <nish0...@gmail.com> wrote:
> Hi Dean,
>
> I have a small issue that I am not able to get around, concerning LUFA.
> Basically I have set up a device (in the descriptor using 2 interfaces) one
> interface a mass storage device and the other as a USB keyboard. when my
> device is plugged in and starts up, both keyboard and mass storage device
> enumerate correctly, however later on in the application I would like to
> disable one of the interfaces (mass storage device) completely.
> Unfortunately I have only seen that I can disable the entire usb device
> using usb_disable() . is there a way to stop/disable a particular usb
> interface as opposed to all interfaces.
>
> Also if I have multiple configurations in the descriptor.c am I able to
> point to which configuration I want to use from within my program? or is
> that only selectable from the host?  If i can use my program to select a
> configuration, then I was thinking of having a configuration for mass
> storage and a separate configuration for keyboard, then I could use a pin
> input jumper to check what config to use.
>
> Please help.
>
> Regards
>
> Nishant
>
> ...
>
> read more »

Nishant Mistry

unread,
May 28, 2013, 3:24:39 PM5/28/13
to lufa-s...@googlegroups.com
Thanks Dean,

Do you happen to have any other suggestions, I was looking for a solution that would make the "mass storage" device not appear at all. On the other hand, would it be possible to maybe loqd two application programs on the device? Or maybe load a mass storage app into the bootloader section.

What I am really trying to do is
1. Enumerate a keyboard
2. Detect communication between the keyboard and host (using caps lock, scroll lock and num lock reports)
3. Depending on the combination of the caps lock, num lock and scroll lock report, enter "mass storage mode" so that a text file can be loaded into the dataflash.
4. If caps lock num lock and scroll lock are not pressed, then the device does not appear as a mass storage device at all.
Sent from my BlackBerry® wireless device

Nishant Mistry

unread,
Jun 5, 2013, 6:54:51 AM6/5/13
to lufa-s...@googlegroups.com
Hi All,

I have a small problem. I have built a device that enumerates as both a mass storage and keyboard. Now the problem is, when I first plug the device into a host, it starts searching windows updates for the drivers, and it takes very long. Is there a way or configuration in the descriptors code or something , so that the device can tell the host not to search windows update or something to that effect. I need the device to speed up the time taken to install drivers, without the host being disconnected from the internet (windows update).

Dean Camera

unread,
Jun 8, 2013, 6:33:42 AM6/8/13
to lufa-s...@googlegroups.com
Nishant,

No, there is no way to accelerate this on the device side - Windows has
an internal database of VID and PIDs that it can quickly map to its
internal drivers, while all others will first search Windows Update for
a dedicated driver before falling back to the inbuilt on (so that
manufacturers can supply custom drivers). Unless the host PC is
configured to not first search Windows Update for new drivers, you're
stuck waiting.

Note that once a device of a certain VID/PID has been enumerated and
configured on a host PC, future driver installs of the same VID/PID
should be accelerated.

Cheers!
- Dean
> <d...@fourwalledcubicle.com <mailto:d...@fourwalledcubicle.com>>wrote:
> <abcminiu...@gmail.com <mailto:abcminiu...@gmail.com>>
> > > wrote:
> > > > > Hi Nishant,
> >
> > > > > Try the Projects/TempDataLogger example included in LUFA,
> which shows
> > > > > how to wire up FATFS to the dataflash functions in LUFA to
> read/write
> > > > > files to a FAT32 partition on the USBKEY dataflash. You
> just need to
> > > > > modify the FatFS read and write block functions to read
> and write one
> > > > > 512 byte block from your SD card to make the FatFS
> abstraction layer
> > > > > work correctly.
> >
> > > > > Cheers!
> > > > > - Dean
> >
> > > > > On Apr 25, 5:22 pm, Nishant Mistry <nish0...@gmail.com
> <mailto:cltw...@hotmail.com>> wrote:
> >
> > > > > > > > > > Sorry I was wrong. I wasnt able to mount the
> drive. I must
> > > have
> > > > > > > > > > overwritten the bootsector which causes the
> flash fat file
> > > > > system to
> > > > > > > > > > be corrupted.
> >
> > > > > > > > > > Colin
> >
> > > > > > > > > > On Jan 19, 2:04 pm, Colin <cltw...@hotmail.com
> <mailto:cltw...@hotmail.com>> wrote:
> >
> > > > > > > > > > > I've manage to mount the drive by using Fatfs
> library
> > > through
> > > > > the
> > > > > > > > > > > DataflashManager_WriteBlocks and
> > > DataflashManager_ReadBlocks.
> > > > > > > However,
> > > > > > > > > > > when i tried to write a file, the fat file
> partition on the
> > > > > USBKey
> > > > > > > > > > > turned into raw.
> >
> > > > > > > > > > > Do i need to initialise the dataflash before
> writing?
> >
> > > > > > > > > > > Colin
> >
> > > > > > > > > > > On Jan 19, 10:02 am, Colin
> <mailto:lufa-support%2Bunsu...@googlegroups.com>.
> > > > > To post to this group, send email to
> lufa-s...@googlegroups.com <mailto:lufa-s...@googlegroups.com>.
> > > > > Visit this group
> athttp://groups.google.com/group/lufa-support?hl=en
> <http://groups.google.com/group/lufa-support?hl=en>.
> > > > > For more options,
> visithttps://groups.google.com/groups/opt_out
> <http://groups.google.com/groups/opt_out>.
> >
> > > --
> > > You received this message because you are subscribed to the
> Google Groups
> > > "LUFA
> >
> > ...
> >
> > read more »
>
> --
> You received this message because you are subscribed to the Google
> Groups "LUFA Library Support List" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to lufa-support...@googlegroups.com
> <mailto:lufa-support%2Bunsu...@googlegroups.com>.
> To post to this group, send email to lufa-s...@googlegroups.com
> <mailto:lufa-s...@googlegroups.com>.

jakub...@gmail.com

unread,
Jun 10, 2014, 3:00:22 AM6/10/14
to lufa-s...@googlegroups.com
Hi Dean,

I've tried to implement Your concept.
I don't know what you exactly mean by sending 'failure' on test unit ready.
Could you explain it a little bit?
I've put:
 if (suspend_msc == 1)//grant SD access to FATFS
  {
       SCSI_SenseCode(lun,
                   NOT_READY,
                   MEDIUM_NOT_PRESENT);
    return -1;
  }
in 3 places ( test unit ready, and read/write requests).
It works good only on linux.
Under windows(I've tried on VISTA 32bit and Windows7 64bit) it works poor - it causes windows waiting full 2 minutes doing nothing and then sending reset..

Maybe in case of test unit ready response should look differnet?

Regards
Jakub

Dean Camera

unread,
Jun 10, 2014, 3:18:17 AM6/10/14
to lufa-s...@googlegroups.com
Hi Jakub,

According to https://en.wikipedia.org/wiki/Key_Code_Qualifier and http://www.t10.org/lists/asc-num.htm#ASC_3A the SCSI Additional Sense Key/Additional Sense Key Qualifier should be 0x3A and 0x00 respectively, or in LUFA speak:

        SCSI_SET_SENSE(SCSI_SENSE_KEY_NOT_READY,
                       SCSI_ASENSE_MEDIUM_NOT_PRESENT,
                       SCSI_ASENSEQ_NO_QUALIFIER);

Which should be returnable for all read/write commands. For the TEST UNIT READY command, the documentation at ftp://www.t10.org/t10/document.06/06-022r0.pdf states that only a CHECK CONDITION sense key is allowed as an error, with HARDWARE ERROR and LOGICAL UNIT FAILURE as the ASC/ASCQ.


Cheers!
- Dean

Jakub Siudy

unread,
Jun 10, 2014, 3:47:04 AM6/10/14
to lufa-s...@googlegroups.com
Hi Dean!
Thanks for quick reply!
I have the problem that i'm not using LUFA and in library i'm using there is SCSI_SenseCode function where i can't place for ASCQ..it's:

void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC)
{
  SCSI_Sense[SCSI_Sense_Tail].Skey  = sKey;
  SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8;
  SCSI_Sense_Tail++;
  if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH)
  {
    SCSI_Sense_Tail = 0;
  }
}

But when you told me what should be sent I hope i'll find way to do it..

Cheers!
Jakub


--
You received this message because you are subscribed to a topic in the Google Groups "LUFA Library Support List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lufa-support/8g1L3KHGm9A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lufa-support...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages