Pic Micro, Arduino, Atmel, Microchip, Freescale, Texas Instrument, ecc. Strumenti di sviluppo, firmware e progetti.
#3137
Buon giorno
Avrei bisognodi chiedervi un consiglio su un po' di documentazione per scrivere una routine riguardante la lettura di cartelle e file su un file system fat32 (o 16) e riconoscere se la partizione sia 16 o 32 (comportandosi di conseguenza), da microcontrollore.

Sto svolgendo il progetto su un PIC32MX230F, ho provato ad utilizzare le librerie di gestione File System della Microchip ("MDD File System") ma purtroppo non sembrano funzionare correttamente: mi permetono di creae, rinominare file e scriverlo ma non sembrano funzionare per la parte di lettura (a partire dalla root). Mi riportano costantemente l'errore "CE_BADCAHCEREAD".... Sono partito dagli esempi forniti dal costrutore senza grande successo
Avendo perso ongi speranza e non volendomi arenare vorrei provare a farmi da solo una routine.

Grazie

P.s. se qualcuno avesse qualche suggerimento per far funzionare correttamente la libreria avendo avuto problem simili, sarebbe egualmente ben accetto :)
#3139
Non ho esperienza diretta col PIC32MX230F, ma se dovessi affrontare il problema che riferisci darei un'occhiata al sorgente della funzione di lettura che dà errore.
Non credo che il difetto derivi da un bug, ma piuttosto da una discrepanza tra l'hardware e la configurazione del software.
In pratica, il software sta credendo di operare su una Ferrari mentre in realtà ha sotto una Panda, o viceversa. Può essere un clock che sta andando troppo veloce, o un timer che scatta troppo presto, o una risorsa che diviene insufficiente prima del previsto.
L'errore CE_BADCACHEREAD dovrebbe manifestare il fatto che un'operazione non è andata a buon fine per un motivo prevedibile, non per un crash catastrofico dovuto al caso.
La prima possibilità che mi viene in mente riguarda la stazza della RAM: se il software crede di avere un tot da occupare, e l'hardware è in realtà più piccolo, le richieste di allocazione di un buffer possono fallire.
La seconda possibilità che vaglierei riguarda i clock: se ti è possibile abbassa una per una le cadenze e guarda se il difetto scompare.
In ultimo darei un'occhiata alle dichiarazioni delle variabili prima del main, provando ad invertire l'ordine per vedere se c'è qualche sconfinamento.
Immagina questa sequenza d'esempio: char vars[10]; char pippo; int pluto; pippo = 10;
Se per errore scrivi nell'array vars[] undici elementi, invece di 10 come dovrebbe essere, in realtà hai cambiato il valore di pippo senza accorgertene, e questo potrebbe far danni altrove senza alcuna apparente ragione.
L'idea di scrivere da zero la funzione di lettura è intrigante, ma considera che per "incastrarla" a dovere nel resto del pacchetto avrai bisogno di conoscere mooolti dettagli noiosi :)
Gio55 ringraziano
#3164
Grazie!

L'errore sulle variabili lo posso escludere (anche da aclune prove fatte), poi finora nel main c'è talmente poco... che l'ho potuto verificare facilmente.

Invece per le altre due cause probabilmente è li l'inghippo. Il pic ha 64k di memora e potrebbe essere la casua della saturazione di memoria imprevista. In questo caso come potei procedere?

Invece per il clock, come potrei verificare abbassando la cadenza? Agendo sui bit di configrazione (tipo FPLLODIV FPLLIDIV)? Ho messo un clock esterno da 12Mhz e ho impostato i seguenti parametri (anche per ottenere i 48Mhz necessari alla interfaccia USB)

Codice: Seleziona tutto#pragma config UPLLEN   = ON                        // USB PLL Enabled
    #pragma config FPLLMUL  = MUL_20        // PLL Multiplier
    #pragma config UPLLIDIV = DIV_3              // USB PLL Input Divider
    #pragma config FPLLIDIV = DIV_4              // PLL Input Divider
    #pragma config FPLLODIV = DIV_2            // PLL Output Divider
    #pragma config FPBDIV   = DIV_8               // Peripheral Clock divisor
    #pragma config FWDTEN   = OFF                // Watchdog Timer
    #pragma config WDTPS    = PS1                 // Watchdog Timer Postscale
    #pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
    #pragma config OSCIOFNC = OFF             // CLKO Enable
    #pragma config POSCMOD  = HS              // Primary Oscillator
    #pragma config IESO     = OFF                    // Internal/External Switch-over
    #pragma config FSOSCEN  = OFF             // Secondary Oscillator Enable (KLO was off)
    #pragma config FNOSC    = FRCPLL//FNOSC    = PRIPLL        // Oscillator Selection
    #pragma config CP       = OFF                      // Code Protect
    #pragma config BWP      = OFF                   // Boot Flash Write Protect
    #pragma config PWP      = OFF                   // Program Flash Write Protect
    #pragma config ICESEL   = ICS_PGx1     // ICE/ICD Comm Channel Select

    #pragma config FVBUSONIO= ON
    #pragma config JTAGEN   = OFF
    #pragma config DEBUG    = ON                  // Debug mode ON*/

    #pragma config PMDL1WAY = OFF           // Peripheral Module Disable Configuration
    #pragma config IOL1WAY  = OFF               // Peripheral Pin Select Configuration
    #pragma config FUSBIDIO = ON//OFF     // USB USID Selection (Controlled by the USB Module)
    #pragma config WINDIS   = OFF                  // Watchdog Timer Window Enable
    #pragma config FWDTWINSZ= WINSZ_25      // Watchdog Timer Window Size (Window Size is 25%)
#3165
Gio55 ha scritto:L'errore sulle variabili lo posso escludere (anche da aclune prove fatte), poi finora nel main c'è talmente poco... che l'ho potuto verificare facilmente.

OK, ma verifica che nel main ci siano le necessarie inizializzazioni. Immagino che il pacchetto che gestisce il file system preveda una funzione da chiamare una sola volta in testa al main per predisporre l'ambiente e definire com'è fatto l'hardware. Esisteranno anche un sacco di righe #define sepolte in tanti .h, alcuni dei quali contenenti solo la testata di copyright e l'inclusione di un altro .h subordinata a qualche #ifdef :)

Gio55 ha scritto:Il pic ha 64k di memora e potrebbe essere la casua della saturazione di memoria imprevista. In questo caso come potei procedere?

In teoria, se qualche #define cita esplicitamente il modello di PIC che usi, e durante la compilazione non compaiono dei warning, il software dovrebbe tener conto dei limiti fisici dell'hardware.

Gio55 ha scritto:Invece per il clock, come potrei verificare abbassando la cadenza? Agendo sui bit di configrazione (tipo FPLLODIV FPLLIDIV)?

Probabilmente sì, ma non conosco abbastanza il micro per suggerirti al volo una modifica valida.
Quando mi trovo in situazioni simili procedo in emulazione e collego l'oscilloscopio o l'analizzatore di stati logici a qualche pin libero che "muovo" da software inserendo delle righe in più nel sorgente.
L'idea di base è comunque questa: metti un breakpoint appena prima della funzione che fallisce, e prendi nota del contenuto del buffer che dovrebbe ricevere i dati; esegui la funzione in un colpo solo, e vedi che cosa è cambiato nel buffer e in eventuali parametri di ritorno; infine ripeti la manovra ma entrando nella funzione in modalità passo-passo. Con un po' di fortuna dovresti scoprire un'altra funzione di basso livello che ritorna un errore più specifico di quello che ottieni eseguendo tutto in un colpo solo. Detto così sembra facile, ma ovviamente potresti incontrare una gestione basata su interrupt o, peggio, su DMA, e allora potresti perdere il filo e dover cambiare strategia.
Senza altri dettagli sul sorgente non saprei cos'altro suggerirti. Se il software che stai scrivendo può essere divulgato, prova a postare il pezzo che contiene la funzione a basso livello incriminata.
#3168
No nessuna remora a postre il codice, poi soprattutto in questa fase è praticamente una serie di funzioni richiamate dalla libreria per testare e capire come fare il vero programma. Proprio per questo fa letteralmente "schifo" quindi magari abbiate comprensione..... :lol:

la libreria da quello che vedo è gestita con interrupt.
La catena più o meno dovrebbe essere la seguente (inclusione delle librerie):
- usb
- usb_ch9
- usb_common
- usb_hal
- usb_hal_local
- usb_hal_pic32
- usb_host
- usb_host_hid
- usb_host_hid_parser
-usb_host_msd
- usb_host_msd_scsi

MDD File system:
- FSIO
- CF- Bit transaction
- CF-PMP
- Internal Flash
- SD-SPI

Tutte le definizioni della libreria MDD (del file system Microchip) sono sul file "FSConfig.h", sempre in questo file c'è il link tra la libreria del File System e quella Usb (usb_host_msd_scsi)
Le routine mie sono sui due file "main" e "RoutineUsb".

Non riporto tutto il progetto che credo non potrei neanche caricare, per motivi di dimensione. Dovrebbbero essere questi tre i file principali, il resto sono file di libreria. Comunque dovesse macare qualcosa, aggiungo senza problemi!

La funzione incriminata è "FindFirst" in "RoutineUsb". La penna Usb è enumerata correttamente (anche perchè la scrittura sulla stessa, traminte le funzioni delle librerie, è ok).

Purtroppo la documentazione del costruttore non è molto espilcativa, gli esempi ancor meno....sto cercando di individuare il buffer dei dati letti durante la scansione dei settori nella pennetta.

MAIN.C
Codice: Seleziona tutto
//*****____________________________________
#include <xc.h>

#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <lega-c/machine/types.h>
//#include <lega-c/proc/p32mx795f512l.h>
#include <lega-c/proc/p32mx230f064b.h>
#include "GenericTypeDefs.h"
#include "HardwareProfile.h"
#include "usb_config.h"
#include "USB/usb.h"
////#include "USB/usb_host.h"
#include "USB/usb_host_hid_parser.h"

#include "Common/GenericTypeDefs.h"
#include "USB/usb_host_hid.h"
#include "KeyBoardRoutine.h"
//#include "USB/usb_host_msd.h"
#include "RoutineUsb.h"

#if defined( __PIC32MX__ )
    #pragma config UPLLEN   = ON            // USB PLL Enabled
    #pragma config FPLLMUL  = MUL_20        // PLL Multiplier
    #pragma config UPLLIDIV = DIV_3         // USB PLL Input Divider
    #pragma config FPLLIDIV = DIV_4         // PLL Input Divider
    #pragma config FPLLODIV = DIV_2         // PLL Output Divider
    #pragma config FPBDIV   = DIV_8         // Peripheral Clock divisor
    #pragma config FWDTEN   = OFF           // Watchdog Timer
    #pragma config WDTPS    = PS1           // Watchdog Timer Postscale
    #pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
    #pragma config OSCIOFNC = OFF           // CLKO Enable
    #pragma config POSCMOD  = HS            // Primary Oscillator
    #pragma config IESO     = OFF           // Internal/External Switch-over
    #pragma config FSOSCEN  = OFF           // Secondary Oscillator Enable (KLO was off)
//    #pragma config FNOSC    = PRIPLL        // Oscillator Selection
    #pragma config FNOSC    = FRCPLL//FNOSC    = PRIPLL        // Oscillator Selection
    #pragma config CP       = OFF           // Code Protect
    #pragma config BWP      = OFF           // Boot Flash Write Protect
    #pragma config PWP      = OFF           // Program Flash Write Protect
    #pragma config ICESEL   = ICS_PGx1      // ICE/ICD Comm Channel Select


    #pragma config FVBUSONIO= ON
    #pragma config JTAGEN   = OFF
    #pragma config DEBUG    = ON            // Debug mode ON*/

    #pragma config PMDL1WAY = OFF           // Peripheral Module Disable Configuration
    #pragma config IOL1WAY  = OFF           // Peripheral Pin Select Configuration
    #pragma config FUSBIDIO = ON//OFF       // USB USID Selection (Controlled by the USB Module)
    #pragma config WINDIS   = OFF           // Watchdog Timer Window Enable
    #pragma config FWDTWINSZ= WINSZ_25      // Watchdog Timer Window Size (Window Size is 25%)
   
   

#endif
using namespace std;
//*****____________________________________
#define FREQ_SYS                    0.0000312            //E.g. la frequenza di esecuzione per oscillatore HS interno è 32KHz.
#define Sys_Clk                     4000000//32000       //Fc Frequenza esecuzione CPU (le operazioni, count, sono espresse da 2/Fc)

#define Sys_Prd                     (10000000.0*2.0/((float)(Sys_Clk)))
//*****____________________________________


/*
 * GLOBALS
 */

//*****____________________________________
void setUp(void);
//*****____________________________________

//*****____________________________________
unsigned int      _timeLowScan        = 100;

BOOL                Doloop              = TRUE;
BOOL                _cycleScan          = FALSE;
BOOL                _setUpDone          = FALSE;
int                 countLoop           = 0;
unsigned long int   _timElapse          = 0;

bool onOff =false;
bool onOff1=false;
//*****____________________________________

void delay_ms(int time);
void delay_10us(int time);//void delay_10us(uint32_t time);


//******************************************************************************
//******************************************************************************
// Set up
//******************************************************************************
//******************************************************************************

void setUp(void){
         
    //Configuro la porta D per eseguire segnalazione lampeggio  led (D6, D7 su Led 15,8)
   
    //------------------------------------------------------

         
 
   
    TRISAbits.TRISA0    = 0;
    LATAbits.LATA0 = 0;
   

   
    //Acquisisco la velocità della CPU di elaborazione (per settaggi definiti)
    long int  pnct;
    pnct = GetSystemClock(); 
   
    INTEnableSystemMultiVectoredInt();

   
    InitRoutineUsb();
}

//******************************************************************************
//******************************************************************************
// Main
//******************************************************************************
//******************************************************************************

//string debugFile_folderA[4];
//string debugFile_folderB[4];

int main(void) {     
   
;
   
    unsigned int aux = 0;
    unsigned int aux1 = 0;
    unsigned long int auxCountScan = 0;
   
    setUp();   
                   
   
    while(Doloop==true){                                         
                     
        ProcedureRoutineUsb();
       
               
        if(_cycleScan==TRUE){
            _cycleScan=FALSE;

        }else{
            _cycleScan=TRUE;

        }   
    }
   
    return 0;
}


//----------------------------------------------------------------------
void delay_ms(int time){

    time_t startTime = ReadCoreTimer();     
    float d2 = 0.0;

    while( ((int)(d2*Sys_Prd))<=(time*10000) ){
        asm ("nop");
        d2 = (float)(difftime( ReadCoreTimer() , startTime ));
    }   
   
}
   

void delay_10us(int time){

    time_t startTime = ReadCoreTimer();     
    float d2 = 0.0;
    int d3 = 0;

    while( ((int)(d2*Sys_Prd*1))<=(time*10) ){
        asm ("nop");
        d2 = (float)(difftime( ReadCoreTimer() , startTime ));
        d3 = (int)d2;
    }   
   
}

//----------------------------------------------------------------------



ROUTINE USB
Codice: Seleziona tutto#include "RoutineUsb.h"
#include "MDD File System/FSIO.h"

#ifdef   __cplusplus
extern "C" {
#endif

SearchRec file;
int ris = 0;
BOOL readingOn = FALSE;
   
//******************************************************************************
//******************************************************************************
// Main
//******************************************************************************
//******************************************************************************
   
    volatile BOOL   deviceAttached;
    FSFILE *        myFile;
    BOOL            mantein_connectionMedia = FALSE;   
   
    unsigned char attributes;
    const   char str5[] = {'t',0x00,'e',0x00,'s',0x00,'t',0x00,'.',0x00,'t',0x00,'x',0x00,'t',0x00,'\0', 0x00};
    SearchRec rec;
    //----
    //#define SkipWhiteSpace()    { while (commandInfo.buffer[commandInfo.index] == ' ') commandInfo.index++; }
    #define MAX_COMMAND_LENGTH              50
    char                param1[MAX_COMMAND_LENGTH];
   
    char buffer[40];
    char * pointer;
    //----
   
    void ProcedureRoutineUsb(void){
        //USB stack process function from MICROCHIP LIBRARY
        USBTasks();

        //if thumbdrive is plugged in
        if(USBHostMSDSCSIMediaDetect())
        {
            deviceAttached = TRUE;
           
            //now a device is attached
            //See if the device is attached and in the right format
            if(FSInit())
            { 
                readingOn = TRUE;
                //Main root
                int r;
//                r = FSchdir("\\t\\");                                               
               
                pointer = FSgetcwd (buffer, 40);
               
//                BYTE dataBuffer[512];
//                USBHostMSDSCSISectorRead( 0, dataBuffer );
                                           
                SearchRec  file;
                unsigned char attributes = ATTR_MASK;
                char name[3] = "*.*";
                name[0] = 0x2A;
                name[1] = 0x2E;
                name[2] = 0x2A;
                               
                SearchRec file0;
                unsigned char attributes0 = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_READ_ONLY | ATTR_VOLUME |
                ATTR_ARCHIVE;
                char name0[] = "*.*";
                // Find any non-directory file that has a name starting
                // with the letters FILE
                BYTE looppa = -1;
                while (looppa!=0)
                //if (FindFirst (name0, attributes0, &file0))
                {
                   looppa = FindFirst (name0, attributes0, &file0);//FindFirst (name, attributes0, &file0);
                }
                // Find the next file or directory
                if( FindNext (&file))
                {
                    ris = ris | ( 0b1<<2 );
                }
                if( FindNext (&file))
                {
                    ris = ris | ( 0b1<<3 );
                }

                while (deviceAttached == TRUE){                   
                                                     
                    if(USBHostMSDSCSIMediaDetect()){
                        deviceAttached = TRUE;
                    }else{
                        deviceAttached = FALSE;
                    }
                   
                    //USBTasks();
                }               
            }
        }
    }
   
   
    void ProcedureRoutineUsb_old(void){
        //USB stack process function
        USBTasks();

        //if thumbdrive is plugged in
        if(USBHostMSDSCSIMediaDetect())
        {
            deviceAttached = TRUE;

            //now a device is attached
            //See if the device is attached and in the right format
            if(FSInit())
            {
               
            }
        }
    }
       
   
    void InitRoutineUsb(void){
       
        int  value;

        value = SYSTEMConfigWaitStatesAndPB( GetSystemClock() );

        // Enable the cache for the best performance
        CheKseg0CacheOn();

        INTEnableSystemMultiVectoredInt();

        value = OSCCON;
        while (!(value & 0x00000020)){
            value = OSCCON;    // Wait for PLL lock to stabilize
           
        }

        USBInitialize(0);           // Initialize USB layers

       
    }


    void __ISR(_TIMER_4_VECTOR  , IPL4) _T4Interrupt( void )
    {
        if (IFS0bits.T4IF)
        {
            IFS0bits.T4IF   = 0;
            if(READY_TO_TX_RX_REPORT == App_State_Keyboard)
            {
                App_State_Keyboard = GET_INPUT_REPORT; // If no report is pending schedule new request
            }
        }
    }

   
   
#ifdef   __cplusplus
}
#endif


FSConfig
Codice: Seleziona tutto/******************************************************************************
 *
 *                Microchip Memory Disk Drive File System
 *
 ******************************************************************************
 * FileName:        FSconfig.h
 * Dependencies:    None
 * Processor:       PIC18/PIC24/dsPIC30/dsPIC33
 * Compiler:        C18/C30
 * Company:         Microchip Technology, Inc.
 * Version:         1.0.0
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the ?Company?) for its PICmicro® Microcontroller is intended and
 * supplied to you, the Company?s customer, for use solely and
 * exclusively on Microchip PICmicro Microcontroller products. The
 * software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN ?AS IS? CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
*****************************************************************************/


#ifndef _FS_DEF_

#include "../HardwareProfile.h"

/***************************************************************************/
/*   Note:  There are likely pin definitions present in the header file    */
/*          for your device (SP-SPI.h, CF-PMP.h, etc).  You may wish to    */
/*          specify these as well                                          */
/***************************************************************************/

// The FS_MAX_FILES_OPEN #define is only applicable when Dynamic
// memeory allocation is not used (FS_DYNAMIC_MEM not defined).
// Defines how many concurent open files can exist at the same time.
// Takes up static memory. If you do not need to open more than one
// file at the same time, then you should set this to 1 to reduce
// memory usage
#define FS_MAX_FILES_OPEN    3
/************************************************************************/

// The size of a sector
// Must be 512, 1024, 2048, or 4096
// 512 bytes is the value used by most cards
#define MEDIA_SECTOR_SIZE       512
/************************************************************************/



/* *******************************************************************************************************/
/************** Compiler options to enable/Disable Features based on user's application ******************/
/* *******************************************************************************************************/


// Uncomment this to use the FindFirst, FindNext, and FindPrev
#define ALLOW_FILESEARCH
/************************************************************************/
/************************************************************************/

// Comment this line out if you don't intend to write data to the card
#define ALLOW_WRITES
/************************************************************************/

// Comment this line out if you don't intend to format your card
// Writes must be enabled to use the format function
//#define ALLOW_FORMATS
/************************************************************************/

// Uncomment this definition if you're using directories
// Writes must be enabled to use directories
#define ALLOW_DIRS
/************************************************************************/

// Allows the use of FSfopenpgm, FSremovepgm, etc with PIC18
#if defined(__18CXX)
    #define ALLOW_PGMFUNCTIONS
#endif
/************************************************************************/

// Allows the use of the FSfprintf function
// Writes must be enabled to use the FSprintf function
//#define ALLOW_FSFPRINTF
/************************************************************************/

// If FAT32 support required then uncomment the following
#define SUPPORT_FAT32
/* ******************************************************************************************************* */

// Long File Name is supported
#define SUPPORT_LFN

#define LFNREADWRITE;
/* ******************************************************************************************************* */

// Select how you want the timestamps to be updated
// Use the Real-time clock peripheral to set the clock
// You must configure the RTC in your application code
//#define USEREALTIMECLOCK
// The user will update the timing variables manually using the SetClockVars function
// The user should set the clock before they create a file or directory (Create time),
// and before they close a file (last access time, last modified time)
//#define USERDEFINEDCLOCK
// Just increment the time- this will not produce accurate times and dates
#define INCREMENTTIMESTAMP


#ifdef USE_PIC18
   #ifdef USEREALTIMECLOCK
      #error Some PIC18 devices do not have a Real-time clock and calander module
   #endif
#endif

#ifdef ALLOW_PGMFUNCTIONS
   #ifndef USE_PIC18
      #error The pgm functions are unneccessary when not using PIC18
   #endif
#endif

#ifndef USEREALTIMECLOCK
    #ifndef USERDEFINEDCLOCK
        #ifndef INCREMENTTIMESTAMP
            #error Please enable USEREALTIMECLOCK, USERDEFINEDCLOCK, or INCREMENTTIMESTAMP
        #endif
    #endif
#endif

/************************************************************************/
// Define FS_DYNAMIC_MEM to use malloc for allocating
// FILE structure space.  uncomment all three lines
//#define FS_DYNAMIC_MEM
/************************************************************************/
#if 0
   #define FS_DYNAMIC_MEM
   #ifdef USE_PIC18
      #define FS_malloc   SRAMalloc
      #define FS_free      SRAMfree
   #else
      #define FS_malloc   malloc
      #define FS_free      free
   #endif
#endif


#ifdef __18CXX
    /* Define the locations for the dataBuffer and FATbuffer; PLEASE CHECK THE LINKER FILE */
    #define DATA_BUFFER_ADDRESS      0x800
    #define FAT_BUFFER_ADDRESS       0xA00
#endif


// Function definitions
// Associate the physical layer functions with the correct physical layer
#ifdef USE_SD_INTERFACE_WITH_SPI       // SD-SPI.c and .h

    #define MDD_MediaInitialize     MDD_SDSPI_MediaInitialize
    #define MDD_MediaDetect         MDD_SDSPI_MediaDetect
    #define MDD_SectorRead          MDD_SDSPI_SectorRead
    #define MDD_SectorWrite         MDD_SDSPI_SectorWrite
    #define MDD_InitIO              MDD_SDSPI_InitIO
    #define MDD_ShutdownMedia       MDD_SDSPI_ShutdownMedia
    #define MDD_WriteProtectState   MDD_SDSPI_WriteProtectState
    #define MDD_ReadSectorSize      MDD_SDSPI_ReadSectorSize
    #define MDD_ReadCapacity        MDD_SDSPI_ReadCapacity
    #define MDD_FINAL_SPI_SPEED     2000000

#elif defined USE_CF_INTERFACE_WITH_PMP       // CF-PMP.c and .h

    #define MDD_MediaInitialize     MDD_CFPMP_MediaInitialize
    #define MDD_MediaDetect         MDD_CFPMP_MediaDetect
    #define MDD_SectorRead          MDD_CFPMP_SectorRead
    #define MDD_SectorWrite         MDD_CFPMP_SectorWrite
    #define MDD_InitIO              MDD_CFPMP_InitIO
    #define MDD_ShutdownMedia       MDD_CFPMP_ShutdownMedia
    #define MDD_WriteProtectState   MDD_CFPMP_WriteProtectState
    #define MDD_CFwait              MDD_CFPMP_CFwait
    #define MDD_CFwrite             MDD_CFPMP_CFwrite
    #define MDD_CFread              MDD_CFPMP_CFread

#elif defined USE_MANUAL_CF_INTERFACE         // CF-Bit transaction.c and .h

    #define MDD_MediaInitialize     MDD_CFBT_MediaInitialize
    #define MDD_MediaDetect         MDD_CFBT_MediaDetect
    #define MDD_SectorRead          MDD_CFBT_SectorRead
    #define MDD_SectorWrite         MDD_CFBT_SectorWrite
    #define MDD_InitIO              MDD_CFBT_InitIO
    #define MDD_ShutdownMedia       MDD_CFBT_ShutdownMedia
    #define MDD_WriteProtectState   MDD_CFBT_WriteProtectState
    #define MDD_CFwait              MDD_CFBT_CFwait
    #define MDD_CFwrite             MDD_CFBT_CFwrite
    #define MDD_CFread              MDD_CFBT_CFread

#elif defined USE_USB_INTERFACE               // USB host MSD library

    #define MDD_MediaInitialize     USBHostMSDSCSIMediaInitialize
    #define MDD_MediaDetect         USBHostMSDSCSIMediaDetect
    #define MDD_SectorRead          USBHostMSDSCSISectorRead
    #define MDD_SectorWrite         USBHostMSDSCSISectorWrite
    #define MDD_InitIO();             
    #define MDD_ShutdownMedia       USBHostMSDSCSIMediaReset
    #define MDD_WriteProtectState   USBHostMSDSCSIWriteProtectState

#endif

#endif
#3170
Seguendo in debug anche entro le chiamate alle funzioni della libreria ho scoperto forse il punto dove si "inceppa". La funzione MDD_SectorRead (dalla libreria in FSConfig.h associata a USBHostMSDSCSISectorRead, di usb_host_msd_scsi.h) ritorna FALSE ovvero il settore che dovrebbe leggere, non può essere letto...

Riproto la descrizione della funzione da Microchip:

Codice: Seleziona tutto/****************************************************************************
  Function:
    BYTE USBHostMSDSCSISectorRead( DWORD sectorAddress, BYTE *dataBuffer)

  Summary:
    This function reads one sector.

  Description:
    This function uses the SCSI command READ10 to read one sector.  The size
    of the sector was determined in the USBHostMSDSCSIMediaInitialize()
    function.  The data is stored in the application buffer.

  Precondition:
    None

  Parameters:
    DWORD   sectorAddress   - address of sector to read
    BYTE    *dataBuffer     - buffer to store data

  Return Values:
    TRUE    - read performed successfully
    FALSE   - read was not successful

  Remarks:
    The READ10 command block is as follows:

    <code>
        Byte/Bit    7       6       5       4       3       2       1       0
           0                    Operation Code (0x28)
           1        [    RDPROTECT      ]  DPO     FUA      -     FUA_NV    -
           2        [ (MSB)
           3                        Logical Block Address
           4
           5                                                          (LSB) ]
           6        [         -         ][          Group Number            ]
           7        [ (MSB)         Transfer Length
           8                                                          (LSB) ]
           9        [                    Control                            ]
    </code>
  ***************************************************************************/


Chissa se anche questo può essere di auiuto a risolvere l'arcano.
#3173
Gio55 ha scritto:Seguendo in debug anche entro le chiamate alle funzioni della libreria ho scoperto forse il punto dove si "inceppa"... Chissa se anche questo può essere di auiuto a risolvere l'arcano.

E' un ottimo punto d'inizio, visto che l'errore sembra nascere proprio da qui. Suggerirei di controllare tutti i campi del READ10 command block, prima e dopo la chiamata della funzione. Se, per ipotesi, il Logical Block Address contenesse un numero fuori della gamma permessa, la funzione avrebbe un buon motivo per fallire. Anche l'indirizzo del buffer passato alla funzione andrebbe verificato, poiché potrebbe riferirsi ad una zona di RAM inesistente. Altro check opportuno è suggerito dalla frase "The size of the sector was determined in the USBHostMSDSCSIMediaInitialize()": siamo certi che tale funzione sia stata eseguita prima di chiedere la lettura? Siamo certi che l'ampiezza di settore ottenuta durante l'init sia conforme all'hardware? Un'altra prova che potresti fare è ricompilare da zero tutti i sorgenti che usi, compresi gli header, perché a volte gli IDE non si accorgono che un file .h è stato modificato, e mantengono la versione precedente che trovano nella loro cache. Non a caso gli Integrated Development Environment (IDE) prevedono l'opzione Clean insieme a Compile e Build :)
Gio55 ringraziano
#3174
L'indirizzo del buffer dovrebbe essere ok. Ho controllato in debug, viene assegnato l'indirizzo A400030C (della Ram). La Ram del micro da datasheet va da A0000000 a A0003FFF.

La funzione HostMSDSCSIMediaInitialize viene richiamata dalla funzione FSInit, la funzione prova a leggere il disco vede il tipo di partizione (FAT32) e la dimensione del settore (200).

Il problema penserei si aggiri attorno al Logical Block Address. Le librerie lo impostano così:
Codice: Seleziona tutto    // Fill in the command block with the READ10 parameters.
    commandBlock[0] = 0x28;     // Operation code
    commandBlock[1] = RDPROTECT_NORMAL | FUA_ALLOW_CACHE;
    commandBlock[2] = (BYTE) (sectorAddress >> 24);     // Big endian!
    commandBlock[3] = (BYTE) (sectorAddress >> 16);
    commandBlock[4] = (BYTE) (sectorAddress >> 8);
    commandBlock[5] = (BYTE) (sectorAddress);
    commandBlock[6] = 0x00;     // Group Number
    commandBlock[7] = 0x00;     // Number of blocks - Big endian!
    commandBlock[8] = 0x01;
    commandBlock[9] = 0x00;     // Control


ove "commandBlock" è il vettore usato per inviare il comando sulla usb nella funzione relativa al "READ10". sectorAddress (è pari a 403F) viene ricavata dall'indirizzo del settore e da un offset (c'è una funzione nelle ibrerie che calcola il prossimo settore da leggere), l'offset è zero credo che da qui cominci la lettura dell'area dati.
Il dubbio che vedo e non comprendo sono i campi dei byte 6 - 7. Perchè sono a 0 ? E prorio così vengono inviati...

Grazie ancora!
#3175
Gio55 ha scritto:L'indirizzo del buffer dovrebbe essere ok. Ho controllato in debug, viene assegnato l'indirizzo A400030C (della Ram). La Ram del micro da datasheet va da A0000000 a A0003FFF.

Salvo errori di battitura, A400030C non è nella gamma A0000000 - A0003FFF (A4 invece di A0).

Gio55 ha scritto:Il dubbio che vedo e non comprendo sono i campi dei byte 6 - 7. Perchè sono a 0 ? E prorio così vengono inviati...

Non conosco in dettaglio l'impiego dei byte 6 e 7, ma mi è capitato in altri contesti di scoprire che in realtà non sono parametri in ingresso ma valori di ritorno in uscita. In pratica, prima della funzione valgono 0, e dopo la funzione contengono il numero di blocchi effettivamente letti. Per dissipare il dubbio potresti dare un'occhiata al Command Block che viene costruito durante la scrittura che va a buon fine. Se il debugger te lo permette puoi anche scrivere A000030C al posto di A400030C un attimo prima di eseguire la funzione.
#3177
Purtroppo è una mia svista, l'indirizzo è A400030C. Dal datasheet dice "reserv".

Ancora non ho avuto modo di controllare quei due campi con una prova in debug per vedere come si modifcano prima e dopo la trasmissione. Nella documentazione dello standard usb risultano riservati, quindi penserei che siano proprio usati per comunicare il numero di blocchi acquisiti.
Vendo

OWON HDS2202S nuovo imballo originale 190.00 eur[…]

Sono comuni interruttori a levetta DPDT. Se le due[…]

Visita il nostro canale telegram