Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Balkonkraftwerk Speicher und Wechselrichter Tests und Tutorials

QuellCode Get Flash FileSector.bas


'CopyRight
   'Dipl.-Ing. Norbert L. Brodtmann , Gütersloh Germany

   'This program is wrote to become familiar with SD-Card technologies
   'in order to integrate it in my 8-acis Robotic-Controller (www.RoBo-mac.de).

   'It is based on J.F. Vögel's  AVR-DOS and uses parts of its code issued in his product documentation.
   'It may be used in accordance of BASCOM's and AVR-DOS's license policy and agreement.

'*  This program returns the Start-Sector Number of any file - short filenames (8.3) - stored in a Flash-Card
'   in order to use it with direct access of the commands  DriveWriteSektor() / DriveReadSektor() etc.

'*  It also gives output to measure Transfer-Time; to benefit this, you need an oscilloscope.

'*  You can use this program just to become familiar with SD-Cards too
'   or include parts in your application. Therefore it is divvied in 5 parts.


'Part 1
   'Declaration based on the used Hardware (Mega 128 / LCD 4 x 20 / SD-Card board of Display 3000).

'Part 2
   'Additional declaration of including AVR-DOS and the type of Flash-Card used (FC, SD/MCC etc. ).
   'Please note: You have to adapt the "config_CARD.bas" (for example Config_MMC.bas) to your system too.
   'There is a (Compiler-) Function-switch to select of the following possibilities.

   'Function_1  Test DOS-Commands using COM/TERMINAL in dialog
   'Function_2  Running Part 3 to 5
   'Function_3  Direct Sector Access and measurement of transfer-time by using an oscilloscope (Bort B.7)
   '            In addition you will find a trick to read a file's
   '            - (Long)-Name (up to 40 Characters + Extension =  44 in total incl. "dot") and its
   '            - Date/Time-Stamp.

   'Function_1/2  needs a SRAM Size > 3k, Function_3 less than 1k

'Part 3
   'A "GOSUB" Routine_fileinfo
   'Asking for the files name (8.3) and searching information concerning this file (also including the Sector#)

'Part 4
   'A "GOSUB" Routine_sector_select
   'using the Sector# with the command DriveReadSektor() as a "how to do" example

'Part 5
   'A "GOSUB" Routine_transfer_time_1
   'to measure transfer time. Bort B.7 toggles with every DriveReadSektor() command.
   'Using an oscilloscope you will get an frequency. Each period consists the time to read two sectors!

   'This Routine is based on something similar I found in the Internet several times
   '- however I do not know the Copyright owner, I suppose it is shareware.

'Please note:
'There is a tutorial (in German language) concerning these items at ......



'--- Part1 ---------------------------------------------------
$regfile = "m128def.dat"                                    'ATmega128
$crystal = 16000000


'---
Config Lcdbus = 4                                           '4-bit Step_Step_Mode
Config Lcd = 20 * 4                                         '20x4 LCD display
Config Lcdpin = Pin , Db4 = Porte.4 , Db5 = Porte.5 , Db6 = Porte.6 , Db7 = Porte.7 , E = Porte.3 , Rs = Porte.2


Const Lcd_line1 = "Get_Flash_FileSector"
Const Lcd_line2 = "CopyRight:"
Const Lcd_line3 = "     www.RoBo-mac.de"

Cls : Cursor Off Noblink
Locate 1 , 1 : Lcd Lcd_line1
Locate 2 , 1 : Lcd Lcd_line2
Locate 3 , 1 : Lcd Lcd_line3

'Special Function (Display 3000)
Config Pinb.4 = Input                                       'Cardsensor
Config Pinb.5 = Output                                      'SD-Card      active (High) / inaktiv (Low)
Config Pinb.6 = Input                                       'Writeprotect active (Low)  / inaktiv (High)
Config Pinb.7 = Output                                      'Toggel

Portb = &B01110000

   If Pinb.4 = 1 Then
      Locate 4 , 1 : Lcd "Card NO"
      End
   Else
      Locate 4 , 1 : Lcd "Card YES "

      If Pinb.6 = 1 Then
        Locate 4 , 11 : Lcd "read only"
      Else
        Locate 4 , 11 : Lcd "read/write"
      End If
   End If

'--- Part2 ---------------------------------------------------

' Adjust HW Stack, Soft-Stack and Frame size to 128 minimum each!!!
$hwstack = 128
$swstack = 128
$framesize = 128

Enable Interrupts

$baud1 = 9600
Open "Com1:" As Binary As #1                                ' use #1 for fs_interpreter


'Include here your driver for Compactflash/HardDisk or other
   '$include "Config_CompactFlash_M128.bas"
   '$Include "Config_HardDisk_M128.bas"
   $include "Config_MMC.bas"

'Select a function
   'Const Function_switch = 1                                'SRAM ca. 3340 / FS_Interpreter.bas active
   'Const Function_switch = 2                                'SRAM ca. 3030 / will use Part 3 to 5
   Const Function_switch = 3                                'SRAM ca.  780 / Just direct Sector Access


#if Function_switch = 3
'Direct Sector Access and measurement of transfer-time
'Does not neet:  Config_AVR-DOS.bas !!!

Dim Ptr As Word                                             'Address-Pointer SRAM
Dim Buffer As String * 512
Dim Mmc_error As Byte
Dim Sector_now As Word

   Ptr = Varptr(buffer)

   For Sector_now = 512 To 10511                            '512 is normaly the first Data-Sector

   'Sector_now = 512                                         'endles

      'Toggle Portb.7
      Set Portb.7
      Mmc_error = Drivereadsector(ptr , Sector_now)         'Ca. 1,37 msec HW / 6,05 msec SW  per Sector
      'Mmc_error = Drivewritesector(ptr , Sector_now)        'Ca. 1,83 msec HW / 7,5 msec SW  per Sector
      Reset Portb.7

''(
'The following code will only work fine, if these information
'- are specially placed by the PC-Program writing the file
'- to a very fresh formatted SD-Card!!!

Dim Datei_name As String * 45 At Buffer + 00 Overlay        'File Name max: (40.3)
Dim Datei_date_time As String * 19 At Buffer + 45 Overlay
Dim Interim As Byte
Dim Interim_2 As Byte At Mmc_error + 00 Overlay


      If Sector_now = 512 Then
         Waitms 1500
         Locate 4 , 1 : Lcd Spc(20)
         Locate 4 , 1 : Lcd Mid(datei_name , 1 , 20)
         Wait 1

         Interim_2 = Len(datei_name)                        'Shiftlcd Left  moves whole display, therefore
         If 20 < Interim_2 Then
            Interim_2 = Interim_2 - 19
            For Interim = 2 To Interim_2
               Locate 4 , 1 : Lcd Mid(datei_name , Interim , 20)
               Waitms 200
            Next
            Wait 1
         End If

         Locate 4 , 1 : Lcd Mid(datei_date_time , 1 , 19) + " "
         Wait 1
      End If
'')
   Next

End
'-------------------------------------------------------------
#else
   $include "Config_AVR-DOS.bas"                            'Include AVR-DOS Configuration and library

Dim Btemp1 As Byte

   Print #1 , "Wait for Drive"
   If Gbdriveerror = 0 Then
      Print #1 , "Init File System ... ";
      Btemp1 = Initfilesystem(1)                            ' Partition 1
                                                              ' use 0 for drive without Master boot record
      If Btemp1 <> 0 Then
        Print #1 ,
        Print #1 , "Error: " ; Btemp1 ; " at Init file system"
        Print #1 ,
        End
      Else
        Print #1 , " OK"
        Print #1 , "Filesystem:           " ; Gbfilesystem
        Print #1 , "FAT Start Sector:     " ; Glfatfirstsector
        Print #1 , "Root Start Sector:    " ; Glrootfirstsector
        Print #1 , "Data First Sector:    " ; Gldatafirstsector
        Print #1 , "Max. Cluster Nummber: " ; Glmaxclusternumber
        Print #1 , "Sectors per Cluster:  " ; Gbsectorspercluster
        Print #1 , "Root Entries:         " ; Gwrootentries
        Print #1 , "Sectors per FAT:      " ; Glsectorsperfat
        Print #1 , "Number of FATs:       " ; Gbnumberoffats
        Print #1 ,
        Print #1 ,
      End If
   Else
      Print #1 , "Error during Drive Init: " ; Gbdriveerror
      End
   End If
#endif

#if Function_switch = 1
   Config Clock = Soft
   Config Date = Mdy , Separator = .
   $include "FS_Interpreter.bas"                            'No GOSUBs allowed, (DIM conflicts)
#endif

#if Function_switch = 2
   Gosub Routine_fileinfo
   Gosub Routine_sector_select
   Gosub Routine_transfer_time_1
#endif

End

#if Function_switch = 2
'--- Part3 ---------------------------------------------------

Routine_fileinfo:

Dim File_name As String * 12
Dim Pbfilenr As Byte

Dim Lltemp1 As Long
Dim Lbfilenumber As Byte
Dim Lbfilemode As Byte
Dim Lwfiledirentry As Word
Dim Llfiledirsectornumber As Long
Dim Llfilefirstcluster As Long
Dim Llfilesize As Long
Dim Llfileposition As Long
Dim Llfilesectornumber As Long
Dim Lbfilebufferstatus As Byte
Dim Lwfilebufferaddress As Word

Dim Sector_start As Long

Pbfilenr = 127   'use 127, to avoid conflicts with auto generatet numbers from FreeFile (128 to 255)

File_select:
   Input "Select FileName  (8.3) / Type END to finish program  " , File_name
   Locate 2 , 1 : Lcd "File:               "
   Locate 2 , 7 : Lcd File_name
   Locate 3 , 1 : Lcd "                    "

   If Ucase(file_name) = "END" Then
      Print #1 , "Program finished"
      Locate 3 , 1 : Lcd "Program finished"

      End
   End If
   Open File_name For Input As #pbfilenr

   Loadadr Pbfilenr , X
   ld r24, X
   !Call _GetFileHandle
   brcc PrintFileInfo1
   rjmp PrintFileInfoError
Printfileinfo1:
   Loadadr Lbfilenumber , X
   ldi r24, 25
   !Call _Mem_Copy
   Loadadr Lwfilebufferaddress , X
   st X+, zl
   st X+, zh

   Print #1 ,
   Print #1 , "File            " ; File_name
   Print #1 , "Handle#:        " ; Lbfilenumber
   Print #1 , "Open mode:      " ; Bin(lbfilemode)
   Print #1 , "Dir Entry#:     " ; Lwfiledirentry
   Print #1 , "Dir Sector#:    " ; Llfiledirsectornumber
   Print #1 , "First Cluster#: " ; Llfilefirstcluster
   Print #1 , "Size:           " ; Llfilesize
   Print #1 , "Position:       " ; Llfileposition
   Print #1 , "Sector#:        " ; Llfilesectornumber
   Print #1 , "Buffer Status:  " ; Bin(lbfilebufferstatus)
   Lltemp1 = 0

   Sector_start = Llfilesectornumber
   Close #pbfilenr

   Locate 3 , 1 : Lcd "Sector#:"
   Locate 3 , 10 : Lcd Sector_start

Return

Printfileinfoerror:
   'Print #1 , "No Filehandle for " ; Pbfilenr ; " found"
   Print #1 , "FileName < " ; File_name ; " > Not Found "
   Print #1 ,
   Locate 3 , 1 : Lcd "     Not Found      "
   Goto File_select

'--- Part4 ---------------------------------------------------
Routine_sector_select:

Dim Ptr As Word                                             'Address-Pointer SRAM
Dim Buffer As String * 512
Dim Mmc_error As Byte
Dim Sector_now As Long
Dim Sector_size As Long
Dim Sector_max As Long


   Sector_size = Llfilesize
   Shift Sector_size , Right , 9                            'Division 512 Byte/Sector

   'Btemp1 = Llfilesize \ 512                                'does not work correct, therefore:

   Shift Sector_size , Left , 9
   If Sector_size < Llfilesize Then
      Shift Sector_size , Right , 9
      Sector_size = Sector_size + 1
   Else
      Shift Sector_size , Right , 9
   End If

   Ptr = Varptr(buffer)                                     'SRAM Adr von Buffer
   Mmc_error = Drivereadsector(ptr , Sector_start)

   Print
   Print
   Print "SectorSize:     " ; Sector_size
   Print "Read Start-Sector(" ; Sector_start ; ") ok."
   Print
   Print Buffer
   Print

Return

'--- Part5 ---------------------------------------------------
Routine_transfer_time_1:

   Print "For 'Transfer-Time' measurement with an oscilloscope use toggling PortB.7"
   Print "- 1 Period represents 2 Sectors"
   Print
   Print "Test the 'Transfer-Time' "
   Print "  - for Read and Write (to be choosen by changing block-marker)"
   Print "  - with and without the Print-Commands"
   Print "  - with Soft/Hard SPI. To do so, select used SPI in File  Config_CARD.bas"
   Print
   Input "To start the test, strike ENTER/RETURN now ! / Type END to finish program" , File_name
   Print
   Print

   If Ucase(file_name) = "END" Then
      Print #1 , "Program finished"
      Locate 3 , 1 : Lcd "Program finished"

      End
   End If


   Ptr = Varptr(buffer)
   Sector_max = Sector_start + Sector_size
   Sector_max = Sector_max - 1

   If Gbdriveerror = 0 Then
      Mmc_error = Driveinit()
      If Mmc_error = 0 Then
         Print "Driveinit Ok. "

         For Sector_now = Sector_start To Sector_max
            Toggle Portb.7
'Read
''(
            Mmc_error = Drivereadsector(ptr , Sector_now)
            If Mmc_error = 0 Then
               Print "ReadSector(" ; Sector_now ; ") ok."
               Print Buffer
            Else
               Print "Error during ReadSector(" ; Sector_now ; ") : " ; Mmc_error
            End If
'')
'----------------
'Write
'(                                                           '                                                        '
            Mmc_error = Drivewritesector(ptr , Sector_now)
            If Mmc_error = 0 Then
               Print "WriteSector(" ; Sector_now ; ") ok."
               Print Buffer
            Else
               Print "Error during WriteSector(" ; Sector_now ; ") : " ; Mmc_error
            End If
')
         Next Sector_now
      Else
         Print "Error during Driveinit(): " ; Mmc_error
      End If

      Print "End of Test"
   End If

Return

#endif

Siehe auch


LiFePO4 Speicher Test