Addition of USB files
This commit is contained in:
parent
a520fe4646
commit
219846f408
36 changed files with 11046 additions and 0 deletions
515
cpu/avr/dev/usb/storage/avr_flash.c
Normal file
515
cpu/avr/dev/usb/storage/avr_flash.c
Normal file
|
@ -0,0 +1,515 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file avr_flash.c *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file writes/reads to/from flash memory internal to the AVR.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
#include "config.h" // system configuration
|
||||
#include "storage/avr_flash.h"
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/boot.h>
|
||||
|
||||
#ifndef SPM_PAGESIZE
|
||||
#error SPM_PAGESIZE undefined!!!
|
||||
#endif
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
//_____ P R I V A T E D E C L A R A T I O N _____________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
|
||||
#define MEM_BASE_ADDRESS 0x10000UL
|
||||
|
||||
|
||||
DATA U32 gl_ptr_mem; /* memory data pointer */
|
||||
|
||||
|
||||
/* Disk management */
|
||||
bit reserved_disk_space = FALSE; /* reserved space for application on disk */
|
||||
|
||||
|
||||
U32 AVRF_DISK_SIZE = 111; /* 57 KB, some room at end saved for bootloader section */
|
||||
|
||||
|
||||
void avrf_check_init( void );
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
//!
|
||||
//! @brief This function initializes the hw/sw ressources required to drive the AVR Flash
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_mem_init(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function tests the state of the AVR Flash
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Else -> CTRL_NO_PRESENT
|
||||
//!/
|
||||
Ctrl_status avrf_test_unit_ready(void)
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function gives the address of the last valid sector.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param *u32_nb_sector number of sector (sector = 512B). OUT
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!/
|
||||
Ctrl_status avrf_read_capacity( U32 *u32_nb_sector )
|
||||
{
|
||||
*u32_nb_sector = AVRF_DISK_SIZE;
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function returns the write protected status of the memory.
|
||||
//!
|
||||
//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection
|
||||
//! !!! The customer must unplug the memory to change this write protected status,
|
||||
//! which cannot be for a DF.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return FALSE -> the memory is not write-protected (always)
|
||||
//!/
|
||||
Bool avrf_wr_protect(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function tells if the memory has been removed or not.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @return FALSE -> The memory isn't removed
|
||||
//!/
|
||||
Bool avrf_removal(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------ STANDARD FUNCTIONS to read/write the memory --------------------
|
||||
|
||||
//!
|
||||
//! @brief This function performs a read operation of n sectors from a given address on.
|
||||
//! (sector = 512B)
|
||||
//!
|
||||
//! DATA FLOW is: AVRF => USB
|
||||
//!
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param addr Sector address to start the read from
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//!
|
||||
Ctrl_status avrf_read_10( U32 addr , U16 nb_sector )
|
||||
{
|
||||
avrf_read_open(addr); // wait device is not busy, then send command & address
|
||||
avrf_read_sector(nb_sector); // transfer data from memory to USB
|
||||
avrf_read_close(); // unselect memory
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction initialise the memory for a write operation
|
||||
//!
|
||||
//! DATA FLOW is: USB => DF
|
||||
//!
|
||||
//!
|
||||
//! (sector = 512B)
|
||||
//! @param addr Sector address to start write
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//!
|
||||
Ctrl_status avrf_write_10( U32 addr , U16 nb_sector )
|
||||
{
|
||||
|
||||
avrf_write_open(addr); // wait device is not busy, then send command & address
|
||||
avrf_write_sector(nb_sector); // transfer data from memory to USB
|
||||
avrf_write_close(); // unselect memory
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//------------ AVR FLASH LOWER LEVEL ROUTIENS -----------------------------------------
|
||||
|
||||
//!
|
||||
//! @brief This function opens a DF memory in read mode at a given sector address.
|
||||
//!
|
||||
//! NOTE: Address may not be synchronized on the beginning of a page (depending on the DF page size).
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param pos Logical sector address
|
||||
//!
|
||||
//! @return bit
|
||||
//! The open succeeded -> OK
|
||||
//!/
|
||||
bit avrf_read_open (Uint32 pos)
|
||||
{
|
||||
// Set the global memory ptr at a Byte address.
|
||||
gl_ptr_mem = (pos * 512) + MEM_BASE_ADDRESS;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function unselects the current DF memory.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_read_close (void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function is optimized and writes nb-sector * 512 Bytes from
|
||||
//! DataFlash memory to USB controller
|
||||
//!
|
||||
//! DATA FLOW is: DF => USB
|
||||
//!
|
||||
//!
|
||||
//! NOTE:
|
||||
//! - First call must be preceded by a call to the df_read_open() function,
|
||||
//! - The USB EPIN must have been previously selected,
|
||||
//! - USB ping-pong buffers are free,
|
||||
//! - As 512 is always a sub-multiple of page size, there is no need to check
|
||||
//! page end for each Bytes,
|
||||
//! - Interrupts are disabled during transfer to avoid timer interrupt,
|
||||
//! - nb_sector always >= 1, cannot be zero.
|
||||
//!
|
||||
//! @warning code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param nb_sector number of contiguous sectors to read [IN]
|
||||
//!
|
||||
//! @return bit
|
||||
//! The read succeeded -> OK
|
||||
//!/
|
||||
bit avrf_read_sector (Uint16 nb_sector)
|
||||
{
|
||||
U8 i,j;
|
||||
do
|
||||
{
|
||||
for (i = 8; i != 0; i--)
|
||||
{
|
||||
Disable_interrupt(); // Global disable.
|
||||
|
||||
for (j = 0; j < 64; j++) {
|
||||
Usb_write_byte(pgm_read_byte_far(gl_ptr_mem++));
|
||||
}
|
||||
|
||||
|
||||
//# Send the USB FIFO IN content to the USB Host.
|
||||
Usb_send_in(); // Send the FIFO IN content to the USB Host.
|
||||
|
||||
Enable_interrupt(); // Global interrupt re-enable.
|
||||
|
||||
// Wait until the tx is done so that we may write to the FIFO IN again.
|
||||
while(Is_usb_write_enabled()==FALSE);
|
||||
}
|
||||
nb_sector--; // 1 more sector read
|
||||
}
|
||||
while (nb_sector != 0);
|
||||
|
||||
return OK; // Read done.
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function opens a DF memory in write mode at a given sector
|
||||
//! address.
|
||||
//!
|
||||
//! NOTE: If page buffer > 512 bytes, page content is first loaded in buffer to
|
||||
//! be partially updated by write_byte or write64 functions.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param pos Sector address
|
||||
//!
|
||||
//! @return bit
|
||||
//! The open succeeded -> OK
|
||||
//!/
|
||||
bit avrf_write_open (Uint32 pos)
|
||||
{
|
||||
// Set the global memory ptr at a Byte address.
|
||||
gl_ptr_mem = (pos * 512) + MEM_BASE_ADDRESS;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
//!
|
||||
//! @brief This function fills the end of the logical sector (512B) and launch
|
||||
//! page programming.
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
//!/
|
||||
void avrf_write_close (void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This code can be setup to work with the DFU bootloader, which comes with the AT90USB1287. However I haven't
|
||||
had time to test it with such */
|
||||
#define LAST_BOOT_ENTRY 0xFFFE
|
||||
|
||||
|
||||
void dfuclone_boot_buffer_write(uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word);
|
||||
void dfuclone_boot_page_erase(uint32_t dummy1, uint16_t dummy2, uint32_t address);
|
||||
void dfuclone_boot_page_write(uint32_t dummy1, uint16_t dummy2, uint32_t address);
|
||||
|
||||
|
||||
/* Enable the use of the AVR DFU bootloader by defining "USE_AVRDFU_BOOTLOADER", it will
|
||||
then call the low-level routines already in the bootloader. */
|
||||
#ifdef USE_AVRDFU_BOOTLOADER
|
||||
|
||||
#error UNTESTED/UNSUPPORTED AT THIS TIME
|
||||
|
||||
// These functions pointers are used to call functions entry points in bootloader
|
||||
void (*dfu_boot_buffer_write) (uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)=
|
||||
(void (*)(uint16_t, uint32_t, uint16_t, uint16_t))(LAST_BOOT_ENTRY-6);
|
||||
|
||||
void (*dfu_boot_page_write) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
(void (*)(uint32_t, uint16_t, uint32_t))(LAST_BOOT_ENTRY-4);
|
||||
|
||||
void (*dfu_boot_page_erase) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
(void (*)(uint32_t, uint16_t, uint32_t))(LAST_BOOT_ENTRY-2);
|
||||
|
||||
#else
|
||||
|
||||
// These functions pointers are used to call functions entry points in bootloader
|
||||
void (*dfu_boot_buffer_write) (uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)=
|
||||
dfuclone_boot_buffer_write;
|
||||
|
||||
void (*dfu_boot_page_write) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
dfuclone_boot_page_write;
|
||||
|
||||
void (*dfu_boot_page_erase) (uint32_t dummy1, uint16_t dummy2, uint32_t address)=
|
||||
dfuclone_boot_page_erase;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//!
|
||||
//! @brief This function is optimized and writes nb-sector * 512 Bytes from
|
||||
//! USB controller to DataFlash memory
|
||||
//!
|
||||
//! DATA FLOW is: USB => DF
|
||||
//!
|
||||
//!
|
||||
//! NOTE:
|
||||
//! - First call must be preceded by a call to the df_write_open() function,
|
||||
//! - As 512 is always a sub-multiple of page size, there is no need to check
|
||||
//! page end for each Bytes,
|
||||
//! - The USB EPOUT must have been previously selected,
|
||||
//! - Interrupts are disabled during transfer to avoid timer interrupt,
|
||||
//! - nb_sector always >= 1, cannot be zero.
|
||||
//!
|
||||
//! @warning code:?? bytes (function code length)
|
||||
//!
|
||||
//! @param nb_sector number of contiguous sectors to write [IN]
|
||||
//!
|
||||
//! @return bit
|
||||
//! The write succeeded -> OK
|
||||
//!/
|
||||
bit avrf_write_sector (Uint16 nb_sector)
|
||||
{
|
||||
Byte i, j;
|
||||
U16 w;
|
||||
|
||||
U16 pgindex = 0;
|
||||
U16 sector_bytecounter = 0;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
//# Write 8x64b = 512b from the USB FIFO OUT.
|
||||
for (i = 8; i != 0; i--)
|
||||
{
|
||||
// Wait end of rx in USB EPOUT.
|
||||
while(Is_usb_read_enabled()==FALSE);
|
||||
|
||||
Disable_interrupt(); // Global disable.
|
||||
|
||||
//If start of page, erase it!
|
||||
if (pgindex == 0) {
|
||||
(*dfu_boot_page_erase)(0, 0, gl_ptr_mem);
|
||||
}
|
||||
|
||||
//For all the data in the endpoint, write to flash temp page
|
||||
for (j = 0; j < 32; j++) {
|
||||
w = Usb_read_byte();
|
||||
w += Usb_read_byte() << 8;
|
||||
(*dfu_boot_buffer_write)(0, gl_ptr_mem, pgindex, w);
|
||||
pgindex += 2;
|
||||
}
|
||||
|
||||
Usb_ack_receive_out(); // USB EPOUT read acknowledgement.
|
||||
|
||||
//If we have filled flash page, write that sucker to memory
|
||||
if (pgindex == SPM_PAGESIZE) {
|
||||
|
||||
(*dfu_boot_page_write)(0,0, gl_ptr_mem);
|
||||
|
||||
Enable_interrupt(); // Global enable again
|
||||
|
||||
gl_ptr_mem += SPM_PAGESIZE; // Update the memory pointer.
|
||||
pgindex = 0;
|
||||
|
||||
sector_bytecounter += SPM_PAGESIZE;
|
||||
|
||||
if(sector_bytecounter == 512) {
|
||||
nb_sector--; // 1 more sector written
|
||||
sector_bytecounter = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // for (i = 8; i != 0; i--)
|
||||
|
||||
}
|
||||
while (nb_sector != 0);
|
||||
|
||||
return OK; // Write done
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_AVRDFU_BOOTLOADER
|
||||
/* Perform read/write of FLASH, using same calling convention as low-level routines in AVR DFU bootloader */
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_buffer_write(uint16_t dummy, uint32_t baseaddr, uint16_t pageaddr, uint16_t word)
|
||||
{
|
||||
boot_page_fill(baseaddr + pageaddr, word);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_page_erase(uint32_t dummy1, uint16_t dummy2, uint32_t address)
|
||||
{
|
||||
boot_page_erase(address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
BOOTLOADER_SECTION void dfuclone_boot_page_write(uint32_t dummy1, uint16_t dummy2, uint32_t address)
|
||||
{
|
||||
boot_page_write(address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
return;
|
||||
}
|
||||
#endif //USE_AVRDFU_BOOTLOADER
|
||||
|
||||
//------------ SPECIFIC FONCTION USB TRANSFER -----------------------------------------
|
||||
|
||||
//** If your device transfer have a specific transfer for USB (Particularity of Chejudo product, or bootloader)
|
||||
// !!! In this case the driver must be know the USB access
|
||||
|
||||
//! This fonction transfer the memory data (programed in scsi_read_10) directly to the usb interface
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!
|
||||
Ctrl_status avrf_usb_read()
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction transfer the usb data (programed in scsi_write_10) directly to the memory data
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//!
|
||||
Ctrl_status avrf_usb_write( void )
|
||||
{
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
/** @} */
|
135
cpu/avr/dev/usb/storage/avr_flash.h
Normal file
135
cpu/avr/dev/usb/storage/avr_flash.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file avr_flash.h *********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file writes/reads to/from flash memory internal to the AVR.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _DFMEM_H_
|
||||
#define _DFMEM_H_
|
||||
|
||||
#include "conf_access.h"
|
||||
#include "ctrl_status.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
//! FAT specification
|
||||
#define ENTRY_SIZE 32 // size of entrie in byte
|
||||
|
||||
|
||||
|
||||
// First sector of the disk virtual (this disk isn't partitioned, only one partion)
|
||||
#define PBR_SECTOR (0)
|
||||
#define FAT_SECTOR (PBR_SECTOR + VMEM_RESERVED_SIZE)
|
||||
#define ROOT_SECTOR (FAT_SECTOR + (VMEM_SIZE_FAT*VMEM_NB_FATS))
|
||||
#define FILE_SECTOR (ROOT_SECTOR + ((ENTRY_SIZE*VMEM_NB_ROOT_ENTRY) / VMEM_SECTOR_SIZE)) // 1(sector) = size root dir
|
||||
|
||||
|
||||
/* FAT Format Structure */
|
||||
typedef struct
|
||||
{
|
||||
Uint16 nb_cylinder;
|
||||
Byte nb_head;
|
||||
Byte nb_sector;
|
||||
Byte nb_hidden_sector;
|
||||
Byte nb_sector_per_cluster;
|
||||
} s_format;
|
||||
|
||||
#define MEM_BSY 0
|
||||
#define MEM_OK 1
|
||||
#define MEM_KO 2
|
||||
|
||||
|
||||
|
||||
|
||||
//---- CONTROL FONCTIONS ----
|
||||
|
||||
// those fonctions are declared in df_mem.h
|
||||
void avrf_mem_init(void);
|
||||
Ctrl_status avrf_test_unit_ready(void);
|
||||
Ctrl_status avrf_read_capacity( U32 _MEM_TYPE_SLOW_ *u32_nb_sector );
|
||||
Bool avrf_wr_protect(void);
|
||||
Bool avrf_removal(void);
|
||||
|
||||
//---- AVR FLASH LOW-LEVEL----
|
||||
|
||||
|
||||
bit avrf_init (void);
|
||||
bit avrf_mem_check(void);
|
||||
bit avrf_read_open (Uint32);
|
||||
void avrf_read_close (void);
|
||||
bit avrf_write_open (Uint32);
|
||||
void avrf_write_close (void);
|
||||
|
||||
//! Funtions to link USB DEVICE flow with data flash
|
||||
bit avrf_write_sector (Uint16);
|
||||
bit avrf_read_sector (Uint16);
|
||||
|
||||
|
||||
s_format * avrf_format (void);
|
||||
|
||||
|
||||
|
||||
//---- ACCESS DATA FONCTIONS ----
|
||||
|
||||
// Standard functions for open in read/write mode the device
|
||||
Ctrl_status avrf_read_10( U32 addr , U16 nb_sector );
|
||||
Ctrl_status avrf_write_10( U32 addr , U16 nb_sector );
|
||||
|
||||
|
||||
//** If your device transfer have a specific transfer for USB (Particularity of Chejudo product, or bootloader)
|
||||
#ifdef DF_VALIDATION
|
||||
#include "virtual_usb.h"
|
||||
#else
|
||||
#include "usb_drv.h" // In this case the driver must be known for the USB access
|
||||
#endif
|
||||
Ctrl_status avr_usb_read( void );
|
||||
Ctrl_status avr_usb_write( void );
|
||||
|
||||
|
||||
|
||||
#endif // _DFMEM_H_
|
||||
|
||||
/** @} */
|
197
cpu/avr/dev/usb/storage/conf_access.h
Normal file
197
cpu/avr/dev/usb/storage/conf_access.h
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file conf_access.h *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the possible external configuration of the control access
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _CONF_ACCESS_H_
|
||||
#define _CONF_ACCESS_H_
|
||||
|
||||
|
||||
// Active the Logical Unit
|
||||
#define LUN_0 DISABLE // On-Chip flash vitual memory
|
||||
#define LUN_1 DISABLE // NF 2KB
|
||||
#define LUN_2 DISABLE // NF 512B
|
||||
#define LUN_3 DISABLE // Data Flash
|
||||
#define LUN_4 ENABLE //On-chip 32KB
|
||||
#define LUN_5 DISABLE
|
||||
#define LUN_6 DISABLE
|
||||
#define LUN_7 DISABLE
|
||||
#define LUN_USB DISABLE
|
||||
|
||||
// LUN 0 DEFINE
|
||||
#define LUN_0_INCLUDE "lib_mem\virtual_mem\virtual_mem.h"
|
||||
#define Lun_0_test_unit_ready() virtual_test_unit_ready()
|
||||
#define Lun_0_read_capacity(nb_sect) virtual_read_capacity(nb_sect)
|
||||
#define Lun_0_wr_protect() virtual_wr_protect()
|
||||
#define Lun_0_removal() virtual_removal()
|
||||
#define Lun_0_read_10(ad, sec) virtual_read_10(ad, sec)
|
||||
#define Lun_0_usb_read() virtual_usb_read()
|
||||
#define Lun_0_write_10(ad, sec) virtual_write_10(ad, sec)
|
||||
#define Lun_0_usb_write() virtual_usb_write()
|
||||
#define Lun_0_ram_2_mem(addr , ram) virtual_ram_2_mem(addr, ram)
|
||||
#define Lun_0_ram_2_mem_write() virtual_ram_2_mem_write()
|
||||
#define Lun_0_mem_2_ram(addr , ram) virtual_mem_2_ram(addr, ram)
|
||||
#define Lun_0_mem_2_ram_read() virtual_mem_2_ram_read()
|
||||
#define LUN_0_NAME "VIRTUAL_MEM_ON_CHIP"
|
||||
|
||||
// LUN 1 DEFINE
|
||||
#if (LUN_1 == ENABLE)
|
||||
#define NF_2K_MEM ENABLE
|
||||
#else
|
||||
#define NF_2K_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_1_INCLUDE "lib_mem\nf_1x_2kb\nf_mem.h"
|
||||
#define Lun_1_test_unit_ready() nf_test_unit_ready()
|
||||
#define Lun_1_read_capacity(nb_sect) nf_read_capacity(nb_sect)
|
||||
#define Lun_1_wr_protect() nf_wr_protect()
|
||||
#define Lun_1_removal() nf_removal()
|
||||
#define Lun_1_read_10(ad, sec) nf_read_10(ad, sec)
|
||||
#define Lun_1_usb_read() nf_usb_read()
|
||||
#define Lun_1_write_10(ad, sec) nf_write_10(ad, sec)
|
||||
#define Lun_1_usb_write() nf_usb_write()
|
||||
#define Lun_1_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_1_ram_2_mem_write() TODO
|
||||
#define Lun_1_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_1_mem_2_ram_read() TODO
|
||||
|
||||
// LUN 2 DEFINE
|
||||
#if (LUN_2 == ENABLE)
|
||||
#define NF_512_MEM ENABLE
|
||||
#else
|
||||
#define NF_512_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_2_INCLUDE "lib_mem\nf_1x_512\nf_mem.h"
|
||||
#define Lun_2_test_unit_ready() nf_test_unit_ready()
|
||||
#define Lun_2_read_capacity(nb_sect) nf_read_capacity(nb_sect)
|
||||
#define Lun_2_wr_protect() nf_wr_protect()
|
||||
#define Lun_2_removal() nf_removal()
|
||||
#define Lun_2_read_10(ad, sec) nf_read_10(ad, sec)
|
||||
#define Lun_2_usb_read() nf_usb_read()
|
||||
#define Lun_2_write_10(ad, sec) nf_write_10(ad, sec)
|
||||
#define Lun_2_usb_write() nf_usb_write()
|
||||
#define Lun_2_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_2_ram_2_mem_write() TODO
|
||||
#define Lun_2_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_2_mem_2_ram_read() TODO
|
||||
|
||||
// LUN 3 DEFINE
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define DF_MEM ENABLE
|
||||
#else
|
||||
#define DF_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_ID_DF LUN_ID_3
|
||||
#define LUN_3_INCLUDE "lib_mem\df\df_mem.h"
|
||||
#define Lun_3_test_unit_ready() df_test_unit_ready()
|
||||
#define Lun_3_read_capacity(nb_sect) df_read_capacity(nb_sect)
|
||||
#define Lun_3_wr_protect() df_wr_protect()
|
||||
#define Lun_3_removal() df_removal()
|
||||
#define Lun_3_read_10(ad, sec) df_read_10(ad, sec)
|
||||
#define Lun_3_usb_read() df_usb_read()
|
||||
#define Lun_3_write_10(ad, sec) df_write_10(ad, sec)
|
||||
#define Lun_3_usb_write() df_usb_write()
|
||||
#define Lun_3_ram_2_mem(addr , ram) df_ram_2_df(addr, ram)
|
||||
#define Lun_3_ram_2_mem_write() df_ram_2_df_write()
|
||||
#define Lun_3_mem_2_ram(addr , ram) df_df_2_ram(addr, ram)
|
||||
#define Lun_3_mem_2_ram_read() df_df_2_ram_read()
|
||||
#define LUN_3_NAME "\"On board data flash\""
|
||||
|
||||
// LUN 3 DEFINE
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define AVR_MEM ENABLE
|
||||
#else
|
||||
#define AVR_MEM DISABLE
|
||||
#endif
|
||||
#define LUN_ID_AVRF LUN_ID_4
|
||||
#define LUN_4_INCLUDE "storage/avr_flash.h"
|
||||
#define Lun_4_test_unit_ready() avrf_test_unit_ready()
|
||||
#define Lun_4_read_capacity(nb_sect) avrf_read_capacity(nb_sect)
|
||||
#define Lun_4_wr_protect() avrf_wr_protect()
|
||||
#define Lun_4_removal() avrf_removal()
|
||||
#define Lun_4_read_10(ad, sec) avrf_read_10(ad, sec)
|
||||
#define Lun_4_usb_read() avrf_usb_read()
|
||||
#define Lun_4_write_10(ad, sec) avrf_write_10(ad,sec)
|
||||
#define Lun_4_usb_write() avrf_usb_write()
|
||||
#define Lun_4_ram_2_mem(addr , ram) TODO
|
||||
#define Lun_4_ram_2_mem_write() TODO
|
||||
#define Lun_4_mem_2_ram(addr , ram) TODO
|
||||
#define Lun_4_mem_2_ram_read() TODO
|
||||
#define LUN_4_NAME "\"AVR Flash Memory\""
|
||||
|
||||
|
||||
// LUN USB DEFINE
|
||||
#if (LUN_USB == ENABLE)
|
||||
#define MEM_USB ENABLE
|
||||
#else
|
||||
#define MEM_USB DISABLE
|
||||
#endif
|
||||
#define LUN_USB_INCLUDE "lib_mem\host_mem\host_mem.h"
|
||||
#define Lun_usb_test_unit_ready(lun) host_test_unit_ready(lun)
|
||||
#define Lun_usb_read_capacity(lun,nb_sect) host_read_capacity(lun,nb_sect)
|
||||
#define Lun_usb_wr_protect(lun) host_wr_protect(lun)
|
||||
#define Lun_usb_removal() host_removal()
|
||||
#define Lun_usb_ram_2_mem(addr , ram) host_write_10_ram(addr, ram)
|
||||
#define Lun_usb_mem_2_ram(addr , ram) host_read_10_ram(addr, ram)
|
||||
#define LUN_USB_NAME "\"USB Remote memory\""
|
||||
|
||||
|
||||
// ATMEL DEFINE - DO NOT MODIFY
|
||||
|
||||
// Active interface fonction
|
||||
#define ACCESS_USB ENABLED // USB I/O in control access
|
||||
#define ACCESS_STREAM DISABLED // Stream I/O in control access
|
||||
#define ACCESS_STREAM_RECORD DISABLED // Stream I/O in control access AND RECORD MODE
|
||||
#define ACCESS_MEM_TO_RAM DISABLED // RAM to Mem I/O in control access
|
||||
#define ACCESS_MEM_TO_MEM DISABLED // Mem to Mem I/O in control access
|
||||
|
||||
|
||||
|
||||
// Specific option control access
|
||||
#define GLOBAL_WR_PROTECT DISABLED // To manage a global write protection
|
||||
|
||||
|
||||
#endif //! _CONF_ACCESS_H_
|
||||
|
||||
/** @} */
|
973
cpu/avr/dev/usb/storage/ctrl_access.c
Normal file
973
cpu/avr/dev/usb/storage/ctrl_access.c
Normal file
|
@ -0,0 +1,973 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_access.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
#if (ACCESS_MEM_TO_MEM == ENABLED)
|
||||
#include "modules/file_system/fat.h"
|
||||
U8 buf_sector[FS_SIZE_OF_SECTOR];
|
||||
#endif
|
||||
|
||||
|
||||
//! Computed the maximum of static lun (don't add the lun of Mass Storage in mode USB Host)
|
||||
// FYC: Memory = Logical Unit
|
||||
|
||||
|
||||
|
||||
// CHECK FOR LUN DEFINE
|
||||
#ifndef LUN_0
|
||||
# error LUN_0 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_1
|
||||
# error LUN_1 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_2
|
||||
# error LUN_2 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_3
|
||||
# error LUN_3 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_4
|
||||
# error LUN_4 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_5
|
||||
# error LUN_5 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_6
|
||||
# error LUN_6 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_7
|
||||
# error LUN_7 must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
#ifndef LUN_USB
|
||||
# error LUN_USB must be defined with ENABLE or DISABLE in conf_access.h
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (LUN_0 == ENABLE)
|
||||
#define LUN_0_EN 1
|
||||
U8 FLASH lun0_name[]=LUN_0_NAME;
|
||||
#else
|
||||
#define LUN_0_EN 0
|
||||
#endif
|
||||
#if (LUN_1 == ENABLE)
|
||||
#define LUN_1_EN 1
|
||||
U8 FLASH lun1_name[]=LUN_1_NAME;
|
||||
#else
|
||||
#define LUN_1_EN 0
|
||||
#endif
|
||||
#if (LUN_2 == ENABLE)
|
||||
#define LUN_2_EN 1
|
||||
U8 FLASH lun2_name[]=LUN_2_NAME;
|
||||
#else
|
||||
#define LUN_2_EN 0
|
||||
#endif
|
||||
#if (LUN_3 == ENABLE)
|
||||
#define LUN_3_EN 1
|
||||
U8 FLASH lun3_name[]=LUN_3_NAME;
|
||||
#else
|
||||
#define LUN_3_EN 0
|
||||
#endif
|
||||
#if (LUN_4 == ENABLE)
|
||||
#define LUN_4_EN 1
|
||||
U8 FLASH lun4_name[]=LUN_4_NAME;
|
||||
#else
|
||||
#define LUN_4_EN 0
|
||||
#endif
|
||||
#if (LUN_5 == ENABLE)
|
||||
#define LUN_5_EN 1
|
||||
U8 FLASH lun5_name[]=LUN_5_NAME;
|
||||
#else
|
||||
#define LUN_5_EN 0
|
||||
#endif
|
||||
#if (LUN_6 == ENABLE)
|
||||
#define LUN_6_EN 1
|
||||
U8 FLASH lun6_name[]=LUN_6_NAME;
|
||||
#else
|
||||
#define LUN_6_EN 0
|
||||
#endif
|
||||
#if (LUN_7 == ENABLE)
|
||||
#define LUN_7_EN 1
|
||||
U8 FLASH lun7_name[]=LUN_7_NAME;
|
||||
#else
|
||||
#define LUN_7_EN 0
|
||||
#endif
|
||||
#if (LUN_USB == ENABLE)
|
||||
#define LUN_USB_EN 1
|
||||
U8 FLASH lunusb_name[]=LUN_USB_NAME;
|
||||
#else
|
||||
#define LUN_USB_EN 0
|
||||
#endif
|
||||
|
||||
|
||||
#define LUN_ID_0 (0)
|
||||
#define LUN_ID_1 (LUN_0_EN)
|
||||
#define LUN_ID_2 (LUN_0_EN+LUN_1_EN)
|
||||
#define LUN_ID_3 (LUN_0_EN+LUN_1_EN+LUN_2_EN)
|
||||
#define LUN_ID_4 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN)
|
||||
#define LUN_ID_5 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN)
|
||||
#define LUN_ID_6 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN)
|
||||
#define LUN_ID_7 (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN+LUN_6_EN)
|
||||
#define MAX_LUN (LUN_0_EN+LUN_1_EN+LUN_2_EN+LUN_3_EN+LUN_4_EN+LUN_5_EN+LUN_6_EN+LUN_7_EN)
|
||||
#define LUN_ID_USB (MAX_LUN)
|
||||
|
||||
// Check configuration
|
||||
#if (MAX_LUN == 0)
|
||||
#error No memory is active in conf_access.h
|
||||
#endif
|
||||
|
||||
// Write protect variable
|
||||
#if (GLOBAL_WR_PROTECT == ENABLED)
|
||||
static U8 g_u8_wr_protect;
|
||||
#endif
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S __ F O N C T I O N S _________________________
|
||||
|
||||
|
||||
//! This fonction return the number of logical unit
|
||||
//!
|
||||
//! @return U8 number of logical unit in the system
|
||||
//!
|
||||
U8 get_nb_lun()
|
||||
{
|
||||
#if (MEM_USB == ENABLED)
|
||||
return (MAX_LUN + Host_getlun());
|
||||
#else
|
||||
return MAX_LUN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//! This fonction return the current logical unit
|
||||
//!
|
||||
//! @return U8 number of logical unit in the system
|
||||
//!
|
||||
U8 get_cur_lun()
|
||||
{
|
||||
return 0; //TODO
|
||||
}
|
||||
|
||||
|
||||
//! This fonction test the state of memory, and start the initialisation of the memory
|
||||
//!
|
||||
//! MORE (see SPC-3 §5.2.4) : The TEST UNIT READY command allows an application client
|
||||
//! to poll a logical unit until it is ready without the need to allocate space for returned data.
|
||||
//! The TEST UNIT READY command may be used to check the media status of logical units with removable media.
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//! Not initialize -> CTRL_BUSY
|
||||
//!
|
||||
Ctrl_status mem_test_unit_ready( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_test_unit_ready();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_test_unit_ready(lun - LUN_ID_USB);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction return the capacity of the memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param u32_nb_sector The sector to query
|
||||
//!
|
||||
//! @return *u16_nb_sector number of sector (sector = 512B)
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status mem_read_capacity( U8 lun , U32 _MEM_TYPE_SLOW_ *u32_nb_sector )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_read_capacity( u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_read_capacity( lun - LUN_ID_USB,u32_nb_sector );
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction return is the write protected mode
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection
|
||||
//! !!! The customer must be unplug the card for change this write protected mode.
|
||||
//!
|
||||
//! @return TRUE -> the memory is protected
|
||||
//!
|
||||
Bool mem_wr_protect( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_wr_protect();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_wr_protect(lun - LUN_ID_USB);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction inform about the memory type
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Bool mem_removal( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return Lun_0_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return Lun_1_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return Lun_2_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return Lun_3_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return Lun_4_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return Lun_5_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return Lun_6_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return Lun_7_removal();
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_removal();
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return CTRL_FAIL;
|
||||
}
|
||||
|
||||
//! This fonction returns a pointer to the LUN name
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//!
|
||||
//! @return pointer to code string
|
||||
//!
|
||||
U8 FLASH* mem_name( U8 lun )
|
||||
{
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
return (U8 FLASH*)lun0_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
return (U8 FLASH*)lun1_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
return (U8 FLASH*)lun2_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
return (U8 FLASH*)lun3_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
return (U8 FLASH*)lun4_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
return (U8 FLASH*)lun5_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
return (U8 FLASH*)lun6_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
return (U8 FLASH*)lun7_name;
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return (U8 FLASH*)lunusb_name;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return 0; // Remove compiler warning
|
||||
}
|
||||
|
||||
//************************************************************************************
|
||||
//!----------- Listing of READ/WRITE interface with MODE ACCESS REGISTER -------------
|
||||
//************************************************************************************
|
||||
|
||||
|
||||
//! This fonction tranfer a data from memory to usb
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start read (sector = 512B)
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status memory_2_usb( U8 lun , U32 addr , U16 nb_sector )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_read_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_usb_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
//! This fonction trabsfer a data from usb to memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start write (sector = 512B)
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
//! @return Ctrl_status
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//! Memory unplug -> CTRL_NO_PRESENT
|
||||
//!
|
||||
Ctrl_status usb_2_memory( U8 lun , U32 addr , U16 nb_sector )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_write_10(addr , nb_sector);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_usb_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
//! Interface for RAM
|
||||
#if (ACCESS_MEM_TO_RAM == ENABLED)
|
||||
|
||||
//! This fonction tranfer one sector data from memory to ram
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start read (sector = 512B)
|
||||
//! @param ram Adresse of ram buffer (only xdata)
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Ctrl_status memory_2_ram( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ *ram )
|
||||
{
|
||||
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_mem_2_ram(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_mem_2_ram_read();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_mem_2_ram(*addr , ram);
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ACCESS_MEM_TO_RAM == ENABLED
|
||||
|
||||
|
||||
|
||||
#if (ACCESS_MEM_TO_RAM==ENABLE)
|
||||
|
||||
//! This fonction trabsfer a data from ram to memory
|
||||
//!
|
||||
//! @param lun Logical unit number
|
||||
//! @param addr Sector address to start write (sector = 512B)
|
||||
//! @param ram Adresse of ram buffer (only xdata)
|
||||
//!
|
||||
//! @return TRUE -> The memory is removal
|
||||
//!
|
||||
Ctrl_status ram_2_memory( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ * ram )
|
||||
{
|
||||
Ctrl_status status;
|
||||
|
||||
switch( lun )
|
||||
{
|
||||
# if (LUN_0 == ENABLE)
|
||||
case LUN_ID_0:
|
||||
status = Lun_0_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_0_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_1 == ENABLE)
|
||||
case LUN_ID_1:
|
||||
status = Lun_1_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_1_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_2 == ENABLE)
|
||||
case LUN_ID_2:
|
||||
status = Lun_2_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_2_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_3 == ENABLE)
|
||||
case LUN_ID_3:
|
||||
status = Lun_3_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_3_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_4 == ENABLE)
|
||||
case LUN_ID_4:
|
||||
status = Lun_4_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_4_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_5 == ENABLE)
|
||||
case LUN_ID_5:
|
||||
status = Lun_5_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_5_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_6 == ENABLE)
|
||||
case LUN_ID_6:
|
||||
status = Lun_6_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_6_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_7 == ENABLE)
|
||||
case LUN_ID_7:
|
||||
status = Lun_7_ram_2_mem(*addr , ram);
|
||||
if (CTRL_GOOD == status)
|
||||
{
|
||||
status = Lun_7_ram_2_mem_write();
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
# if (LUN_USB == ENABLE)
|
||||
default:
|
||||
return Lun_usb_ram_2_mem(*addr , ram);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ACCESS_RAM_TO_MEM == ENABLED
|
||||
|
||||
|
||||
|
||||
//! Interface for streaming interface
|
||||
#if (ACCESS_STREAM == ENABLED)
|
||||
|
||||
|
||||
|
||||
// Interface for transfer MEM to MEM
|
||||
# if (ACCESS_MEM_TO_MEM == ENABLED)
|
||||
//! This fonction copy a data from memory to other memory
|
||||
//!
|
||||
//! @param src_lun The LUN of the source
|
||||
//! @param src_addr The address of the source
|
||||
//! @param dest_lun The LUN of the destination
|
||||
//! @param dest_addr The address of the destination
|
||||
//! @param nb_sector Number of sectors to transfer
|
||||
//!
|
||||
U8 stream_mem_to_mem( U8 src_lun , U32 src_addr , U8 dest_lun , U32 dest_addr , U16 nb_sector )
|
||||
{
|
||||
while(nb_sector)
|
||||
{
|
||||
memory_2_ram( src_lun , &src_addr , buf_sector );
|
||||
ram_2_memory( dest_lun , &dest_addr , buf_sector );
|
||||
src_addr++;
|
||||
dest_addr++;
|
||||
nb_sector--;
|
||||
}
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
# endif // ACCESS_MEM_TO_MEM == ENABLED
|
||||
|
||||
|
||||
|
||||
|
||||
//! Returns the state on a data transfer
|
||||
//!
|
||||
//! @param Id transfer id
|
||||
//!
|
||||
//! @return the state of the transfer
|
||||
//! CTRL_GOOD It is finish
|
||||
//! CTRL_BUSY It is running
|
||||
//! CTRL_FAIL It is fail
|
||||
//!
|
||||
Ctrl_status stream_state( U8 Id )
|
||||
{
|
||||
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
//! Stop the data transfer
|
||||
//!
|
||||
//! @param Id Transfer id
|
||||
//!
|
||||
//! @return the number of sector remainder
|
||||
//!
|
||||
U16 stream_stop( U8 Id )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // ACCESS_STREAM == ENABLED
|
||||
|
||||
/** @} */
|
157
cpu/avr/dev/usb/storage/ctrl_access.h
Normal file
157
cpu/avr/dev/usb/storage/ctrl_access.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_access.h *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _MEM_CTRL_H_
|
||||
#define _MEM_CTRL_H_
|
||||
|
||||
#include "storage/conf_access.h"
|
||||
#include "storage/ctrl_status.h"
|
||||
|
||||
// FYC: Memory = Logical Unit
|
||||
#if (LUN_0 == ENABLE)
|
||||
#include LUN_0_INCLUDE
|
||||
#endif
|
||||
#if (LUN_1 == ENABLE)
|
||||
#include LUN_1_INCLUDE
|
||||
#endif
|
||||
#if (LUN_2 == ENABLE)
|
||||
#include LUN_2_INCLUDE
|
||||
#endif
|
||||
#if (LUN_3 == ENABLE)
|
||||
#include LUN_3_INCLUDE
|
||||
#endif
|
||||
#if (LUN_4 == ENABLE)
|
||||
#include LUN_4_INCLUDE
|
||||
#endif
|
||||
#if (LUN_5 == ENABLE)
|
||||
#include LUN_5_INCLUDE
|
||||
#endif
|
||||
#if (LUN_6 == ENABLE)
|
||||
#include LUN_6_INCLUDE
|
||||
#endif
|
||||
#if (LUN_7 == ENABLE)
|
||||
#include LUN_7_INCLUDE
|
||||
#endif
|
||||
#if (LUN_USB == ENABLE)
|
||||
#include LUN_USB_INCLUDE
|
||||
#endif
|
||||
|
||||
|
||||
//------- Test the configuration in conf_access.h
|
||||
|
||||
// Specific option control access
|
||||
#ifndef GLOBAL_WR_PROTECT
|
||||
# error GLOBAL_WR_PROTECT must be defined with ENABLED or DISABLED in conf_access.h
|
||||
#endif
|
||||
//------- END OF Test the configuration in conf_access.h
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
|
||||
//!**** Listing of commun interface ****************************************
|
||||
|
||||
U8 get_nb_lun();
|
||||
U8 get_cur_lun();
|
||||
Ctrl_status mem_test_unit_ready( U8 lun );
|
||||
Ctrl_status mem_read_capacity( U8 lun , U32 _MEM_TYPE_SLOW_ *u32_nb_sector );
|
||||
Bool mem_wr_protect( U8 lun );
|
||||
Bool mem_removal( U8 lun );
|
||||
U8 FLASH* mem_name( U8 lun );
|
||||
|
||||
|
||||
//!**** Listing of READ/WRITE interface ************************************
|
||||
|
||||
|
||||
//---- Interface for USB ---------------------------------------------------
|
||||
Ctrl_status memory_2_usb( U8 lun , U32 addr , U16 nb_sector );
|
||||
Ctrl_status usb_2_memory( U8 lun , U32 addr , U16 nb_sector );
|
||||
#include "usb_drv.h"
|
||||
#include "conf_usb.h"
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//---- Interface for RAM to MEM --------------------------------------------
|
||||
Ctrl_status memory_2_ram( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ *ram );
|
||||
Ctrl_status ram_2_memory( U8 lun , const U32 _MEM_TYPE_SLOW_ *addr , U8 _MEM_TYPE_SLOW_ * ram );
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//!---- Interface for streaming interface ----------------------------------
|
||||
#if (ACCESS_STREAM == ENABLED)
|
||||
|
||||
#define ID_STREAM_ERR 0xFF
|
||||
|
||||
|
||||
// RLE #include "dfc_mngt.h"
|
||||
|
||||
#define TYPE_STREAM_AUDIO DFC_ID_AUDIOPROC1
|
||||
#define TYPE_STREAM_AUDIO2 DFC_ID_AUDIOPROC2
|
||||
#define TYPE_STREAM_SIO DFC_ID_SIO
|
||||
#define TYPE_STREAM_SPI DFC_ID_SPI
|
||||
#define TYPE_STREAM_DEVNULL DFC_ID_NULL_DEV
|
||||
|
||||
U8 stream_mem_to_mem ( U8 src_lun , U32 src_addr , U8 dest_lun , U32 dest_addr , U16 nb_sector );
|
||||
U8 stream_read_10_start ( U8 TypeStream , U8 lun , U32 addr , U16 nb_sector );
|
||||
U8 stream_write_10_start ( U8 TypeStream , U8 lun , U32 addr , U16 nb_sector );
|
||||
U8 stream_to_stream_start ( U8 TypeStream_src , U8 TypeStream_dest , U16 nb_sector );
|
||||
Ctrl_status stream_state( U8 Id );
|
||||
U16 stream_stop( U8 Id );
|
||||
|
||||
#endif // (ACCESS_STREAM == ENABLED)
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#endif // _MEM_CTRL_H_
|
||||
/**@}*/
|
70
cpu/avr/dev/usb/storage/ctrl_status.h
Normal file
70
cpu/avr/dev/usb/storage/ctrl_status.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file ctrl_status.h ********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file contains the interface :
|
||||
* - between USB <-> MEMORY
|
||||
* OR
|
||||
* - between USB <- Access Memory Ctrl -> Memory
|
||||
*
|
||||
* This interface may be controled by a "Access Memory Control" for :
|
||||
* - include a management of write protect global or specific
|
||||
* - include a management of access password
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifndef _CTRL_STATUS_H_
|
||||
#define _CTRL_STATUS_H_
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
//! Define control status
|
||||
typedef enum
|
||||
{
|
||||
CTRL_GOOD =(PASS ) // It is ready
|
||||
, CTRL_FAIL =(FAIL ) // Memory fail
|
||||
, CTRL_NO_PRESENT =(FAIL+1) // Memory unplug
|
||||
, CTRL_BUSY =(FAIL+2) // Not initialize
|
||||
} Ctrl_status;
|
||||
|
||||
#endif // _CTRL_STATUS_H_
|
||||
/** @} */
|
787
cpu/avr/dev/usb/storage/scsi_decoder.c
Normal file
787
cpu/avr/dev/usb/storage/scsi_decoder.c
Normal file
|
@ -0,0 +1,787 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file scsi_decoder.c *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file is the scsi decoder
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
#include "config.h"
|
||||
#include "storage/scsi_decoder.h"
|
||||
#include "conf_usb.h"
|
||||
#include "usb_drv.h"
|
||||
#include "storage/ctrl_status.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
U8 g_scsi_command[16];
|
||||
U8 g_scsi_status;
|
||||
U32 g_scsi_data_remaining;
|
||||
|
||||
FLASH U8 g_sbc_vendor_id[8] = SBC_VENDOR_ID;
|
||||
FLASH U8 g_sbc_product_id[16] = SBC_PRODUCT_ID;
|
||||
FLASH U8 g_sbc_revision_id[4] = SBC_REVISION_ID;
|
||||
|
||||
extern U8 usb_LUN;
|
||||
|
||||
s_scsi_sense g_scsi_sense;
|
||||
|
||||
|
||||
FLASH struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
|
||||
{
|
||||
/* Byte 0 : 0x00 */
|
||||
0x00, /* DeviceType: Direct-access device */
|
||||
0, /* PeripheralQualifier : Currently connected */
|
||||
|
||||
/* Byte 1 : 0x80 */
|
||||
0, /* Reserved1 */
|
||||
1, /* RMB : Medium is removable (this bit must be at 1, else the medium isn't see on Windows) */
|
||||
|
||||
// /* Byte 2 : 0x02 */
|
||||
// 0x02, /* Version: Device compliant to ANSI X3.131:1994 */
|
||||
|
||||
/* Byte 2 : 0x00 */
|
||||
0x00, /* Version: Device not compliant to any standard */
|
||||
|
||||
/* Byte 3 : 0x02 */
|
||||
2, /* Response data format */
|
||||
0, /* NormACA */
|
||||
0, /* Obsolete0 */
|
||||
0, /* AERC */
|
||||
|
||||
/* Byte 4 : 0x1F */
|
||||
/* Byte 5 : 0x00 */
|
||||
/* Byte 6 : 0x00 */
|
||||
/* Reserved4[3] */
|
||||
{
|
||||
0x1F, /* Additional Length (n-4) */
|
||||
0, /* SCCS : SCC supported */
|
||||
0
|
||||
},
|
||||
|
||||
/* Byte 7 : 0x00 */
|
||||
0, /* SoftReset */
|
||||
0, /* CommandQueue */
|
||||
0, /* Reserved5 */
|
||||
0, /* LinkedCommands */
|
||||
0, /* Synchronous */
|
||||
0, /* Wide16Bit */
|
||||
0, /* Wide32Bit */
|
||||
0, /* RelativeAddressing */
|
||||
};
|
||||
|
||||
|
||||
static void send_informational_exceptions_page (void);
|
||||
static void send_read_write_error_recovery_page (U8);
|
||||
static void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length );
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
/**
|
||||
* @brief SCSI decoder function
|
||||
*
|
||||
* This function read the SCSI command and launches the appropriate function
|
||||
*
|
||||
* @warning Code:.. bytes (function FLASH length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool scsi_decode_command(void)
|
||||
{
|
||||
Bool status;
|
||||
|
||||
if (g_scsi_command[0] == SBC_CMD_WRITE_10)
|
||||
{
|
||||
Scsi_start_write_action();
|
||||
status = sbc_write_10();
|
||||
Scsi_stop_write_action();
|
||||
return status;
|
||||
}
|
||||
if (g_scsi_command[0] == SBC_CMD_READ_10 )
|
||||
{
|
||||
Scsi_start_read_action();
|
||||
status = sbc_read_10();
|
||||
Scsi_stop_read_action();
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (g_scsi_command[0]) /* check other command received */
|
||||
{
|
||||
case SBC_CMD_REQUEST_SENSE: /* 0x03 - Mandatory */
|
||||
return sbc_request_sense();
|
||||
break;
|
||||
|
||||
case SBC_CMD_INQUIRY: /* 0x12 - Mandatory */
|
||||
return sbc_inquiry();
|
||||
break;
|
||||
|
||||
case SBC_CMD_TEST_UNIT_READY: /* 0x00 - Mandatory */
|
||||
return sbc_test_unit_ready();
|
||||
break;
|
||||
|
||||
case SBC_CMD_READ_CAPACITY: /* 0x25 - Mandatory */
|
||||
return sbc_read_capacity();
|
||||
break;
|
||||
|
||||
case SBC_CMD_MODE_SENSE_6: /* 0x1A - Optional */
|
||||
return sbc_mode_sense( FALSE );
|
||||
break;
|
||||
|
||||
case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:/* 0x1E */
|
||||
return sbc_prevent_allow_medium_removal();
|
||||
break;
|
||||
|
||||
case SBC_CMD_VERIFY_10: /* 0x2F - Optional */
|
||||
sbc_lun_status_is_good();
|
||||
break;
|
||||
case SBC_CMD_MODE_SENSE_10: /* 0x5A - Optional */
|
||||
return sbc_mode_sense( TRUE );
|
||||
break;
|
||||
|
||||
case SBC_CMD_FORMAT_UNIT: /* 0x04 - Mandatory */
|
||||
|
||||
case SBC_CMD_MODE_SELECT_6: /* 0x15 - Optional */
|
||||
|
||||
|
||||
|
||||
|
||||
case SBC_CMD_START_STOP_UNIT: /* 0x1B - Optional */
|
||||
case SBC_CMD_SEND_DIAGNOSTIC: /* 0x1D - */
|
||||
case SBC_CMD_READ_LONG: /* 0x23 - Optional */
|
||||
case SBC_CMD_SYNCHRONIZE_CACHE: /* 0x35 - Optional */
|
||||
case SBC_CMD_WRITE_BUFFER: /* 0x3B - Optional */
|
||||
case SBC_CMD_RESERVE_10: /* 0x56 - Mandatory */
|
||||
case SBC_CMD_RELEASE_10: /* 0x57 - Mandatory - see chapter 7.16 - SPC 2 */
|
||||
default:
|
||||
{ /* Command not supported */
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI REQUEST SENSE command (0x03)
|
||||
*
|
||||
* The SCSI Sense contains the status of the last command
|
||||
* This status is composed of 3 Bytes :
|
||||
* - sense key (g_scsi_sense.key)
|
||||
* - additional sense code (g_scsi_sense.asc)
|
||||
* - additional sense code qualifier (g_scsi_sense.ascq)
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_request_sense (void)
|
||||
{
|
||||
U8 allocation_length, i;
|
||||
U8 request_sens_output[18]; /* the maximum size of request is 17 */
|
||||
|
||||
allocation_length = g_scsi_command[4]; /* Allocation length */
|
||||
|
||||
/* Initialize the request sense data */
|
||||
request_sens_output[0] = SBC_RESPONSE_CODE_SENSE; /* 70h */
|
||||
request_sens_output[1] = 0x00; /* Obsolete */
|
||||
request_sens_output[2] = g_scsi_sense.key;
|
||||
|
||||
request_sens_output[3] = 0x00; /* For direct access media, Information field */
|
||||
request_sens_output[4] = 0x00; /* give the unsigned logical block */
|
||||
request_sens_output[5] = 0x00; /* address associated with the sense key */
|
||||
request_sens_output[6] = 0x00;
|
||||
|
||||
request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH; /* !! UFI device shall not adjust the Additional sense length to reflect truncation */
|
||||
request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
|
||||
request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
|
||||
request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
|
||||
request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
|
||||
|
||||
request_sens_output[12] = g_scsi_sense.asc;
|
||||
request_sens_output[13] = g_scsi_sense.ascq;
|
||||
|
||||
request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
|
||||
request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
|
||||
request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
|
||||
request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
|
||||
|
||||
/* Send the request data */
|
||||
for( i=0 ; i<allocation_length ; i++ )
|
||||
{
|
||||
Usb_write_byte( request_sens_output[i] );
|
||||
}
|
||||
Sbc_valid_write_usb( allocation_length );
|
||||
|
||||
sbc_lun_status_is_good();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI INQUIRY command (0x12)
|
||||
*
|
||||
* The SCSI Inquiry field contains information regarding parameters
|
||||
* of the target. For example:
|
||||
* - vendor identification
|
||||
* - product identification
|
||||
* - peripheral qualifier
|
||||
* - peripheral device type
|
||||
* - etc
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_inquiry (void)
|
||||
{
|
||||
U8 allocation_length, i;
|
||||
|
||||
#ifdef AVRGCC
|
||||
PGM_VOID_P ptr;
|
||||
#else
|
||||
U8 FLASH *ptr;
|
||||
#endif
|
||||
|
||||
if( (0 == (g_scsi_command[1] & 0x03) ) // CMDT and EPVD bits are 0
|
||||
&& (0 == g_scsi_command[2] ) ) // PAGE or OPERATION CODE fields = 0x00?
|
||||
{
|
||||
//** send standard inquiry data
|
||||
|
||||
// Check the size of inquiry data
|
||||
allocation_length = g_scsi_command[4];
|
||||
if (allocation_length > SBC_MAX_INQUIRY_DATA)
|
||||
{
|
||||
allocation_length = SBC_MAX_INQUIRY_DATA;
|
||||
}
|
||||
|
||||
// send first inquiry data (0 to 8)
|
||||
ptr = (FLASH U8*) &sbc_std_inquiry_data;
|
||||
|
||||
for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
|
||||
{
|
||||
if( 8 == i )
|
||||
{ // send vendor id (8 to 16)
|
||||
ptr = (FLASH U8 *) &g_sbc_vendor_id;
|
||||
}
|
||||
if( 16 == i )
|
||||
{ // send product id (16 to 32)
|
||||
ptr = (FLASH U8 *) &g_sbc_product_id;
|
||||
}
|
||||
if( 32 == i )
|
||||
{ // send revision id (32 to 36)
|
||||
ptr = (FLASH U8 *) &g_sbc_revision_id;
|
||||
}
|
||||
#ifndef AVRGCC
|
||||
Usb_write_byte((U8)(*ptr++)); // send tab
|
||||
#else // AVRGCC does not support point to PGM space
|
||||
#warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// send data (36 to SBC_MAX_INQUIRY_DATA), and can be tranmitted by Bulk
|
||||
// Description of next bytes (this bytes is always egal to 0) :
|
||||
// VendorSpecific : 20 Bytes
|
||||
// Next byte : 1 byte
|
||||
// - InfoUnitSupport : 1 bit
|
||||
// - QuickArbitSupport : 1 bit
|
||||
// - Clocking : 2 bits
|
||||
// - Reserved6 : 4 bits
|
||||
// Reserved7 : 1 byte
|
||||
// VersionDescriptor : 8 bytes
|
||||
// Reserved8 : 22 bytes
|
||||
// ...
|
||||
while( allocation_length > i )
|
||||
{
|
||||
if (64 == i)
|
||||
{ // for each 64 bytes, send USB packet
|
||||
Sbc_valid_write_usb(64);
|
||||
allocation_length -= 64;
|
||||
i = 0;
|
||||
}
|
||||
Usb_write_byte(0); // write value of last bytes of inquiry data
|
||||
i++;
|
||||
}
|
||||
// send last USB packet
|
||||
Sbc_valid_write_usb(allocation_length);
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{ // (CMDT=EVPD <> 0) or (PAGE CODE <> 0x00)
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_test_unit_ready(void)
|
||||
{
|
||||
switch ( mem_test_unit_ready(usb_LUN) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_read_capacity (void)
|
||||
{
|
||||
_MEM_TYPE_SLOW_ U32 mem_size_nb_sector;
|
||||
|
||||
switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
Usb_write_byte(MSB0(mem_size_nb_sector)); // return nb block
|
||||
Usb_write_byte(MSB1(mem_size_nb_sector));
|
||||
Usb_write_byte(MSB2(mem_size_nb_sector));
|
||||
Usb_write_byte(MSB3(mem_size_nb_sector));
|
||||
Usb_write_byte( 0 ); // return block size (= 512B)
|
||||
Usb_write_byte( 0 );
|
||||
Usb_write_byte( (U8)(512 >> 8) );
|
||||
Usb_write_byte( (U8)(512 & 0xFF));
|
||||
|
||||
Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_read_10 (void)
|
||||
{
|
||||
U32 mass_addr; // rd or wr block address
|
||||
U16 mass_size; // rd or write nb of blocks
|
||||
|
||||
MSB0(mass_addr) = g_scsi_command[2]; // read address
|
||||
MSB1(mass_addr) = g_scsi_command[3];
|
||||
MSB2(mass_addr) = g_scsi_command[4];
|
||||
MSB3(mass_addr) = g_scsi_command[5];
|
||||
|
||||
MSB(mass_size) = g_scsi_command[7]; // read size
|
||||
LSB(mass_size) = g_scsi_command[8];
|
||||
|
||||
if (mass_size != 0)
|
||||
{
|
||||
switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No data to transfer
|
||||
sbc_lun_status_is_good();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Bool sbc_write_10 (void)
|
||||
{
|
||||
U32 mass_addr; // rd or wr block address
|
||||
U16 mass_size; // rd or write nb of blocks
|
||||
|
||||
MSB0(mass_addr) = g_scsi_command[2]; // read address
|
||||
MSB1(mass_addr) = g_scsi_command[3];
|
||||
MSB2(mass_addr) = g_scsi_command[4];
|
||||
MSB3(mass_addr) = g_scsi_command[5];
|
||||
|
||||
MSB(mass_size) = g_scsi_command[7]; // read size
|
||||
LSB(mass_size) = g_scsi_command[8];
|
||||
|
||||
if (mass_size != 0)
|
||||
{
|
||||
if( TRUE == mem_wr_protect( usb_LUN ) )
|
||||
{
|
||||
sbc_lun_status_is_protected();
|
||||
return FALSE;
|
||||
#warning For Win98 data must be read to avoid blocking
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))
|
||||
{
|
||||
case CTRL_GOOD :
|
||||
sbc_lun_status_is_good();
|
||||
g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case CTRL_NO_PRESENT :
|
||||
sbc_lun_status_is_not_present();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_BUSY :
|
||||
sbc_lun_status_is_busy_or_change();
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case CTRL_FAIL :
|
||||
default :
|
||||
sbc_lun_status_is_fail();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No data to transfer
|
||||
sbc_lun_status_is_good();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI MODE SENSE command (0x1A for sense 6 and 0x5A for sense 10)
|
||||
*
|
||||
* The SCSI mode sense function returns parameters to an application client.
|
||||
* It is a complementary command to the SCSI MODE SELECT command.
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @param b_sense_10 ( TRUE = sense 10, TRUE = sense 6)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_mode_sense( Bool b_sense_10 )
|
||||
{
|
||||
U8 allocation_length;
|
||||
|
||||
if( b_sense_10 )
|
||||
allocation_length = g_scsi_command[8];
|
||||
else
|
||||
allocation_length = g_scsi_command[4];
|
||||
|
||||
// switch for page code
|
||||
switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
|
||||
{
|
||||
case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS: /* Page Code: Informational exceptions control page */
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
|
||||
send_informational_exceptions_page();
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
|
||||
break;
|
||||
|
||||
case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
|
||||
send_read_write_error_recovery_page(allocation_length);
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
|
||||
break;
|
||||
|
||||
case SBC_PAGE_CODE_ALL:
|
||||
sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
|
||||
if( b_sense_10 )
|
||||
{
|
||||
if (allocation_length == 8)
|
||||
{
|
||||
Sbc_valid_write_usb(8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allocation_length == 4)
|
||||
{
|
||||
Sbc_valid_write_usb(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// send page by ascending order code
|
||||
send_read_write_error_recovery_page(allocation_length); // 12 bytes
|
||||
if (allocation_length > 12)
|
||||
{
|
||||
send_informational_exceptions_page(); // 12 bytes
|
||||
Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sbc_valid_write_usb(allocation_length);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function send the header of the SCSI MODE SENSE command
|
||||
*
|
||||
* @param b_sense_10 TRUE = sense 10, FALSE = sense 6
|
||||
* @param u8_data_length data length in byte
|
||||
*
|
||||
*/
|
||||
void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
|
||||
{
|
||||
// Send Data length
|
||||
if( b_sense_10 )
|
||||
{
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
Usb_write_byte( u8_data_length );
|
||||
|
||||
// Send device type
|
||||
Usb_write_byte(SBC_MEDIUM_TYPE);
|
||||
|
||||
// Write protect status
|
||||
if (mem_wr_protect( usb_LUN ))
|
||||
{
|
||||
Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT); // Device is write protected
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE); // Device is write enabled
|
||||
}
|
||||
|
||||
if( b_sense_10 )
|
||||
{ // Reserved
|
||||
Usb_write_byte(0);
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
|
||||
// Send Block descriptor length
|
||||
if( b_sense_10 )
|
||||
{
|
||||
Usb_write_byte(0);
|
||||
}
|
||||
Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function writes informational exceptions page parameters
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
void send_informational_exceptions_page (void)
|
||||
{
|
||||
Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS); /* Page Code: Informational exceptions control page */
|
||||
/* See chapter 8.3.8 on SPC-2 specification */
|
||||
Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS); /* Page Length */
|
||||
Usb_write_byte(0x00); /* ..., Test bit = 0, ... */
|
||||
Usb_write_byte(SBC_MRIE); /* MRIE = 0x05 */
|
||||
Usb_write_byte(0x00); /* Interval Timer (MSB) */
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00); /* Interval Timer (LSB) */
|
||||
Usb_write_byte(0x00); /* Report Count (MSB) */
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x01); /* Report Count (LSB) */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function writes error recovery page
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @param length The length of
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
void send_read_write_error_recovery_page (U8 length)
|
||||
{
|
||||
Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
|
||||
|
||||
Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY); /* Page Length */
|
||||
Usb_write_byte(0x80);
|
||||
Usb_write_byte(SBC_READ_RETRY_COUNT);
|
||||
Usb_write_byte(SBC_CORRECTION_SPAN);
|
||||
Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
|
||||
Usb_write_byte(SBC_DATA_STROBE_OFFSET);
|
||||
Usb_write_byte(0x00); /* Reserved */
|
||||
|
||||
if (length > 12)
|
||||
{
|
||||
Usb_write_byte(SBC_WRITE_RETRY_COUNT);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
|
||||
Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function manages the SCSI PREVENT ALLOW MEDIUM REMOVAL
|
||||
* command (0x1E)
|
||||
*
|
||||
* The SCSI prevent allow medium removal command requests that the target
|
||||
* enable or disable the removal of the medium in the logical unit.
|
||||
*
|
||||
* @warning Code:.. bytes (function code length)
|
||||
*
|
||||
* @return FALSE: result KO,
|
||||
* TRUE: result OK
|
||||
*
|
||||
*/
|
||||
Bool sbc_prevent_allow_medium_removal(void)
|
||||
{
|
||||
sbc_lun_status_is_good();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! This fonction send the UFI status GOOD
|
||||
//!
|
||||
void sbc_lun_status_is_good(void)
|
||||
{
|
||||
Sbc_send_good();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status "lun not present"
|
||||
//!
|
||||
void sbc_lun_status_is_not_present(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status busy and change
|
||||
//!
|
||||
void sbc_lun_status_is_busy_or_change(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status FAIL
|
||||
//!
|
||||
void sbc_lun_status_is_fail(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
|
||||
}
|
||||
|
||||
//! This fonction send the UFI status FAIL because write protection
|
||||
//!
|
||||
void sbc_lun_status_is_protected(void)
|
||||
{
|
||||
Sbc_send_failed();
|
||||
Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
|
||||
}
|
||||
|
||||
/** @} */
|
338
cpu/avr/dev/usb/storage/scsi_decoder.h
Normal file
338
cpu/avr/dev/usb/storage/scsi_decoder.h
Normal file
|
@ -0,0 +1,338 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file scsi_decoder.h *******************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file is the scsi decoder
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
#ifndef _SCSI_DECODER_H_
|
||||
#define _SCSI_DECODER_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 key;
|
||||
U8 asc;
|
||||
U8 ascq;
|
||||
} s_scsi_sense;
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
Bool scsi_decode_command (void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* Command for all SCSI device types */
|
||||
/****************************************************************************/
|
||||
|
||||
#define SBC_CMD_TEST_UNIT_READY (0x00)
|
||||
#define SBC_CMD_REQUEST_SENSE (0x03)
|
||||
#define SBC_CMD_FORMAT_UNIT (0x04)
|
||||
#define SBC_CMD_READ_6 (0x08)
|
||||
#define SBC_CMD_INQUIRY (0x12)
|
||||
#define SBC_CMD_MODE_SELECT_6 (0x15)
|
||||
#define SBC_CMD_MODE_SENSE_6 (0x1A)
|
||||
#define SBC_CMD_START_STOP_UNIT (0x1B)
|
||||
#define SBC_CMD_RECEIVE_DIAGNOSTICS (0x1C)
|
||||
#define SBC_CMD_SEND_DIAGNOSTIC (0x1D)
|
||||
#define SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL (0x1E)
|
||||
#define SBC_CMD_READ_LONG (0x23)
|
||||
#define SBC_CMD_READ_CAPACITY (0x25)
|
||||
#define SBC_CMD_READ_CD_ROM_CAPACITY (0x25)
|
||||
#define SBC_CMD_READ_10 (0x28)
|
||||
#define SBC_CMD_WRITE_10 (0x2A)
|
||||
#define SBC_CMD_VERIFY_10 (0x2F)
|
||||
#define SBC_CMD_SYNCHRONIZE_CACHE (0x35)
|
||||
#define SBC_CMD_WRITE_BUFFER (0x3B)
|
||||
#define SBC_CMD_CHANGE_DEFINITION (0x40)
|
||||
#define SBC_CMD_READ_TOC (0x43)
|
||||
#define SBC_CMD_MODE_SELECT_10 (0x55)
|
||||
#define SBC_CMD_RESERVE_10 (0x56)
|
||||
#define SBC_CMD_RELEASE_10 (0x57)
|
||||
#define SBC_CMD_MODE_SENSE_10 (0x5A)
|
||||
|
||||
#define SBC_CONTROL_BYTE (0x00)
|
||||
#define SBC_CMD_DIR_IN (0x80)
|
||||
#define SBC_CMD_DIR_OUT (0x00)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Sense Key Code */
|
||||
/****************************************************************************/
|
||||
#define SBC_SENSE_KEY_NO_SENSE (0x00)
|
||||
#define SBC_SENSE_KEY_RECOVERED_ERROR (0x01)
|
||||
#define SBC_SENSE_KEY_NOT_READY (0x02)
|
||||
#define SBC_SENSE_KEY_MEDIUM_ERROR (0x03)
|
||||
#define SBC_SENSE_KEY_HARDWARE_ERROR (0x04)
|
||||
#define SBC_SENSE_KEY_ILLEGAL_REQUEST (0x05)
|
||||
#define SBC_SENSE_KEY_UNIT_ATTENTION (0x06)
|
||||
#define SBC_SENSE_KEY_DATA_PROTECT (0x07)
|
||||
#define SBC_SENSE_KEY_BLANK_CHECK (0x08)
|
||||
#define SBC_SENSE_KEY_VENDOR_SPECIFIC (0x09)
|
||||
#define SBC_SENSE_KEY_COPY_ABORTED (0x0A)
|
||||
#define SBC_SENSE_KEY_ABORTED_COMMAND (0x0B)
|
||||
#define SBC_SENSE_KEY_VOLUME_OVERFLOW (0x0D)
|
||||
#define SBC_SENSE_KEY_MISCOMPARE (0x0E)
|
||||
|
||||
/****************************************************************************/
|
||||
/* ASC code assignments */
|
||||
/****************************************************************************/
|
||||
#define SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION (0x00)
|
||||
#define SBC_ASC_LOGICAL_UNIT_NOT_READY (0x04)
|
||||
#define SBC_ASC_INVALID_FIELD_IN_CDB (0x24)
|
||||
#define SBC_ASC_WRITE_PROTECTED (0x27)
|
||||
#define SBC_ASC_FORMAT_ERROR (0x31)
|
||||
#define SBC_ASC_INVALID_COMMAND_OPERATION_CODE (0x20)
|
||||
#define SBC_ASC_NOT_READY_TO_READY_CHANGE (0x28)
|
||||
#define SBC_ASC_MEDIUM_NOT_PRESENT (0x3A)
|
||||
|
||||
/****************************************************************************/
|
||||
/* ASCQ code assignments */
|
||||
/****************************************************************************/
|
||||
#define SBC_ASCQ_FORMAT_COMMAND_FAILED (0x01)
|
||||
#define SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED (0x02)
|
||||
#define SBC_ASCQ_OPERATION_IN_PROGRESS (0x07)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* REQUEST SENSE PARAMETERS */
|
||||
/****************************************************************************/
|
||||
#define SBC_RESPONSE_CODE_SENSE (0x70)
|
||||
#define SBC_ADDITIONAL_SENSE_LENGTH (0x0A)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_3 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_2 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_1 (0x00)
|
||||
#define SBC_COMMAND_SPECIFIC_INFORMATION_0 (0x00)
|
||||
#define SBC_FIELD_REPLACEABLE_UNIT_CODE (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_2 (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_1 (0x00)
|
||||
#define SBC_SENSE_KEY_SPECIFIC_0 (0x00)
|
||||
|
||||
/******* number of bytes of READ CAPACITY response *********/
|
||||
#define SBC_READ_CAPACITY_LENGTH (0x08)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*MODE SENSE and REQUEST SENSE DEFINITIONS */
|
||||
/****************************************************************************/
|
||||
|
||||
/*************** Direct access medium type ****************/
|
||||
#define SBC_DEFAULT_MEDIUM_TYPE (0x00)
|
||||
#define SBC_FLEXIBLE_DISK_SINGLE_SIDED_UNSPECIFIED (0x01)
|
||||
#define SBC_FLEXIBLE_DISK_DOUBLE_SIDED_UNSPECIFIED (0x02)
|
||||
|
||||
#define SBC_MEDIUM_TYPE SBC_DEFAULT_MEDIUM_TYPE
|
||||
|
||||
#define SBC_DEV_SPEC_PARAM_WR_ENABLE (0x00)
|
||||
#define SBC_DEV_SPEC_PARAM_WR_PROTECT (0x80)
|
||||
#define SBC_BLOCK_DESCRIPTOR_LENGTH (0x00)
|
||||
|
||||
#define SBC_MSK_DBD (0x08)
|
||||
#define SBC_MSK_PAGE_CONTROL (0xC0)
|
||||
#define SBC_MSK_PAGE_CODE (0x3F)
|
||||
|
||||
|
||||
/************ General Page Code paramaters *****************/
|
||||
#define SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY (0x01)
|
||||
#define SBC_PAGE_CODE_FORMAT_DEVICE (0x03)
|
||||
#define SBC_PAGE_CODE_FLEXIBLE_DISK (0x05)
|
||||
#define SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS (0x1C)
|
||||
#define SBC_PAGE_CODE_ALL (0x3F)
|
||||
|
||||
|
||||
#define SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS (0x0A)
|
||||
#define SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY (0x0A)
|
||||
#define SBC_PAGE_LENGTH_FLEXIBLE_DISK (0x1E)
|
||||
#define SBC_PAGE_LENGTH_FORMAT_DEVICE (0x16)
|
||||
|
||||
|
||||
|
||||
#define SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS (SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS + 2 + 3)
|
||||
#define SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY (SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY + 2 + 3 )
|
||||
#define SBC_MODE_DATA_LENGTH_FLEXIBLE_DISK (SBC_PAGE_LENGTH_FLEXIBLE_DISK + 2 + 3 )
|
||||
#define SBC_MODE_DATA_LENGTH_FORMAT_DEVICE (SBC_PAGE_LENGTH_FORMAT_DEVICE + 2 + 3 )
|
||||
/*SBC_PAGE_LENGTH_FLEXIBLE_DISK + 2 + \*/
|
||||
#define SBC_MODE_DATA_LENGTH_CODE_ALL (SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY + 2 + \
|
||||
SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS + 2 + \
|
||||
SBC_BLOCK_DESCRIPTOR_LENGTH + \
|
||||
+ 3 )
|
||||
|
||||
/* SBC_MODE_DATA_LENGTH_FORMAT_DEVICE + 2 + \*/
|
||||
/****** Information exceptions control page parameters *****/
|
||||
#define SBC_MRIE (0x05)
|
||||
|
||||
/*************** Format device page parameters *************/
|
||||
#define SBC_TRACK_PER_ZONE_MSB (0x00)
|
||||
#define SBC_TRACK_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_SECTORS_PER_ZONE_MSB (0x00)
|
||||
#define SBC_ALTERNATE_SECTORS_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_ZONE_MSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_ZONE_LSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_LU_MSB (0x00)
|
||||
#define SBC_ALTERNATE_TRACK_PER_LU_LSB (0x00)
|
||||
|
||||
/************* Flexible Disk page Parameters ***************/
|
||||
#define SBC_TRANSFER_RATE_MSB (0x13)
|
||||
#define SBC_TRANSFER_RATE_LSB (0x88)
|
||||
/* 1388h 5 Mbit/s */
|
||||
/* 07D0h 2 Mbit/s */
|
||||
/* 03E8h 1 Mbit/s */
|
||||
/* 01F4h 500 kbit/s */
|
||||
/* 012Ch 300 kbit/s */
|
||||
/* 00FAh 250 kbit/s */
|
||||
|
||||
#define SBC_NUMBER_OF_HEAD (0x04)
|
||||
#define SBC_SECTOR_PER_TRACK (0x20)
|
||||
#define SBC_DATA_BYTE_PER_SECTOR_MSB (0x02)
|
||||
#define SBC_DATA_BYTE_PER_SECTOR_LSB (0x00)
|
||||
#define SBC_NUMBER_OF_CYLINDERS_MSB (0x01)
|
||||
#define SBC_NUMBER_OF_CYLINDERS_LSB (0xE9)
|
||||
#define SBC_STARTING_CYLINDER_WRITE_COMPENSATION_MSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_WRITE_COMPENSATION_LSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_REDUCED_WRITE_MSB (0x00)
|
||||
#define SBC_STARTING_CYLINDER_REDUCED_WRITE_LSB (0x00)
|
||||
#define SBC_DEVICE_STEP_RATE_MSB (0x00)
|
||||
#define SBC_DEVICE_STEP_RATE_LSB (0x00)
|
||||
#define SBC_DEVICE_STEP_PULSE_WIDTH (0x00)
|
||||
#define SBC_HEAD_SETTLE_DELAY_MSB (0x00)
|
||||
#define SBC_HEAD_SETTLE_DELAY_LSB (0x00)
|
||||
#define SBC_MOTOR_ON_DELAY (0x00)
|
||||
#define SBC_MOTOR_OFF_DELAY (0x00)
|
||||
#define SBC_STEP_PULSE_PER_CYLINDER (0x00)
|
||||
#define SBC_WRITE_COMPENSATION (0x00)
|
||||
#define SBC_HEAD_LOAD_DELAY (0x00)
|
||||
#define SBC_HEAD_UNLOAD_DELAY (0x00)
|
||||
#define SBC_PIN34_PIN2 (0x00)
|
||||
#define SBC_PIN4_PIN1 (0x00)
|
||||
#define SBC_MEDIUM_ROTATION_RATE_MSB (0x00)
|
||||
#define SBC_MEDIUM_ROTATION_RATE_LSB (0x00)
|
||||
|
||||
/************ Read/Write Error Recovery parameters**********/
|
||||
#define SBC_READ_RETRY_COUNT (0x03)
|
||||
#define SBC_WRITE_RETRY_COUNT (0x80)
|
||||
#define SBC_CORRECTION_SPAN (0x00)
|
||||
#define SBC_HEAD_OFFSET_COUNT (0x00)
|
||||
#define SBC_DATA_STROBE_OFFSET (0x00)
|
||||
#define SBC_RECOVERY_LIMIT_MSB (0x00)
|
||||
#define SBC_RECOVERY_LIMIT_LSB (0x00)
|
||||
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
|
||||
#define SBC_MAX_INQUIRY_DATA (0x60) // value ?
|
||||
|
||||
struct sbc_st_std_inquiry_data
|
||||
{
|
||||
Byte DeviceType : 5;
|
||||
Byte PeripheralQualifier : 3;
|
||||
|
||||
Byte Reserved1 : 7;
|
||||
Byte RemovableMedia : 1;
|
||||
|
||||
Byte Version;
|
||||
|
||||
Byte Reserved3 : 5;
|
||||
Byte NormACA : 1;
|
||||
Byte Obsolete0 : 1;
|
||||
Byte AERC : 1;
|
||||
|
||||
Byte Reserved4[3];
|
||||
|
||||
Byte SoftReset : 1;
|
||||
Byte CommandQueue : 1;
|
||||
Byte Reserved5 : 1;
|
||||
Byte LinkedCommands : 1;
|
||||
Byte Synchronous : 1;
|
||||
Byte Wide16Bit : 1;
|
||||
Byte Wide32Bit : 1;
|
||||
Byte RelativeAddressing : 1;
|
||||
};
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
#define Sbc_send_failed() (g_scsi_status = COMMAND_FAILED)
|
||||
#define Sbc_send_check_condition() (g_scsi_status = CHECK_CONDITION)
|
||||
#define Sbc_send_good() (g_scsi_status = COMMAND_PASSED)
|
||||
|
||||
/*#define Sbc_valid_write_usb(length) ( Usb_set_TXRDY(), \
|
||||
dCBWDataTransferLength -= length, \
|
||||
while (!Usb_tx_complete()),\
|
||||
Usb_clear_TXCMPL() )
|
||||
*/
|
||||
#define Sbc_build_sense(skey, sasc, sascq) ( g_scsi_sense.key = skey, \
|
||||
g_scsi_sense.asc = sasc, \
|
||||
g_scsi_sense.ascq = sascq )
|
||||
|
||||
#define Sbc_valid_write_usb(length) ( Usb_send_in(), \
|
||||
g_scsi_data_remaining -= length )
|
||||
|
||||
|
||||
#define COMMAND_PASSED 0x00
|
||||
#define COMMAND_FAILED 0x01
|
||||
#define CHECK_CONDITION 0x02
|
||||
#define PHASE_ERROR 0x02
|
||||
|
||||
|
||||
Bool sbc_inquiry (void);
|
||||
Bool sbc_mode_sense( Bool sense_10 );
|
||||
Bool sbc_mode_select_6 (void);
|
||||
Bool sbc_request_sense (void);
|
||||
Bool sbc_format (void);
|
||||
Bool sbc_write_10 (void);
|
||||
Bool sbc_read_10 (void);
|
||||
Bool sbc_test_unit_ready(void);
|
||||
Bool sbc_read_capacity(void);
|
||||
Bool sbc_prevent_allow_medium_removal(void);
|
||||
|
||||
void sbc_lun_status_is_good(void);
|
||||
void sbc_lun_status_is_busy_or_change(void);
|
||||
void sbc_lun_status_is_not_present(void);
|
||||
void sbc_lun_status_is_fail(void);
|
||||
void sbc_lun_status_is_protected(void);
|
||||
|
||||
#endif /* _SCSI_DECODER_H_ */
|
||||
/** @} */
|
276
cpu/avr/dev/usb/storage/storage_task.c
Normal file
276
cpu/avr/dev/usb/storage/storage_task.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file usb_task.c *********************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB storage.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\addtogroup usbstorage
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "storage/storage_task.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_standard_request.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "storage/scsi_decoder.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
|
||||
extern U8 usb_configuration_nb;
|
||||
|
||||
|
||||
static bit ms_data_direction;
|
||||
static U8 dCBWTag[4];
|
||||
|
||||
extern U8 g_scsi_status;
|
||||
extern U32 g_scsi_data_remaining;
|
||||
extern bit ms_multiple_drive;
|
||||
extern U8 g_scsi_command[16];
|
||||
|
||||
|
||||
U8 usb_LUN;
|
||||
|
||||
|
||||
void usb_mass_storage_cbw (void);
|
||||
void usb_mass_storage_csw (void);
|
||||
|
||||
#define Usb_set_ms_data_direction_in() (ms_data_direction = 1)
|
||||
#define Usb_set_ms_data_direction_out() (ms_data_direction = 0)
|
||||
#define Is_usb_ms_data_direction_in() (ms_data_direction == 1)
|
||||
|
||||
static struct etimer et;
|
||||
|
||||
PROCESS(storage_process, "Storage process");
|
||||
|
||||
/**
|
||||
* \brief USB Mass Storage Class Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by USB Storage Class
|
||||
*/
|
||||
PROCESS_THREAD(storage_process, ev, data_proc)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
|
||||
if (Is_device_enumerated()) {
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
|
||||
if (Is_usb_receive_out()) {
|
||||
usb_mass_storage_cbw();
|
||||
usb_mass_storage_csw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
etimer_set(&et, CLOCK_SECOND/250 + 1);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
} //while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! @brief USB Command Block Wrapper (CBW) management
|
||||
//!
|
||||
//! This function decodes the CBW command and stores the SCSI command
|
||||
//!
|
||||
//! @warning Code:?? bytes (function code length)
|
||||
//!
|
||||
void usb_mass_storage_cbw (void)
|
||||
{
|
||||
bit cbw_error;
|
||||
uint8_t c;
|
||||
uint8_t dummy;
|
||||
|
||||
cbw_error = FALSE;
|
||||
Usb_select_endpoint(MS_OUT_EP); //! check if dCBWSignature is correct
|
||||
if (0x55 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'U'
|
||||
if (0x53 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'S'
|
||||
if (0x42 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'B'
|
||||
if (0x43 != Usb_read_byte())
|
||||
{ cbw_error = TRUE; } //! 'C'
|
||||
|
||||
dCBWTag[0] = Usb_read_byte(); //! Store CBW Tag to be repeated in CSW
|
||||
dCBWTag[1] = Usb_read_byte();
|
||||
dCBWTag[2] = Usb_read_byte();
|
||||
dCBWTag[3] = Usb_read_byte();
|
||||
|
||||
LSB0(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB1(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB2(g_scsi_data_remaining) = Usb_read_byte();
|
||||
LSB3(g_scsi_data_remaining) = Usb_read_byte();
|
||||
|
||||
|
||||
if (Usb_read_byte() != 0x00) //! if (bmCBWFlags.bit7 == 1) {direction = IN}
|
||||
{
|
||||
Usb_set_ms_data_direction_in();
|
||||
if (cbw_error)
|
||||
{
|
||||
Usb_ack_receive_out();
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_set_ms_data_direction_out();
|
||||
if (cbw_error)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_out();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
usb_LUN = Usb_read_byte();
|
||||
|
||||
if (!ms_multiple_drive)
|
||||
{
|
||||
usb_LUN = get_cur_lun();
|
||||
}
|
||||
|
||||
dummy = Usb_read_byte(); //! dummy CBWCBLength read
|
||||
|
||||
|
||||
for (c=0; c<16; c++) // store scsi_command
|
||||
{
|
||||
g_scsi_command[c] = Usb_read_byte();
|
||||
}
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
if (Is_usb_ms_data_direction_in())
|
||||
{
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
}
|
||||
|
||||
if (TRUE != scsi_decode_command())
|
||||
{
|
||||
if (g_scsi_data_remaining != 0)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! @brief USB Command Status Wrapper (CSW) management
|
||||
//!
|
||||
//! This function sends the status in relation with the last CBW
|
||||
//!
|
||||
void usb_mass_storage_csw (void)
|
||||
{
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
while (Is_usb_endpoint_stall_requested())
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) { usb_process_request(); }
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
}
|
||||
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
while (Is_usb_endpoint_stall_requested())
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) { usb_process_request(); }
|
||||
Usb_select_endpoint(MS_OUT_EP);
|
||||
}
|
||||
|
||||
Usb_select_endpoint(MS_IN_EP);
|
||||
while(!Is_usb_write_enabled());
|
||||
//! write CSW Signature
|
||||
Usb_write_byte(0x55); //! 'U'
|
||||
Usb_write_byte(0x53); //! 'S'
|
||||
Usb_write_byte(0x42); //! 'B'
|
||||
Usb_write_byte(0x53); //! 'S'
|
||||
//! write stored CBW Tag
|
||||
Usb_write_byte(dCBWTag[0]);
|
||||
Usb_write_byte(dCBWTag[1]);
|
||||
Usb_write_byte(dCBWTag[2]);
|
||||
Usb_write_byte(dCBWTag[3]);
|
||||
//! write data residue value
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[3] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[2] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[1] );
|
||||
Usb_write_byte( ((Byte*)&g_scsi_data_remaining)[0] );
|
||||
|
||||
//! write command status
|
||||
Usb_write_byte(g_scsi_status); //! 0 -> PASS, 1 -> FAIL
|
||||
Usb_send_in();
|
||||
}
|
||||
|
||||
/** @} */
|
69
cpu/avr/dev/usb/storage/storage_task.h
Normal file
69
cpu/avr/dev/usb/storage/storage_task.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file storage_task.c **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the USB storage.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Atmel Corporation: http://www.atmel.com \n
|
||||
* Support email: avr@atmel.com
|
||||
******************************************************************************/
|
||||
/*
|
||||
Copyright (c) 2004 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup usbstorage USB Mass Storage Task
|
||||
@{
|
||||
*/
|
||||
#ifndef _STORAGE_TASK_H_
|
||||
#define _STORAGE_TASK_H_
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void sof_action(void);
|
||||
|
||||
|
||||
PROCESS_NAME(storage_process);
|
||||
|
||||
#endif /* _STORAGE_TASK_H_ */
|
||||
/** @} */
|
Loading…
Add table
Add a link
Reference in a new issue