Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Схемы » Программатор Dataflash AT45DBxx


Программатор Dataflash AT45DBxx

Сообщений 1 страница 18 из 18

1

Давайте общими усилиями придумаем программатор для этой памяти! ))

ВНИМАНИЕ!!! Схемы с LPT и прочие "пять проводков" сюда не писать - задача сделать девайс под новые ноутбуки или под те компьютеры, где нет COM, LPT

Основные требования:
1) Работа по USB через переходник FT232BM
2) Программирование микроконтроллером, т.е. схема такая: FT232BM -> Atmega8(например) - > Dataflash
3) Загрузка прошивки с помощью простой терминальной утилиты

Схема устройства простая:
1) Микросхема FT232BM ведет обмен данными с микроконтроллером через UART
2) Микроконтроллер подрублен к флехе через встроенный в MCU интерфейс SPI
3) Питается все по схеме USB -> LM1117 (преобразователь напряжения в 3.3 В)

Отредактировано yakuzaa (2008-04-01 17:22:32)

0

2

Программатор полностью функционирует!!! (14 апреля 2008 г.)

Вот собственно код для mega32 (эта микросхема выбрана в отладочных целях)

(С) - за основу взят проект программатора I2C микросхем памяти, который описан на:

http://www.mcselec.com/index.php?option … ;Itemid=57

я только заменил процедуры I2C на процедуры работы с dataflash

программное обеспечение остается тем же :)

программатор наконец-таки заработал - данные в микруху пишет!!! :D :D :D

Ошибка скрывалась в обработчике прерывания UART

Но для воспроизведения звукового фрагмента из флешки все равно пользуюсь процедурами Ведущего Специалиста - за что ему огррромное спасибо! :-)

Исходный код PROGRAMMATOR.BAS:

Код:
$regfile = "m32def.DAT"
$crystal = 16000000
$baud = 19200
$hwstack = 256
$swstack = 256
$framesize = 256

Dim Startbyte As Byte , Instring As String * 45 , Complete As Bit
Dim Temp As Byte , Temps As String * 3
Dim Bytecount As Byte , Addresshigh As Byte , Addresslow As Byte , Recordtype As Byte , Databyte(16) As Byte , Checksm As Byte
Dim Lus As Byte , Pos As Byte , Checksum_calc As Byte , Checksum_error As Bit
Dim Pagge As Word , Addresse As Word
Pagge = 0
Addresse = 0

Enable Urxc
Enable Interrupts
On Urxc Bytereceived_isr

$include "at45.bas"
Waitms 300
'=== Main  ===

Do
If Complete = 1 Then                                        'Wait until the buffer is filled with one line
  Gosub Process_buffer                                      'Process the buffer
  Gosub Calculate_checksum                                  'Calculate the cheksum
     If Recordtype = &H01 Then                              'EOF finished, send a ACK and return
      Print "Y";
     Else
       If Checksum_error = 0 Then                           'If there's no error continue
         Select Case Recordtype                             'do something with the recordtype
            Case &H00                                       'Data byte
                Gosub Prog_eeprom                           'Recordtype &H00 = databyte, so lets programm the Eeprom
            Case &H02                                       'Extended Linear Address Records, not (yet) supported
               nop
         End Select
       Print "Y";                                           'Checksum ok, send a ACK
      Else
       Print "Z";                                           'Checksum error send a Nack
     End If
    End If
  Complete = 0 : Instring = ""                              'Reset the variable
End If
Loop
End


'=== Subroutines ===
Prog_eeprom:
 
 ' здесь-то и был косяк
 '  получееный байт записывался дважды, да и буфер неправильно заливался ))

   If Addresse < 264 Then
   Call Writetobuffer(1 , Addresse , Databyte(lus))
   Else
   Call Buffertopage(1 , Pagge)
   Incr Pagge
   Addresse = 0
   Call Writetobuffer(1 , Addresse , Databyte(lus))
   End If

   Incr Addresse

   Next Lus

   If Pagge > 2047 Then Print "Z"
Return


Process_buffer:
Temps = Mid(instring , 1 , 2) : Bytecount = Hexval(temps)   'Read the numbers of bytes
Temps = Mid(instring , 3 , 2) : Addresshigh = Hexval(temps) 'Read the high adress
Temps = Mid(instring , 5 , 2) : Addresslow = Hexval(temps)  'Read the low adress
Temps = Mid(instring , 7 , 2) : Recordtype = Hexval(temps)  'Read the recordtype
For Lus = 1 To Bytecount                                    'Process the number of data bytes
      Pos = Lus * 2
      Pos = Pos + 7
      Temps = Mid(instring , Pos , 2) : Databyte(lus) = Hexval(temps)       'Read the databytes
Next Lus
Pos = Pos + 2                                               'read the last byte
Temps = Mid(instring , Pos , 2) : Checksm = Hexval(temps)   'Read checksum
Return


Calculate_checksum:
Temp = 0                                                    'Add up all the databytes
Temp = Temp + Bytecount
Temp = Temp + Addresshigh
Temp = Temp + Addresslow
Temp = Temp + Recordtype
   For Lus = 1 To Bytecount
    Temp = Temp + Databyte(lus)
   Next Lus
Checksum_calc = 256 - Temp                                  'taking its two's complement
   If Checksum_calc <> Checksm Then                         'Compare it with the readed value
    Checksum_error = 1
   Else
    Checksum_error = 0
   End If
Return

Bytereceived_isr:
Temp = Udr                                                  'get the binary value that came across
If Temp = &H0D Then                                         'Received CR = end of line, line complete
 If Len(instring) < 8 Then                                  'To short, startover again
   Complete = 0
   Instring = ""
 Else
   Complete = 1                                             'String is complete set the flag
 End If
End If

If Startbyte = &H3A Then                                    'we have previously received the start byte and this is now data
  If Temp > &H0F Then                                       'Add incoming data to buffer
     Instring = Instring + Chr(temp)
    If Len(instring) > 45 Then Instring = ""                'String is to long, reset and startover again
 End If
End If

If Temp = &H3A Then                                         'if we received an : then its the beginning of an new line.
   Startbyte = Temp
   Complete = 0
   Instring = ""
End If
Return

Исходный код AT45.BAS:

Код:
Declare Sub Initspi
Declare Function Writebyte(byval Bb As Byte) As Byte
Declare Function Getdevicedensity(byval Register As Byte) As Byte
Declare Sub At45ready
Declare Sub Sendaddress(byval Page_address As Word , Byval Buffer_address As Word)
Declare Sub Sendcmd(byval Opcode As Byte , Page_address As Word)
Declare Sub Autopagerewrite(byval Buffer As Byte , Byval Page_address As Word)
Declare Sub Pageerase(byval Page_address As Word)
Declare Sub Pagetobuffer(byval Buffer As Byte , Byval Page_address As Word)
Declare Sub Buffertopage(byval Buffer As Byte , Byval Page_address As Word)
Declare Sub Writetobuffer(byval Buffer As Byte , Byval Addr As Word , Byval Dat As Byte)
Declare Function Readfrombuffer(byval Buffer As Byte , Byval Addr As Word) As Byte

Config Timer1 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Pwm = 8

Dim Den As Byte
Dim Page_size As Word
Dim Pages As Word
Dim Pag As Word
Dim Adr As Word

Config Pind.6 = Output
Greenled Alias Portd.6
Greenled = 0

Cs Alias Portb.4

Ddrb = &B10111001
Waitms 1000
Call Initspi
Waitms 100

Den = Getdevicedensity(&H57)
If Den = 1 Then
   Print "128K"
   Page_size = 264
   Pages = 512
Elseif Den = 2 Then
   Print "256K"
   Page_size = 264
   Pages = 1024
Elseif Den = 3 Then
   Print "Memory size=512K"
   Page_size = 264
   Pages = 2048
   Greenled = 1
Elseif Den = 4 Then
   Print "1M"
   Page_size = 264
   Pages = 4096
Elseif Den = 5 Then
   Print "2M"
   Page_size = 528
   Pages = 4096
Elseif Den = 6 Then
   Print "4M"
   Page_size = 528
   Pages = 8192
End If
Waitms 1000

Greenled = 0

Goto Dfend



'******************************************
'Sub: InitSPI
'Purpose: Initailizes the hardware SPI
'Parameters: none
'Returns: nothing
'******************************************

Sub Initspi
Ddrb = Ddrb Or &H07
Portb = Portb Or &H1F
Spcr = &H5C
End Sub


'******************************************
'Function:Writebyte
'Purpose: Writes a byte to spi port
'Parameters: byte to be writen
'Returns: 1 if write sucessful 0 if timeout
'******************************************

Function Writebyte(byval Bb As Byte) As Bit
Local Retry As Byte , Tmp As Byte
Tmp = 1
Spdr = Bb                                                   'Write To Port
Retry = 40                                                  'Change this if you want
While Tmp = 1
  Tmp = Spsr And Spif
  Decr Retry
Wend
If Retry = 0 Then Writebyte = 0 Else Writebyte = 1
End Function


'******************************************
'Function:GetDeviceDensity
'Purpose: Returns the device density
'Parameters: none
'Returns: Device density
'1=128K, 2=256K, 3=512k, 4=1M, 5=2M, 6=4M
'******************************************
Function Getdevicedensity(byval Register As Byte) As Byte
Local Ok As Byte , Density As Byte , Status As Byte
Reset Cs                                                    'CS low select flash
Ok = Writebyte(register)                                    'Read Status Register
If Ok = 1 Then
  Ok = Writebyte(&Hff)                                      'Dummy byte
  Status = Spdr                                             'read the status
End If
Set Cs
Shift Status , Right , 3
Density = Status And &H07
Getdevicedensity = Density                                  'Return Density
End Function

'******************************************
'Sub:AT45Ready
'Purpose: Waits for flash ready (not busy)
'Parameters: none
'Returns: nothing
'******************************************

Sub At45ready
Local Ok As Byte
  Reset Cs
  While Ok = 1                                              'While is not ready
    Ok = Writebyte(&H57)
    Ok = Writebyte(&Hff)
    Ok = Spdr And &H80                                      'Read The Busy Bit
  Wend
End Sub



'******************************************
'Sub:SendAdress
'Purpose: Sends both buffer and page address to the Flash
'Parameters: Page address and buffer nr.
'Returns: nothing
'******************************************


Sub Sendaddress(byval Page_address As Word , Byval Buffer_address As Word)
  Local Upper_page_address As Byte , Lower_page_address As Byte , Ok As Byte , Tmp As Byte
  If Page_size = 264 Then                                   '1 , 2 , 4 Or 8m
    Shift Page_address , Left , 1
  Else                                                      '16M or 32M
    Shift Page_address , Left , 2
  End If
  Upper_page_address = High(page_address)
  Lower_page_address = Low(page_address) Or High(buffer_address)
  Ok = Writebyte(upper_page_address)
  If Ok = 1 Then
    Ok = Writebyte(lower_page_address)
  End If
  If Ok = 1 Then
     Tmp = Low(buffer_address)
     Ok = Writebyte(tmp)
  End If
End Sub


'******************************************
'Sub:SendCmd
'Purpose: Sends a command (opcode) to the Flash
'and also snds address
'Parameters: Command, Page address
'Returns: nothing
'******************************************

Sub Sendcmd(byval Opcode As Byte , Page_address As Word)
  Local Ok As Byte
  Ok = Writebyte(opcode)
  If Ok = 1 Then
    Call Sendaddress(page_address , 0)
  End If
End Sub



Sub Autopagerewrite(byval Buffer As Byte , Byval Page_address As Word)
  Call At45ready
  Reset Cs
  If Buffer = 1 Then
    Call Sendcmd(&H58 , Page_address)                       'buffer 1
  Else
    Call Sendcmd(&H59 , Page_address)                       ' buffer2
  End If
  Set Cs
End Sub


'******************************************
'Sub:PageErase
'Purpose: Erases a page
'Parameters: Page address
'Returns: nothing
'******************************************

Sub Pageerase(byval Page_address As Word)
 Call At45ready
 Reset Cs
 Call Sendcmd(&H81 , Page_address)
 Set Cs
End Sub


'******************************************
'Sub:PageTo buffer
'Purpose: Moves a given page to the buffer
'Parameters: Page address and buffer nr
'Returns: nothing
'******************************************


Sub Pagetobuffer(byval Buffer As Byte , Byval Page_address As Word)
  Call At45ready
  Reset Cs
  If Buffer = 1 Then
    Call Sendcmd(&H53 , Page_address)
  Else
    Call Sendcmd(&H55 , Page_address)
  End If
  Set Cs
  Waitus 250
End Sub

'******************************************
'Sub:Buffer to Page
'Purpose: Moves the buffer (1 or 2) to a page
'Parameters: Page address and buffer nr
'Returns: nothing
'******************************************
Sub Buffertopage(byval Buffer As Byte , Byval Page_address As Word)
 Call At45ready
 Reset Cs
 If Buffer = 1 Then
   Call Sendcmd(&H83 , Page_address)
 Else
   Call Sendcmd(&H86 , Page_address)
 End If
 Set Cs
End Sub

'******************************************
'Sub:WritetoBuffer
'Purpose: Writes a byte to buffer 1 or 2
'Parameters: Page address and buffer nr and data
'Returns: nothing
'******************************************

Sub Writetobuffer(byval Buffer As Byte , Byval Addr As Word , Byval Dat As Byte)
  Local Ok As Byte
  Call At45ready
  Reset Cs
  If Buffer = 1 Then
    Ok = Writebyte(&H84)
  Else
    Ok = Writebyte(&H87)
  End If
   Call Sendaddress(0 , Addr)
   Ok = Writebyte(dat)
   Set Cs
End Sub

'******************************************
'Function:ReadFromBuffer
'Purpose: Reads a byte to buffer 1 or 2
'Parameters: Address and buffer nr
'Returns: The byte read
'******************************************
Function Readfrombuffer(byval Buffer As Byte , Byval Addr As Word) As Byte
 Local Ok As Byte , Dat As Byte
 Call At45ready
 Reset Cs
  If Buffer = 1 Then
    Ok = Writebyte(&H54)
  Else
    Ok = Writebyte(&H56)
  End If
  If Ok = 1 Then
    Call Sendaddress(0 , Addr)
  End If
  If Ok = 1 Then
    Ok = Writebyte($ff)
  End If
    If Ok = 1 Then
      Ok = Writebyte($ff)                                   ' / / Dummy Byte To Get Result From Slave
      Dat = Spdr                                            ' / / Read After Transmit
    End If
   Set Cs
   Readfrombuffer = Dat
End Function

Dfend:

Отредактировано yakuzaa (2008-04-14 15:07:10)

0

3

бррр, а чем мой код не устроил??
Кстати, есть очень даже не плохой преобразователь ср2101 ср2102.
Есть еще очень даже неплохой апнот где таня2313 подключена к усб и выполняет роль порта уарта и еепромки.Советую этот способ также.

0

4

слегка офтоп

Для тех кто еще не видел этой ссылки и кто юзает параллельный порт и хочет поиграться с at45
http://www.amwaw.edu.pl/~adybkows/elka/ispprog_en.html

Отредактировано pomidor (2008-03-31 10:56:07)

0

5

Ведущийспециалист написал(а):

бррр, а чем мой код не устроил??
Кстати, есть очень даже не плохой преобразователь ср2101 ср2102.
Есть еще очень даже неплохой апнот где таня2313 подключена к усб и выполняет роль порта уарта и еепромки.Советую этот способ также.

Привет! Твой код как раз и заработал у меня - т.е. чтение страницы 264-байтной страницы из микрухи и передача его в шим проходит нормально! отчасти, я думаю, потому, что большинство процедур написано на ассемблере

вот только с записью данных в микруху по событию в UART я пока еще не разобрался )) а именно в примере с записью страницы во флеш:

Код:
'A = Red
'Call Buffer1_write
'For Temp1 = 1 To 132
'Call Wordout()
'Next Temp1
'Set Select_memory
'Call Buffer1_to_flash(1)

как я понимаю, здесь идет запись переменной A 132 раза, которая состоит из двух байт (а значит это уже word), а значит записывается 264 байта

вопрос: как тогда организовать запись однобайтового числа? заменить процедуру wordout() на byteout() ? и увеличить цикл до 264?
например, вот так почему-то не заработало...:

Код:
Dim a as byte
N = 100
Call Buffer1_write
For Temp1 = 1 To 264
Call Byteout()
Next Temp1
Set Select_memory
Call Buffer1_to_flash(1)

Отредактировано yakuzaa (2008-04-07 11:02:40)

0

6

Странно, вообще то все верно, должно работать

0

7

yakuzaa

Прпивет.

А можете дать код как вы считываете WAV с AT45DB ?
ни как не могу разобратся (треск в динамике и все) вроде бы пишется норомально на AT45DB (читал программатором) а вот считать ни как)

Мне кстатии удалось домучать AT25-ю сериию теперь могу и читать и писать туда (AT25Q128 все таки как не как 16мб это уже что-то) если интересно могу выложить код и схемы которые 100% роботают (бо там какой то полтергейст визде написано что ножку CS можно назначать на любой свободный пин но работает только на PortB.1 (это для Атмеги 8 , 88 , 168 , 328))

0

8

Sonic Blast написал(а):

Мне кстатии удалось домучать AT25-ю сериию

Я работаю с 25 серией только в плане чтения.
А с записью пока не пробовал.
Так что тема актуальна, сбрасывайте.

0

9

Код:
'$regfile = "m328pdef.dat"
'$regfile = "ATMEGA32A.dat"
$regfile = "m8adef.dat"
$crystal = 22118400
'$crystal = 14745600
'$crystal = 8000000                                          '8MHz internal RC clock
$hwstack = 128
$swstack = 128
$framesize = 128
$baud = 115200

Const False = 0
Const True = 1

RED ALIAS Portc.1
Config RED = Output
GREEN ALIAS PORTC.2
Config GREEN = Output

Speaker Alias PORTC.0

Config Lcd = 20 * 4
Config Lcdpin = Pin , Rs = PortD.7 , E = PortD.6 , Db4 = PortD.5 , Db5 = PortD.4 , Db6 = PortD.3 , Db7 = PortD.2 ' ,WR = PORTE.3

DIM L AS WORD , S AS WORD

Chip Alias PortB.0
Config PortB.0 = Output
Set Chip
'<<< ИСПОЛЬЗОВАНИЕ M25P16-VMW6TG >>>>


'M25P16 представляет собой последовательную флэш-память 16 Мбайт (2 Мбайт x 8).
'Память может быть запрограммирована от 1 до 256 байтов за раз, используя ПРОГРАММУ СТРАНИЦЫ
'команда. Он состоит из 32 секторов, каждый по 256 страниц. Каждая страница - 256
'шириной в байтах. Память может отображаться как 8 192 страницы или 2 097 152 байта. Целиком
'Память можно стереть, используя команду BULK ERASE, или ее можно стереть одним
'сектор за раз, используя команду SECTOR ERASE.

'Сектор = 256 страниц * 256 байт = 65536 -> & H00000000 ....... & H0000FFFF

'Карта памяти
'Адрес сектора         Начальный адрес         Конец
 '   31           &H001F0000          &H001FFFFF
 '   30           &H001E0000          &H001EFFFF
 '  ...           .........           ..........
 '  ...           .........           ..........
 '   1            &H00010000          &H0001FFFF
 '   0            &H00000000          &H0000FFFF


'The Winbond W25Q16DV 16Mbit chip (also) organized WORD,
'So the CS rate is to be treated separately, as the HW-solving and bytes

' datasheet
'http://www.elinux.org/images/f/f5/Winbond-w25q32.pdf
'25q   mcu
'/CS : Chip
'DO  : MISO
'DI  : MOSI
'Clk : Sck
'wp & hold pullup+3,3v
Declare Sub SIRENE(byVal VV AS WORD)
'CS pin
  Const Write_enable = &H06       'The WRITE ENABLE command sets the write enable latch (WEL) bit.
  Const Write_disable = &H04       'The WRITE DISABLE command resets the write enable latch (WEL) bit.
  Const Read_identification = &H9F
  Const Read_status_register = &H05
  Const Write_status_register = &H01
  Const Read_data_bytes = &H03
  Const Read_data_bytes_higher_speed = &H0B
  Const Page_program = &H02
  Const Sector_erase = &HD8
  Const Bulk_erase = &HC7
  Const Deep_power_down = &HB9
  Const Release_from_deep_power_down = &HAB
  Const Wel = 1       'write enable latch bit
  Const Wip = 0       'write in progress bit
  Const Srwd = 7       'satus register write protect

  Dim Df_status As Byte
  Dim I As Word
  Dim Df_24_bit_address As Long
  Dim Df_array(256) As Byte
  Dim Df_page_number As Word

DECLARE Function Df_read_status() As Byte
DECLARE Sub Df_read_id()
DECLARE Sub Df_deep_powerdown_mode()
DECLARE Sub Df_release_from_powerdown()
DECLARE Sub Df_page_write(page_number As Word)
DECLARE SUB Df_page_read(page_number As Word)
DECLARE Sub Df_sector_erase(page_number As Word)

Declare Sub Jedec_id()
Declare Sub Device_id()
Declare Sub Parameter_page()
Declare Sub Read_data()
Declare Sub Write_data()
Declare Sub Clear_mem()
Declare Sub Clear_pp()
Declare Sub Write_dis()
Declare Sub Write_en()
Declare Sub Stbit()

Declare Sub At25_busywait()
Declare Sub At25_fullerase()
Declare Sub At25_readstatus()
Declare Sub At25_write_enable()
'Declare

Dim Sent_data(8) As Byte
Dim Sent_p(8) As Byte
Dim read_data_tmp(8) As Byte
Dim my_data(8) As Byte
Dim Data_in(4) As Byte                                      ' the array of input data
Dim Data_out(8) As Byte                                     ' the array of 'output data
Dim Mem_p As Byte
Dim St_bit As Bit
Dim Dummy As Byte
Dim Datas As Word
Dim Data_l As Byte At Datas Overlay
Dim Data_h As Byte At Datas + 1 Overlay
Dim Address As Long , Addr As Dword
Dim Addr_l As Byte At Address Overlay
Dim Addr_m As Byte At Address + 1 Overlay
Dim Addr_u As Byte At Address + 2 Overlay
Dim Addr_x As Byte At Address + 3 Overlay

Dim Buffer_command(4) As Byte                                    ' Command buffer
Dim At25_sreg As Byte                                            ' AT25 Dataflash Status Register
    At25_busy Alias At25_sreg.0                                  ' AT25 Busy Flag
    At25_wel Alias At25_sreg.1                                   ' AT25 Write Enable Latch Status Flag
    At25_error Alias At25_sreg.5                                 ' AT25 Erase/Program Error Flag


Dim A As Word
Dim SECT AS WORD
Dim FLASH AS STRING * 9
DIM TI AS WORD , NN AS WORD

'SPI config
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 , Spiin = 0
'Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1 ', Spiin = 0
'   Spsr.0 = 1
   Spsr = 1
Spiinit

Enable Interrupts

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1
'Config Timer1 = Pwm , Compare A Pwm = Clear Up , Prescale = 1
Config PortB.1 = Output
Config PINC.5 = INPUT
SET PORTC.5
Print

Print "Start!"

DO
'Addr_x = 0
'Df_page_number = 1
Cursor Off , NOBLINK
CLS
LOCATE 1 , 1: LCD "-=[AT25xxxxx TEST]=-"
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
FOR L = 1 TO 2
FOR S = 1 TO 20
LOCATE 2 , S: LCD CHR(255)
LOCATE 3 , S: LCD CHR(255)
LOCATE 4 , S: LCD CHR(255)
Toggle GREEN
WAITMS 50
LOCATE 2 , S: LCD " "
LOCATE 3 , S: LCD " "
LOCATE 4 , S: LCD " "
'WAITMS 50
NEXT S
FOR S = 20 TO 1 STEP -1
LOCATE 2 , S: LCD CHR(255)
LOCATE 3 , S: LCD CHR(255)
LOCATE 4 , S: LCD CHR(255)
Toggle RED
WAITMS 50
LOCATE 2 , S: LCD " "
LOCATE 3 , S: LCD " "
LOCATE 4 , S: LCD " "
'WAITMS 50
NEXT S
NEXT L

CLS
'  W25Q16 (2097151 bytes)  = 16 Mbit
'(
       LOCATE 1,1:LCD "ERASE ALL CHIP"
       Df_page_number = 0
       Call Df_sector_erase(df_page_number)

')
       Df_page_number = 0
       L = 2: S = 1
       Call Df_read_id()
       Print "Df_read_id = " ;
       LOCATE 1,1:LCD "Read chip id"
       For I = 1 To 6
'          Toggle YELL
          Toggle GREEN
          Toggle RED
          Print Hex(df_array(i)) ; " / " ;
          LOCATE L, S: LCD Hex(df_array(i)) ; "/" '; Hex(df_array(i + 1))
          S = S + 3
'          IF S > 20 THEN
'          L = L + 1
'          IF L > 4 THEN L = 4
'          END IF
       Next I
Sound Speaker , 75 , 154
Sound Speaker , 194 , 266

'(
       For I = 1 To 256
          Df_array(I) = I
       Next I

')
WAIT 6
Cursor Off , NOBLINK
CLS
Call Jedec_id()
Print "Read chip id": LOCATE 1,1:LCD "Chip Id: "  ;Hex(read_data_tmp(1)) ; "/" ; Hex(read_data_tmp(2)) ;  "/" ;Hex(read_data_tmp(3))
Sound Speaker , 75 , 154
Sound Speaker , 194 , 266
Print Hex(read_data_tmp(1)) ;  "/" ;Hex(read_data_tmp(2)) ;  "/" ;Hex(read_data_tmp(3))
locate 3 , 1:lcd "Memory Type: " ; SECT
Print
Print "Read Manufacturer Device Id "': LOCATE 2,1:LCD "Read Manufact id"
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
Call Device_id()
locate 2,1: lcd "Device ID: " ; Hex(read_data_tmp(4)) ;  "/" ;Hex(read_data_tmp(5)) ;  "/" ;Hex(read_data_tmp(6))
Print Hex(read_data_tmp(4)) ;  "/" ;Hex(read_data_tmp(5)) ;  "/" ;Hex(read_data_tmp(6))
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
IF PINC.5 = 0 THEN GOTO PRG
'PRINT "'GO TO PROGRAMM MODE!"
'GOTO PRG
'      Call Df_release_from_powerdown()
      locate 4 , 1:lcd "Play from " ; FLASH
      RED = 1
      FOR Addr = 0 TO SECT '32767      ' 8388608
'      locate 4 , 7:LCD addr
      Call Df_page_read(Addr)       '********** PROGRAM READ **************************
'      Toggle RED
      For I = 1 To 256       'Data_len
'      B = Df_array(I) '= B
'      C = BIN(B)
      Pwm1A = Df_array(I)
'      Waitus 78      ' 11250hz
      Waitus 52      ' 16000hz
'      Print CHR(B) ;
      Next I
'      INCR df_page_number
      NEXT Addr
'      Print ""
'      Waitms 1000
      RED = 0
CALL SIRENE(2)

'Cursor Off , NOBLINK
'CLS
'call Clear_mem()
'(
'test for mem write data 256 bytes write
A = 0
cls
Print "Write 255 bytes "
LOCATE 1,1:LCD "Write 255 bytes "
For Address = 0 To &H1FFF Step 2
   Incr A
   Data_h = Addr_m
   Data_l = Addr_l
   Call Write_data()
   Print Hex(address) ; "h: " ; Hex(data_h) ; Hex(data_l)
   LOCATE 2,1:LCD Hex(address) ; "h: " ; Hex(data_h) ; Hex(data_l)
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
Next
Print "Writeing DONE "
LOCATE 3,1:LCD "Writeing DONE!!!"
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
Wait 5
CLS

Print "Data dump: "
LOCATE 1,1:LCD "Data dump:"
   Sound Speaker , 75 , 154
   Sound Speaker , 194 , 266
wait 1
For Address = 0 To &H7FFF Step 2                    '         8388608
   Toggle RED
   Call Read_data()
   Print Hex(address) ; "h: " ; Hex(my_data(1)) ; Hex(my_data(2))
'   LOCATE 1,11:LCD Hex(address) ; " "
'   LOCATE 2 , 1:LCD "High: "; Hex(my_data(1))' ; " / Low: " ; Hex(my_data(2))
'   my_data(1) = High(A)
'   my_data(2) = Low(A)

'   C = CHR(my_data(1))
'   HIGH(C) = C
'   C = CHR(my_data(2))
'   Low(C) = C
      For I = 1 To 256       'Data_len

   Pwm1A = my_data(I)
      Next I
'   C =  CHR(my_data(2))
'   Pwm1A = my_data(2)
'   Sound Speaker , 75 , 154
'   Sound Speaker , 194 , 266
Next
Print "Reading DONE "
LOCATE 3,1:LCD "Reading DONE "
')
CALL SIRENE(2)
LOOP
PRG:
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Watchdog = 1024
Open "COM1:" For Binary As #1

Dim Flashbuffer(256) As Byte
Dim Shakedhands As Boolean
Dim Sector As Byte , Page As Word ', Address As Dword
Cursor Off , NOBLINK
CLS
LOCATE 1 , 1 : LCD "PROGRAMM MODE!"
LOCATE 2 , 1 : LCD "SECTOR:"
LOCATE 3 , 1 : LCD "PAGE:"
LOCATE 4 , 1 : LCD "ADDR:"
Do
   ' ждать команды
   Inputbin #1 , Sector
   Select Case Sector

   ' Рукопожатие / Выход
   Case &HAA:
      Shakedhands = Not Shakedhands                                             ' какая-то защита от случайной записи
      Printbin #1 , &HF0                                                        ' ack

   ' стереть сектор (адресные биты 23..16)
   Case &H01:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Sector                                                      ' читать адрес сектора
      Stop Watchdog
      If Shakedhands = True Then
      CALL Df_sector_erase(Sector)
      END IF
      Printbin #1 , &HF0                                                        ' ack

   ' стереть всю память
   Case &H02:
      If Shakedhands = True Then  'Flash_bulk_erase
'      CALL Clear_mem()
      LOCATE 2 , 1 : LCD "BULK ERASE!"
      CALL Clear_mem()
      END IF
'(
      FOR A = 0 TO SECT
      LOCATE 2 , 8 : LCD A
      CALL Df_sector_erase(A)
      Toggle RED
      Toggle GREEN
      NEXT A
      END IF

      Printbin #1 , &HF0                                                        ' ack
      LOCATE 2 , 1 : LCD "SECTOR:    "
')
   ' записать страницу (256 байт, адресные биты 23..8)
   Case &H03:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Page                                                        ' прочитать адрес страницы
      Inputbin #1 , Flashbuffer(1) , 256                                        ' читать данные страницы размером 256 байт
      Stop Watchdog
      Swap Page
      If Shakedhands = True Then 'Flash_write_page Page , Flashbuffer(1)
      For I = 1 To 256
       Df_array(I) = Flashbuffer(I)
      Next I
      Call Df_page_write(Page)       '********** PROGRAM WRITE **************************
      END IF
'      LOCATE 2 , 10 : LCD Sector
      LOCATE 3 , 8 : LCD PAGE
      Toggle GREEN
      Printbin #1 , &HF0                                                        ' ack

   ' прочитать страницу (256 байт, адресные биты 23..8)
   Case &H04:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Page                                                        ' прочитать адрес страницы
      Stop Watchdog
      Swap Page
      Address = Page
      Shift Address , Left , 8
      If Shakedhands = True Then 'Flash_read Address , Flashbuffer(1) , 256
      Call Df_page_read(Page)       '********** PROGRAM READ **************************
      For I = 1 To 256       'Data_len
        Df_array(I) = Flashbuffer(I)
      Next
      END IF
'      LOCATE 2 , 10 : LCD Sector
      LOCATE 4 , 8 : LCD Address
      Toggle RED
      Printbin #1 , Flashbuffer(1) ; 256                                        ' записать данные страницы

   ' прочитать данные идентификатора устройства (81 байт)
   Case &H05:
      If Shakedhands = True Then
      Call Df_read_id()'Flash_get_info Flashbuffer(1)
'      Call Jedec_id()
      RED = 1
      GREEN = 1
       For I = 1 To 21
'          df_array(i) = Hex(df_array(i))
          df_array(i) = Flashbuffer(1)
'         read_data_tmp(I)  = Flashbuffer(I)
       Next I
      END IF
      Printbin #1 , Flashbuffer(1) ; 81
      CALL SIRENE(2)
      RED = 0
      GREEN = 0

   End Select
Loop

'DF_READ_STATUS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Function Df_read_status() As Byte
  Local Tempvar As Byte
  Tempvar = Read_status_register       'READ STATUS REGISTER
  Disable Interrupts
  Reset Chip       'Chip Select
  Spiout Tempvar , 1       'Read Status Register
  Spiin Df_read_status , 1
  Set Chip       'Deselect Chip
  Enable Interrupts
End Function

'DF_READ_ID <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_read_id()
  Local Tempvar As Byte
  Tempvar = Read_identification       'READ IDENTIFICATION
  Disable Interrupts
  Reset Chip       'Chip Select
  Spiout Tempvar , 1
  Spiin Df_array(1) , 21       'Read 3 Byte
  Set Chip       'Deselect Chip
  Enable Interrupts
End Sub

'DF_DEEP_POWERDOWN <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_deep_powerdown_mode()
  Local Tempvar As Byte
  Tempvar = Deep_power_down
  Disable Interrupts
  Reset Chip
  Spiout Tempvar , 1       ' Deep_power_down
  Set Chip
  Enable Interrupts
  Waitus 4
End Sub

'DF_RELEASE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_release_from_powerdown()
  Local Tempvar As Byte
  Tempvar = Release_from_deep_power_down
  Disable Interrupts
  Reset Chip
  Spiout Tempvar , 1       ' Release_from_deep_power_down
  Set Chip
  Enable Interrupts
  Waitus 30
End Sub

'PAGE WRITE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_page_write(page_number As Word)
  Local Tempvar As Byte , I As Word , Templong As Long
  Local 24_bit_address_1 As Byte , 24_bit_address_2 As Byte , 24_bit_address_3 As Byte , Y As Word

  Templong = Page_number * 256
      '24-Bit Address
  I = Templong
  Y = Highw(templong)
  24_bit_address_1 = Low(i)       'Bit 7  ......Bit 0
  24_bit_address_2 = High(i)       'Bit 15 ......Bit 8
  24_bit_address_3 = Low(y)       'Bit 23 ..... Bit 16

  Disable Interrupts

  Tempvar = Write_enable
  Reset Chip
  Spiout Tempvar , 1       ' WRITE ENABLE
  Set Chip

  Do
    Tempvar = Df_read_status()
  Loop Until Tempvar.1 = 1       'Wait until The write enable latch (WEL) is set
  Tempvar = Page_program
  Reset Chip
  Spiout Tempvar , 1       ' PAGE PROGRAM

      '24-Bit address
  Spiout 24_bit_address_3 , 1       'Bit 23 ..... Bit 16
  Spiout 24_bit_address_2 , 1       'Bit 15 ......Bit 8
  Spiout 24_bit_address_1 , 1       'Bit 7  ......Bit 0

  For I = 1 To 256
    Spiout Df_array(i) , 1       'Send 256 Byte
  Next I

  Set Chip       'Deselect Chip

  Do
    Tempvar = Df_read_status()
  Loop Until Tempvar.0 = 0       'Wait until WIP is Reset

  Enable Interrupts
End Sub

'PAGE READ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_page_read(page_number As Word)
  Local Tempvar As Byte , I As Word , Templong As Long
  Local 24_bit_address_1 As Byte , 24_bit_address_2 As Byte , 24_bit_address_3 As Byte , Y As Word

  Templong = Page_number * 256
      '24-Bit Address
  I = Templong
  Y = Highw(templong)
  24_bit_address_1 = Low(i)       'Bit 7  ......Bit 0
  24_bit_address_2 = High(i)       'Bit 15 ......Bit 8
  24_bit_address_3 = Low(y)       'Bit 23 ..... Bit 16

  Disable Interrupts
  Tempvar = &H0B       ' FAST Read Data Bytes
  Reset Chip
  Spiout Tempvar , 1

      '24-Bit address

  Spiout 24_bit_address_3 , 1       'Bit 23 ..... Bit 16
  Spiout 24_bit_address_2 , 1       'Bit 15 ......Bit 8
  Spiout 24_bit_address_1 , 1       'Bit 7  ......Bit 0

  Spiin Tempvar , 1       'DUMMY READ

  For I = 1 To 256
    Spiin Df_array(i) , 1
  Next I

  Set Chip       'Deselect Chip

  Enable Interrupts
End Sub

'DF_SECTOR ERASE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Sub Df_sector_erase(page_number As Word)       'The SECTOR ERASE command sets to 1 (FFh) all bits inside the chosen sector.
  Local Tempvar As Byte , I As Word , Templong As Long
  Local 24_bit_address_1 As Byte , 24_bit_address_2 As Byte , 24_bit_address_3 As Byte , Y As Word

  Templong = Page_number * 256
      '24-Bit Address
  I = Templong       'First two byte
  Y = Highw(templong)       'last byte
  24_bit_address_1 = Low(i)       'Bit 7  ......Bit 0
  24_bit_address_2 = High(i)       'Bit 15 ......Bit 8
  24_bit_address_3 = Low(y)       'Bit 23 ..... Bit 16

  Disable Interrupts

  Tempvar = Write_enable
  Reset Chip
  Spiout Tempvar , 1       ' WRITE ENABLE
  Set Chip

  Do
    Tempvar = Df_read_status()
  Loop Until Tempvar.wel = 1       'Wait until The write enable latch (WEL) is set

  Tempvar = Sector_erase
  Reset Chip
  Spiout Tempvar , 1       ' SECTOR ERASE

      '24-Bit address
      'Any address inside the sector is a valid address for the SECTOR ERASE command

  Spiout 24_bit_address_3 , 1       'Bit 23 ..... Bit 16
  Spiout 24_bit_address_2 , 1       'Bit 15 ......Bit 8
  Spiout 24_bit_address_1 , 1       'Bit 7  ......Bit 0
  Set Chip       'Deselect Chip

      'The WIP bit is 1 during the self-timed SECTOR ERASE
  Do
    Tempvar = Df_read_status()
  Loop Until Tempvar.0 = 0       'Wait until WIP is Reset

  Enable Interrupts
End Sub
' Manufacturing and Memory code reading
Sub Jedec_id()
   Mem_p = &H9F
   Reset Chip
   Spiout Mem_p , 1
   Spiin Read_data_tmp(1) , 3
   Set Chip
'   Call Df_read_id()
   'Call Stbit()
'   Print "ID : " ; Hex(read_data_tmp(3)) ;    ' see 6.6.1
   If read_data_tmp(3) = &H12 Then
   FLASH = "W25Q04" : SECT = 2047
   ELSEIf read_data_tmp(3) = &H13 Then
   FLASH = "W25Q08" : SECT = 4095
   ELSEIf read_data_tmp(3) = &H14 Then
   FLASH = "W25Q08" : SECT = 4095
   ELSEIf read_data_tmp(3) = &H15 Then
   FLASH = "W25Q16" : SECT = 8191
   ELSEIf read_data_tmp(3) = &H16 Then
   FLASH = "W25Q32" : SECT = 16383
   ELSEIf read_data_tmp(3) = &H17 Then
   FLASH = "W25Q64" : SECT = 32767
   ELSEIf read_data_tmp(2) = &H20 Then
   FLASH = "W25Q128" : SECT = 65535
   ELSE
   SECT = 2047
   FLASH = "UNKNOW"
   END IF
End Sub

Sub Device_id()
   Mem_p = &H90
   Reset Chip
   Spiout Mem_p , 1
   Spiin read_data_tmp(1) , 6
   Set Chip
   Call Stbit()
End Sub


' PARAMETER PAGE
Sub Parameter_page()
   Address = 0                                                 'Long type variable!
   Sent_p(1) = &H53                                           'read parameter page
   Sent_p(2) = &H00                                         'address 3 byte
   Sent_p(3) = &H00                                           '000000
   Sent_p(4) = &H00
   Reset Chip
   Spiout Sent_p(1) , 4
   Spiin read_data_tmp(1) , 3
   Set Chip
   Addr_u = read_data_tmp(1)
   Addr_m = read_data_tmp(2)
   Addr_l = read_data_tmp(3)
   Print "CHIP ID: " ; Read_data_tmp(1) ; Read_data_tmp(2) ; Read_data_tmp(3)

   ' address Checking

   'Parameter page deleted?
   If Address = &HFFFFFF Then                               '16777215
      Address = 0
      Print "Flash: empty "
      Wait 2
      Goto Zero
   End If
   'The memory is full? (Address = FFFFFF)
   If Address = &HFFFFFF Then                               '16777215
      Print "Flash: full "
   End If
   Address = Address + 2
   Zero:
      Call Clear_pp()
      Sent_data(1) = &H52                                   'parameter page write
      Sent_data(2) = &H00                                   'dummy
      Sent_data(3) = &H00                                   'dummy
      Sent_data(4) = &H00                                   'address
      Sent_data(5) = Addr_u                                 'data1
      Sent_data(6) = Addr_m                                 'data2
      Sent_data(7) = Addr_l                                 'data3
      Sent_data(8) = &H00                                   'data4 -> empty because of a couple of bytes to be!
      Call Write_en()
      Reset Chip
      Spiout Sent_data(1) , 8
      Set Chip
      Call Stbit()
      Cls
End Sub
' RAM read
Sub Read_data()
   my_data(1) = 0
   my_data(2) = 0
   Mem_p = &H03
   Sent_data(1) = Mem_p
   Sent_data(2) = Addr_u
   Sent_data(3) = Addr_m
   Sent_data(4) = Addr_l
   Reset Chip
   Spiout Sent_data(1) , 4
   Spiin my_data(1) , 2
   Set Chip
   Call Stbit()
End Sub
' RAM write
Sub Write_data()
   Mem_p = &H02
   my_data(1) = Mem_p
   my_data(2) = Addr_u
   my_data(3) = Addr_m
   my_data(4) = Addr_l
   my_data(5) = Data_h
   my_data(6) = Data_l
   Call Write_en()
   Reset Chip
   Spiout My_data(1) , 6
   Set Chip
   Call Write_dis()
   Call Stbit()
End Sub
' Clear RAM
Sub Clear_mem()                                             ' clear flash ram
   Call Write_en()
   Mem_p = &HC7
   Reset Chip
   Spiout Mem_p , 1
   Set Chip
   Call Stbit()
End Sub
' Clear PARAMETER PAGE
Sub Clear_pp()                                              ' clear parameter page
   Call Write_en()
   Mem_p = &HD5
   Reset Chip
   Spiout Mem_p , 1
   Set Chip
   Call Stbit()
End Sub
' WRITE Disable - Enable
Sub Write_dis()                                             ' write disable
   Mem_p = &H04
   Reset Chip
   Spiout Mem_p , 1
   Set Chip
End Sub
Sub Write_en()                                              ' write enable
   Mem_p = &H06
   Reset Chip
   Spiout Mem_p , 1
   Set Chip
End Sub
' STATUS bit
' It will only be over when the memory of the transactions are finished!
Sub Stbit()
   St_bit = 0
   Kezd:
      Mem_p = &H05
      Reset Chip
      Spiout Mem_p , 1
      Spiin Dummy , 1
      Set Chip
      St_bit = Dummy.0
      If St_bit = 0 Then Exit Sub
      Goto Kezd
'      St_bit = 0
End Sub

Sub At25_busywait()                                              ' Wait until the AT25 comes out of busy state
   Do                                                            ' -------------------------------------------
      ' Read the AT25 status register every 100ms until it is no longer busy.
      Call At25_readstatus
      If At25_busy = 0 Then Exit Do
      Waitms 100
   Loop
End Sub


Sub At25_fullerase()                                             ' Perform a full chip erase on the AT25
   Buffer_command(1) = &H60                                      ' -------------------------------------

   ' Enable writing to the AT25
   Call At25_write_enable

   ' Start the SPI transaction, send the Erase Chip opcode, then end the SPI transaction.
   Reset Chip
   Spiout Buffer_command(1) , 1
   Set Chip

   ' Wait until the AT25 is done erasing itself.
   Call At25_busywait

   ' Check is there was an error, and report it.
'   If At25_error = 1 Then
'      Call At25_reporterror
'   End If
End Sub


Sub At25_readstatus()                                            ' Read the AT25 Dataflash Status Register
   Buffer_command(1) = &H05                                      ' ---------------------------------------

   ' Start the SPI transaction, send the Read Status Register opcode, read back the register, then end the SPI transaction.
   Reset Chip
   Spiout Buffer_command(1) , 1
   Spiin At25_sreg , 1
   Set Chip
End Sub


Sub At25_write_enable()                                          ' Enable writing to the AT25
   Buffer_command(1) = &H06                                      ' --------------------------

   ' Start the SPI transaction, send the Write Enable opcode, then end the SPI transaction.
   Reset Chip
   Spiout Buffer_command(1) , 1
   Set Chip

   ' Check if the Write Enable Latch is set, if not report an error.
'   If At25_wel = 0 Then
'      Call At25_reporterror
'   End If
End Sub

Sub SIRENE(VV AS WORD)
    For TI = 1 To VV
       For NN = 500 To 900 STEP 5
         Sound Speaker , 5 , NN
       Next NN
       For NN = 900 To 500 Step -5
         Sound Speaker , 5 , NN
       Next NN
    Next TI
End Sub

Вот мой 100% рабочий код для Атмеги8 (48-328)

Клиент для заливки с винды можно скачать здесь http://mat.midlight.eu/wiki/index.php?t … sh_Library  (с этой библиотекой мне так и не удалось вывести звук , хотя сам код работает (пишет и читает но блоками по 256байт)

Отредактировано Sonic Blast (2021-09-22 01:15:20)

+1

10

Ребята только что заметил что в коде что я выложил сверху в цикле For I = 1 To 256 надо For I = 0 To 255 , так как скопировал не последний код над которым я работал (прошу прощения) после правки должно все работать. Да и ещё я разобрался с кодом который по ссылке (читает звук из флешки и намного качественней чем тот что выше код.)

Дык кто-то выложит код чтения звука для AT45DB ?

0

11

Код для воспроизведения WAV файла из флеш 25-й сории для библиотеки (в позапрошлом посте)

FOR Address = &H0 TO &HFFFFFF
      Flash_beginread Address ' , Flashbuffer(1) , 256
      FOR S = 1 TO 256
      Flashbuffer(S) = Flash_readbyte()
      D = Flashbuffer(S)
      Pwm1A = D
      Waitus 45 ' подбирается в зависимости от установленного кварца 45 нс для 8мгц
      NEXT S
NEXT Address
Flash_endread

Отредактировано Sonic Blast (2021-10-01 11:48:46)

0

12

M25P16-VMW6TG >>>>
'M25P16 представляет собой последовательную флэш-память 16 Мбайт (2 Мбайт x 8)

Не мегабайт, а 16 мегабит

0

13

Александр Д. написал(а):

M25P16-VMW6TG >>>>
'M25P16 представляет собой последовательную флэш-память 16 Мбайт (2 Мбайт x 8)

Не мегабайт, а 16 мегабит

У меня отлично работает и 128мегабитной флешкой (16мбайт) и с 64мбитной (8мб)

0

14

Блин неужели ни кто не имел дела с AT45DB флешкой помогите найти (исправить мой) код для чтения (записи) с неё чего либо вот как я пробую читать с флеш данные (использую код тот что тут взял AT45.BAS , но пробовал и другие (выложу тут что мне удалось найти))

FOR Pagge = 0 TO 8191
'   LOCATE 3 , 7 : LCD Pagge
   Call Pagetobuffer(1 , Pagge)
   FDATA(1) = Readfrombuffer (1 , 528)
      FOR NN = 0 TO 528
            D = FDATA(NN)
         Pwm1A = D
         'OCR1A = D
         Waitus 54
'         Incr Addresse
'         IF Addresse > 528 THEN Addresse = 0
   IF A3 = 0 THEN
         GREEN=1:RED=1:GOSUB TAD:WAIT 1:GREEN=0:RED=0
         GOTO AT45DB
   END IF
      NEXT NN
NEXT Pagge

может я что-то не так делаю ведь описание работы SUB в AT45.BAS очень скупая... Пробовал игратся ставить в цыкл побайтовое считывание с массива , выносил за цыкл итд...
Флешки ТОЧНО рабочие и пробовал разные (идентификатор с микросхемы читает правильно значит подключено к процу правильно) пробовал записывать данные на программаторе так как с тем переделаным с I2С программатора слишком долго пишится (вроди как)

Отредактировано Sonic Blast (2021-11-10 22:15:26)

0

15

Sonic Blast написал(а):

неужели ни кто не имел дела

А что иметь, возьмите даташит и сделайте функцию чтения. Даташит хорошо документирован, иллюстрирован.

0

16

Yuriy.pv написал(а):

А что иметь, возьмите даташит и сделайте функцию чтения. Даташит хорошо документирован, иллюстрирован.

А для чего изобретать заново велосипед если людьми уже давно написано , разобрался уже сам сам .

Буду по тихоньку вылажывать тут библиотеки (есть толковые с реалтзацией фат)

Вот код для DATAFLESH AT45DB321D у меня работает как с AT45DB041D(B) ,  AT45DB081D(B) , AT45DB161E(D,B) ,  AT45DB321D (есть ещё AT45DB011B с ней не пробовал но думаю будет работать)

Код:
$regfile = "m328pdef.dat"
$crystal = 22118400
$hwstack = 100
$swstack = 100
$framesize = 250
$baud = 115200
'*******************************************************************************
A0 ALIAS PIND.2
A1 ALIAS PIND.3
A2 ALIAS PIND.4
A3 ALIAS PIND.5
Config PORTD.2 = INPUT
Config PORTD.3 = INPUT
Config PORTD.4 = INPUT
Config PORTD.5 = INPUT
A0 = 1 : A1 = 1 : A2 = 1 : A3 = 1

GREEN Alias PortC.2
RED Alias PortC.3
Config GREEN = Output
Config RED = Output
Speaker Alias PortD.6
'*******************************************************************************
$lib "lcd_i2c_pcf8574.lib"
'$lib "YwRobot_Lcd_i2c.lib"
$lib "Lcd_i2c_v3.lib"
Dim _out_rw As Byte
Dim _out_e2 As Byte
Dim _lcd_e As Byte
Dim _backlight As Byte
Dim Lcd_backlight As Byte
Config Scl = PortC.5
Config Sda = PortC.4
Config I2cdelay = 1
Const Pcf8574_lcd = &H4E ' PCF8574 address
Const Pcf_e2_is_output = 1
Const Pcf_rw_is_output = 1
Const Pcf_rs = 0
Const Pcf_rw = 1
Const Pcf_e1 = 2 '2
Const Pcf_e2 = 3 '3
Const Pcf_d4 = 4
Const Pcf_d5 = 5
Const Pcf_d6 = 6
Const Pcf_d7 = 7
Const PCF_BL = 1
_lcd_e = 192 ' 64=E2 (3 & 4 stering) 128=E1 (1 & 2 string) 192=E1+E2 (all 4 strings)
_out_rw = 1
_out_e2 = 1
_backlight = 0
Lcd_backlight = 1
'*******************************************************************************
Select_memory Alias Portb.2
Set Select_memory
'***************
Const Buff1_write = &H84
Const Buff2_write = &H87
Const Buff1_mem_write = &H83
Const Buff2_mem_write = &H86
Const Current_page_read = &HD2
Const Current_page_write = &H82
Const Deep_power_down = &HB9
Const Resume_deep_power_down = &HAB

Dim Buf(528) As Byte
Dim Page_mem As Word
Dim A As Word
Dim Temp As Byte
Dim N As Byte , Temp1 As Word
Declare Sub Db45down
Declare Sub Db45up
Declare Sub Wordout()
Declare Sub Byteout()
Declare Sub Bytein()
Declare Sub Page_read(byval Page_mem As Word)
Declare Sub Page_write(byval Page_mem As Word)
Declare Sub Buffer1_to_flash(byval Page_mem As Word)
Declare Sub Buffer1_write
Config Spi = Hard , Interrupt = OFF , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1

Dim Spi_read(256) As Byte
Dim Spi_write(256) As Byte
dim i as word
dim flash_addr1 as long

Dim Cim(5) As Byte
Dim AB(4) As Byte
Dim Pagge As Word , Addresse As Word

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Prescale = 1
Config PORTB.1 = Output
'**********************************************************************
Spiinit
Toggle _out_rw
MAIN:
Do
' YOUR PROGRAM ;)
GOTO AT45DB
LOOP
'*******************************************************************************
AT45DB:
CLS
Reset Select_memory
Waitus 10
CALL Db45up()
Waitus 10
Set Select_memory
Wait 1
Locate 1 , 1 : Lcd "Reading Device...."
Reset Select_memory
Waitus 10
Cim(1) = &H57
Spiout Cim(1) , 1
Spiin AB(1) , 1 ' read A(1) from SPI
Waitus 5
Set Select_memory
Locate 2 , 1 : Lcd Cim(1) ; " " ; AB(1)
Shift AB(1) , Right , 3
AB(1) = AB(1) And &H07
GREEN = 1
If AB(1) = 1 Then
Locate 3 , 1 : MSG = "AT45DB011 264 / 512" : LCD MSG
Elseif AB(1) = 2 Then
Locate 3 , 1 : MSG = "AT45DB021 264 / 1024" : LCD MSG
Elseif AB(1) = 3 Then
Locate 3 , 1 : MSG = "AT45DB041 264 / 2048" : LCD MSG
Elseif AB(1) = 4 Then
Locate 3 , 1 : MSG = "AT45DB081 264 / 4096" : LCD MSG
Elseif AB(1) = 5 Then
Locate 3 , 1 : MSG = "AT45DB161 528 / 4096" : LCD MSG
Elseif AB(1) = 6 Then
Locate 3 , 1 : MSG = "AT45DB321 528 / 8192" : LCD MSG ' now I use AT45DB321D (I also tried DB161E(D) , DB081D(B) , DB041D(B) , DB011B) CHECKED PERSONALLY ME ALL WORKS
End If
Wait 2
CLS
Locate 1 , 1 : Lcd "KEY0 - PROGRAMM MODE"
Locate 2 , 1 : Lcd "KEY1 - PLAY AUDIO"
LOCATE 3 , 1 : LCD "KEY2 - ERASE ALL"
LOCATE 4 , 1 : LCD "KEY3 - EXIT"
DO
IF A0 = 0 THEN
RED = 1 : GOSUB TAD : WAITMS 250
RED = 0 ': GOTO PRGMODE ' IN THE PROCESS OF IMPLEMENTATION
END IF
IF A1 = 0 THEN
GREEN = 1 : GOSUB TAD : WAITMS 250
GREEN = 0 : GOTO PLAYFLASH
END IF
IF A2 = 0 THEN
CLS
LOCATE 1 , 1 : LCD "*ERASE ALL*"
RED = 1 : GOSUB TAD : WAITMS 250
RED = 0 ': GOTO FERASE ' IN THE PROCESS OF IMPLEMENTATION
END IF
IF A3 = 0 THEN
CLS
GREEN = 1 : GOSUB TAD : WAITMS 250
GREEN = 0 : CALL Db45down() : GOTO MAIN
END IF
LOOP
'*******************************************************************************
' PLAYBACK SUBPROGRAM WAV FILE 8 BIT MONO 16000Hz (THE FREQUENCY MAY BE MORE OR LESS BUT THEN YOU HAVE TO CHOOSE Waitus)
PLAYFLASH:
CLS
LOCATE 1 , 1 : LCD "PLAY AUDIO! [AT45DB]"
LOCATE 2 , 1 : LCD MSG
Locate 3 , 1 : Lcd "Address:"
LOCATE 4 , 1 : LCD "Page:"
FOR Pagge = 0 TO 8191
Call Page_read(Pagge)
FOR NN = 1 TO 528
N = Buf(NN)
Pwm1A = N
Waitus 55
IF A3 = 0 THEN
GOTO AT45DB
END IF
NEXT NN
NEXT Pagge
WAIT 2 : GOSUB TADAN
GOTO AT45DB
Return
'**********************************************************************
TAD:
Sound Speaker , 133 , 285
Sound Speaker , 77 , 260
RETURN
'*******************************************************************************
TADAN:
Sound Speaker , 213 , 271
Sound Speaker , 125 , 237
RETURN
'*******************************************************************************
'-------------------------------------------------------------------------------
Sub Page_read(byval Page_mem As Word)
'-------------Flash read subroutine---------------------------------------------
'Subroutine to read a given page of memory
'Login ------- page_Mem (0-8191)
'Output ------ buf (528) 528 byte array
Reset Select_memory 'select flash ram
N = Current_page_read 'command Current_page_read
Call Byteout() 'out 3 bytes of adress
Shift Page_mem , Left , 2 'For 264 pages the value is 1, for 528 pages the value is 2

A = Page_mem
Call Wordout()
N = 0
Call Byteout()
'-------------
Call Byteout()
Call Byteout()
Call Byteout()
Call Byteout()
'transmit 32 dont care bits
For Temp1 = 1 To 528
Call Bytein()
Buf(temp1) = N
Next Temp1
Set Select_memory
End Sub
'*******************************************************************************
Sub Buffer1_to_flash(byval Page_mem As Word)
'-------------Flash write subroutine---------------------------------------------
'The subroutine for writing buffer 1 to the memory page
'Login ------- page_Mem (0-8191)
Reset Select_memory
N = Buff1_mem_write ' command write buffer to flash
Call Byteout()
Shift Page_mem , Left , 2 'For 264 pages the value is 1, for 528 pages the value is 2

A = Page_mem
Call Wordout()
N = 0
Call Byteout()
Set Select_memory 'deselect memory
Waitms 30
End Sub
'*******************************************************************************
Sub Buffer1_write
Reset Select_memory
N = Buff1_write ' command write in buffer
Call Byteout()
N = &H00 '
Call Byteout()
N = &H00 '
Call Byteout()
N = &H00 '
Call Byteout()
'Set Select_memory
End Sub
'*******************************************************************************
Sub Page_write(page_mem As Word)
Reset Select_memory
N = Current_page_write ' command write buffer to flash
Call Byteout()
Shift Page_mem , Left , 2 'For 264 pages the value is 1, for 528 pages the value is 2
A = Page_mem
Call Wordout()
N = 0
Call Byteout()
'Waitms 30
End Sub
'*******************************************************************************
Sub Bytein()
!ldi r23,0
!Out Spdr , R23
Wairh:
!sbis spsr, spif
!rjmp wairh
!in r23,spdr
!sts {n},r23
End Sub
'*******************************************************************************
Sub Byteout
!lds r23, {n}
!out spdr, r23
Waitresult:
!sbis spsr, spif
!rjmp waitresult
End Sub
'*******************************************************************************
Sub Db45down
Reset Select_memory
N = Deep_power_down
Call Byteout()
Set Select_memory
End Sub
'*******************************************************************************
Sub Db45up
Reset Select_memory
N = Resume_deep_power_down
Call Byteout()
Set Select_memory
End Sub
'*******************************************************************************
End

Пока что не разобрался как записывать с помощью этого кода (Нужно чтоб формировал массив 264(528) байт) тогда можно сделать программатор чтоб с компа по уарту залмвать файлы.

Отредактировано Sonic Blast (2021-11-14 17:25:05)

0

17

Мощная Библиотека для работы с AT45DB DataFlash (пока не удаолсь с ней разобратся)

Имя файла: ESF_declarations.inc

Код:
'*******************************************************************************
'
'  Copyright Michael Koecher aka six1 8/2010
'  -> http://www.six1.net/   michael@koecher-web.de
'
'   http://creativecommons.org/licenses/by-sa/3.0/de/
'
'   Sie dьrfen:
'
'     * das Werk bzw. den Inhalt vervielfдltigen, verbreiten und цffentlich zugдnglich machen
'
'     * Abwandlungen und Bearbeitungen des Werkes bzw. Inhaltes anfertigen
'
'   Zu Den Folgenden Bedingungen:
'
'     * Namensnennung.
'       Sie mьssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
'
'     * Keine kommerzielle Nutzung.
'       Dieses Werk darf nicht fьr kommerzielle Zwecke verwendet werden.
'
'     * Weitergabe unter gleichen Bedingungen.
'       Wenn Sie das lizenzierte Werk bzw. den lizenzierten Inhalt bearbeiten
'       oder in anderer Weise erkennbar als Grundlage fьr eigenes Schaffen verwenden,
'       dьrfen Sie die daraufhin neu entstandenen Werke bzw. Inhalte nur
'       unter Verwendung von Lizenzbedingungen weitergeben, die mit denen
'       dieses Lizenzvertrages identisch oder vergleichbar sind.
'
'   Wobei gilt:
'
'     * Verzichtserklдrung
'       Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie
'       die ausdrьckliche Einwilligung des Rechteinhabers dazu erhalten.
'
'     * Sonstige Rechte
'       Die Lizenz hat keinerlei Einfluss auf die folgenden Rechte:
'          - Die gesetzlichen Schranken des Urheberrechts und sonstigen
'            Befugnisse zur privaten Nutzung
'          - Das Urheberpersцnlichkeitsrecht des Rechteinhabers
'          - Rechte anderer Personen, entweder am Lizenzgegenstand selber oder
'            bezьglich seiner Verwendung, zum Beispiel Persцnlichkeitsrechte abgebildeter Personen.
'
'  Hinweis
'
'      Im Falle einer Verbreitung mьssen Sie anderen alle Lizenzbedingungen
'      mitteilen, die fьr dieses Werk gelten. Am einfachsten ist es,
'      einen Link auf http://creativecommons.org/licenses/by-sa/3.0/de/ einzubinden.
'

'*******************************************************************************
$nocompile

'*******************************************************************************
'* ExternalSerialFlash (ESF) Hardware Setup
'*******************************************************************************

   'define Chip-Select Pin of SPI Bus
   Config Ping.4 = Output                                   ' define here Pin for CS External serial Flash
   Esf_cs Alias Portg.4
   Set Esf_cs

'   Config Pinb.0 = Output                                   ' define here Pin for CS External serial Flash
'   SPI_SS Alias PortB.0
'   Set SPI_SS


   ' HW-SPI is configured to highest Speed
'   Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1
'   Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 1 , Spiin = 0
'   Spsr = 1                                                 ' Double speed on ATMega128
   'Set Spsr.spi2x
'   Spiinit
'(
Spcr = &B01011100
Spsr = 1 fьr's Nokia Display

Spcr = &B01010000
Spsr = 1 Fьr                                                's ESF
')


'*******************************************************************************
'* PRIVATE DECLARATIONS
'*  this is Hardware specific. Don't call this functions from your code!
'*******************************************************************************

' Dataflash Opcodes
'Const Flashpageread = &HD2                                                      ' Main Memory Page Read
Const Flashtobuf1transfer = &H53                                                ' Main Memory Page To Buffer 1 Transfer
Const Buf1read = &HD4                                                           ' Buffer 1 Read
Const Flashtobuf2transfer = &H55                                                ' Main Memory Page To Buffer 2 Transfer
Const Buf2read = &HD6                                                           ' Buffer 2 Read
Const Statusreg = &HD7                                                          '&H57                                                          ' Status Register
Const Autopagerewrbuf1 = &H58                                                   ' Auto Page Rewrite Through Buffer 1
Const Autopagerewrbuf2 = &H59                                                   ' Auto Page Rewrite Through Buffer 2
Const Flashtobuf1compare = &H60                                                 ' Main Memory Page To Buffer 1 Compare
Const Flashtobuf2compare = &H61                                                 ' Main Memory Page To Buffer 2 Compare
Const Contarrayread = &H68                                                      ' Continuous Array Read(note : Only A / B -parts Supported)
Const Flashprogbuf1 = &H82                                                      ' Main Memory Page Program Through Buffer 1
Const Buf1toflashwe = &H83                                                      ' Buffer 1 To Main Memory Page Program With Built -in Erase
Const Buf1write = &H84                                                          ' Buffer 1 Write
Const Flashprogbuf2 = &H85                                                      ' Main Memory Page Program Through Buffer 2
Const Buf2toflashwe = &H86                                                      ' Buffer 2 To Main Memory Page Program With Built -in Erase
Const Buf2write = &H87                                                          ' Buffer 2 Write
Const Buf1toflash = &H88                                                        ' Buffer 1 To Main Memory Page Program Without Built -in Erase
Const Buf2toflash = &H89                                                        ' Buffer 2 To Main Memory Page Program Without Built -in Erase

#if Use_xram = 1
   Dim Pagebits As Xram Byte
   Dim Pagesize As XRAM Word
   Dim Status_register_value As XRAM Byte
   Dim Pagecounter As XRAM Word
   Dim Esfsystemsize As XRAM Dword
   Dim Esfsystemcount As XRAM Dword
   Dim Esfblockcount As XRAM Word
   Dim Esfblockcount_l As XRAM Byte At Esfblockcount Overlay
   Dim Esfblockcount_h As XRAM Byte At Esfblockcount + 1 Overlay
   Dim Esfblockcheck As XRAM Word
   Dim Esfblockcheck_l As XRAM Byte At Esfblockcheck Overlay
   Dim Esfblockcheck_h As XRAM Byte At Esfblockcheck + 1 Overlay
   Dim Esfblocksize As XRAM Word
   Dim Esfblocksize_l As Xram Byte At Esfblocksize Overlay
   Dim Esfblocksize_h As Xram Byte At Esfblocksize + 1 Overlay

   Dim Esfblockcount_old As XRAM Word

   Dim Esf_file_start As XRAM Dword
   Dim Esf_file_start_1 As XRAM Byte At Esf_file_start + 2 Overlay
   Dim Esf_file_start_2 As XRAM Byte At Esf_file_start + 1 Overlay
   Dim Esf_file_start_3 As XRAM Byte At Esf_file_start Overlay

   Dim Esf_file_len As XRAM Dword
   Dim Esf_file_len_1 As XRAM Byte At Esf_file_len + 2 Overlay
   Dim Esf_file_len_2 As XRAM Byte At Esf_file_len + 1 Overlay
   Dim Esf_file_len_3 As XRAM Byte At Esf_file_len Overlay

   Dim Buffer_address As XRAM Word
   Dim System_finished As XRAM Byte

   Dim File_read_line_pos As Xram Dword

   Dim Esf_pfad As XRAM String * 15
#else
   Dim Pagebits As Byte
   Dim Pagesize As Word
   Dim Status_register_value As Byte
   Dim Pagecounter As Word
   Dim Esfsystemsize As Dword
   Dim Esfsystemcount As Dword
   Dim Esfblockcount As Word
   Dim Esfblockcount_l As Byte At Esfblockcount Overlay
   Dim Esfblockcount_h As Byte At Esfblockcount + 1 Overlay
   Dim Esfblockcheck As Word
   Dim Esfblockcheck_l As Byte At Esfblockcheck Overlay
   Dim Esfblockcheck_h As Byte At Esfblockcheck + 1 Overlay
   Dim Esfblocksize As Word
   Dim Esfblocksize_l As Byte At Esfblocksize Overlay
   Dim Esfblocksize_h As  Byte At Esfblocksize + 1 Overlay

   Dim Esfblockcount_old As Word

   Dim Esf_file_start As Dword
   Dim Esf_file_start_1 As Byte At Esf_file_start + 2 Overlay
   Dim Esf_file_start_2 As Byte At Esf_file_start + 1 Overlay
   Dim Esf_file_start_3 As Byte At Esf_file_start Overlay

   Dim Esf_file_len As Dword
   Dim Esf_file_len_1 As Byte At Esf_file_len + 2 Overlay
   Dim Esf_file_len_2 As Byte At Esf_file_len + 1 Overlay
   Dim Esf_file_len_3 As Byte At Esf_file_len Overlay

   Dim Buffer_address As Word
   Dim System_finished As Byte

   Dim File_read_line_pos As Dword

   Dim Esf_pfad As String * 15
#endif

Declare Function Df_read_status()as Byte
Declare Sub Df_init()
Declare Function Df_bufferreadbyte(byval Bufferno As Byte , Byval Intpageadr As Word) As Byte
Declare Sub Df_bufferwritebyte(byval Bufferno As Byte , Byval Intpageadr As Word , Byval Databyte As Byte)
Declare Sub Df_pagetobuffer(byval Bufferno As Byte , Byval Pageadr As Word)
Declare Sub Df_buffertopage(byval Bufferno As Byte , Byval Pageadr As Word)
Declare Sub Df_bufferreadarray(byval Bufferno As Byte , Byval Intpageadr As Word , Byval No_of_bytes As Word , Byref Bufferptr As Word)
Declare Sub Df_bufferwriteenable(byval Bufferno As Byte , Byval Intpageadr As Word)
Declare Sub Df_bufferwritestr(byval Bufferno As Byte , Byval Intpageadr As Word , Byval No_of_bytes As Word , Byref Bufferptr As Word)
Declare Sub Cont_flash_read_enable(byval Pageadr As Word , Byval Intpageadr As Word)
Declare Sub Df_chip_erase()
Declare Sub Esf_filelist()
Declare Sub ESF_check_pagepos(byref Pagepos As Word , Byref Page As Word)
declare function Esf_find_file(byval searchfile as string) as byte
Declare Sub ESF_SPI_CS(byval avtivate as byte)


'*******************************************************************************
'* PUBLIC DECLARATIONS
'*  this Functions are independent from Hardware. Call these functions from your code
'*******************************************************************************


   Declare Sub Chg_dir(byval Directory As String)
   Declare Function Get_filelen(byval Filename As String) As DWord
   Declare Function Read_file(byval Filename As String , Byval Directory As String) As String
   Declare Sub Read_file_block(byval Filename As String , Byval Startpos As Dword , Byval Length As Dword , Byval Bufferstart As Word , Byval Buffer As Dword)
   Declare Sub Get_filedate(byval Filename As String , Byref File_date As String)
   Declare Sub Get_filetime(byval Filename As String , Byref File_time As String)
   Declare Sub List_first_file(byref Filename As String)
   Declare Sub List_next_file(byref Filename As String)
   declare Function Read_line(byval Filename As String , Byval Directory As String, byval art as byte) As String



Call Df_init()

Имя файла:  ESF_routines.inc

Код:
'*******************************************************************************
'
'  Copyright Michael Koecher aka six1 8/2010
'  -> http://www.six1.net/   michael@koecher-web.de
'
'   http://creativecommons.org/licenses/by-sa/3.0/de/
'
'   Sie dьrfen:
'
'     * das Werk bzw. den Inhalt vervielfдltigen, verbreiten und цffentlich zugдnglich machen
'
'     * Abwandlungen und Bearbeitungen des Werkes bzw. Inhaltes anfertigen
'
'   Zu Den Folgenden Bedingungen:
'
'     * Namensnennung.
'       Sie mьssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
'
'     * Keine kommerzielle Nutzung.
'       Dieses Werk darf nicht fьr kommerzielle Zwecke verwendet werden.
'
'     * Weitergabe unter gleichen Bedingungen.
'       Wenn Sie das lizenzierte Werk bzw. den lizenzierten Inhalt bearbeiten
'       oder in anderer Weise erkennbar als Grundlage fьr eigenes Schaffen verwenden,
'       dьrfen Sie die daraufhin neu entstandenen Werke bzw. Inhalte nur
'       unter Verwendung von Lizenzbedingungen weitergeben, die mit denen
'       dieses Lizenzvertrages identisch oder vergleichbar sind.
'
'   Wobei gilt:
'
'     * Verzichtserklдrung
'       Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie
'       die ausdrьckliche Einwilligung des Rechteinhabers dazu erhalten.
'
'     * Sonstige Rechte
'       Die Lizenz hat keinerlei Einfluss auf die folgenden Rechte:
'          - Die gesetzlichen Schranken des Urheberrechts und sonstigen
'            Befugnisse zur privaten Nutzung
'          - Das Urheberpersцnlichkeitsrecht des Rechteinhabers
'          - Rechte anderer Personen, entweder am Lizenzgegenstand selber oder
'            bezьglich seiner Verwendung, zum Beispiel Persцnlichkeitsrechte abgebildeter Personen.
'
'  Hinweis
'
'      Im Falle einer Verbreitung mьssen Sie anderen alle Lizenzbedingungen
'      mitteilen, die fьr dieses Werk gelten. Am einfachsten ist es,
'      einen Link auf http://creativecommons.org/licenses/by-sa/3.0/de/ einzubinden.
'

'*******************************************************************************
$nocompile

Sub Esf_spi_cs(byval Avtivate As Byte)
' Avtivate MUST BE!  0 or 1
    If Avtivate = 0 Then
       Set Esf_cs
    Else
       #if _xmega = 0
         Spcr = &B01010000
         Spsr.spi2x = 1
       #endif
       Reset Esf_cs
    End If
End sub



Sub Read_file_block(byval Filename As String , Byval Startpos As Dword , Byval Length As Dword , Byval Bufferstart As Word , Byval Buffer As Dword)
    Local Esf_block As Word , Esf_pos As Word , Esf_readpos As Dword
    Local Payload_pos As dWord , B_b As Byte , No_of_bytes As Word
    Local X_x As Word, Esf_help_block As dword
    local tmp_filename as string * 40

    If Esf_pfad <> "" Then
      Tmp_filename = Esf_pfad + "/" + Filename
    Else
      Tmp_filename = Filename
    End If

    B_b = Esf_find_file(Tmp_filename)
    B_b = 1


    If B_b = 1 then
       Esf_readpos = Esf_file_start + Startpos
       Decr Esf_readpos
       Esf_help_block = Esf_readpos                         ' / 256
       Shift Esf_help_block , Right , 8
       Esf_block = Esf_help_block
       ' add offset Startaddress for Filedata in ESF
       Esf_block = Esf_block + 513
       Esf_pos = Esf_readpos Mod 256
       Call Df_pagetobuffer(1 , Esf_block)
       Payload_pos = Bufferstart + 1
       Length = Length + Bufferstart

       '(
Print #1 , "Filename " ; Filename
Print #1 , "Startpos " ; Startpos
Print #1 , "Length " ; Length
Print #1 , "Esf_readpos " ; Esf_readpos
Print #1 , "Esf_block " ; Esf_block
Print #1 , "Esf_pos " ; Esf_pos
Print #1 , "Payload_pos " ; Payload_pos
')

       ' // with loop
'       Buffer_address = Buffer + Bufferstart
       ' // with SPIIN
       Buffer_address = 1

       Do

           Call Esf_spi_cs(1)
           B_b = Buf1read                                   ' Buffer 1 Read Op -code
           Spiout B_b , 1                                   ' Buffer 1 Read Op -code
           B_b = 0
           Spiout B_b , 1
           B_b = High(esf_pos)                              ' Don't cares
           Spiout B_b , 1                                   ' Upper Part Of Internal Buffer Address
           B_b = Low(esf_pos)                               ' Don't cares
           Spiout B_b , 1                                   ' Lower Part Of Internal Buffer Address
           B_b = 0
           Spiout B_b , 1

           No_of_bytes = 256 - Esf_pos
           X_x = No_of_bytes + Payload_pos
           If X_x > Length Then
              No_of_bytes = Length - Payload_pos
              Incr No_of_bytes
           End If
'Print #1 , "No_of_bytes " ; No_of_bytes

       ' // with SPIIN
           If No_of_bytes > 255 Then
             Spiin Eth_buffer(buffer_address) , 1
             Spiin Eth_buffer(buffer_address + 1) , 255
           Else
             Spiin Eth_buffer(buffer_address) , No_of_bytes
           End If


'(
       ' // with loop
           For X_x = 1 To No_of_bytes
              Spiin B_b , 1
              Out Buffer_address , B_b
'Print #1 , Chr(b_b)
              Incr Buffer_address
           Next
')

           Call Esf_spi_cs(0)
           Buffer_address = Buffer_address + No_of_bytes
           Payload_pos = Payload_pos + No_of_bytes
           Incr Esf_block
           Call Df_pagetobuffer(1 , Esf_block)
           Esf_pos = 0
       Loop Until Payload_pos >= Length
'Print #1 , "Payload_pos " ; Payload_pos

    End If
End Sub




Sub Chg_dir(byval Directory As String)
    ' nothing to do. There is NO DIR on ESF
    Esf_pfad = Trim(directory)
End Sub

Function Get_filelen(byval Filename As String) As Dword
    local tmp_filename as string * 40
    If Esf_pfad <> "" Then
      Tmp_filename = Esf_pfad + "/" + Filename
    Else
      Tmp_filename = Filename
    End If
    If Esf_find_file(tmp_filename) = 1 Then
       Get_filelen = Esf_file_len
    Else
       Get_filelen = 0
    End If
End Function

Function Read_file(byval Filename As String , Byval Directory As String) As String
    local tmp_filename as string * 40
    Local Esf_block As Word , Esf_pos As Word , Esf_readpos As Dword
    Local Payload_pos As dWord , B_b As Byte , No_of_bytes As Word
    Local X_x As Word, Esf_help_block As dword

    Read_file = ""
    If Directory <> "" Then
      Tmp_filename = Directory + "/" + Filename
    Else
      Tmp_filename = Filename
    End If
    B_b = Esf_find_file(tmp_filename)
    If B_b = 1 And Esf_file_len < 256 Then
       Esf_readpos = Esf_file_start
    '   Decr Esf_readpos
       Esf_help_block = Esf_readpos                         ' / 256
       Shift Esf_help_block , Right , 8
       Esf_block = Esf_help_block
       ' add offset Startaddress for Filedata in ESF
       Esf_block = Esf_block + 513
       Esf_pos = Esf_readpos Mod 256
       Call Df_pagetobuffer(1 , Esf_block)
       Payload_pos =  1

       '(
Print #1 , "Filename " ; Filename
Print #1 , "Length " ; Length
Print #1 , "Esf_readpos " ; Esf_readpos
Print #1 , "Esf_block " ; Esf_block
Print #1 , "Esf_pos " ; Esf_pos
Print #1 , "Payload_pos " ; Payload_pos
')

       ' // with loop
'       Buffer_address = Buffer + Bufferstart
       ' // with SPIIN
       Buffer_address = 1

       Do

           Call Esf_spi_cs(1)
           B_b = Buf1read                                   ' Buffer 1 Read Op -code
           Spiout B_b , 1                                   ' Buffer 1 Read Op -code
           B_b = 0
           Spiout B_b , 1
           B_b = High(esf_pos)                              ' Don't cares
           Spiout B_b , 1                                   ' Upper Part Of Internal Buffer Address
           B_b = Low(esf_pos)                               ' Don't cares
           Spiout B_b , 1                                   ' Lower Part Of Internal Buffer Address
           B_b = 0
           Spiout B_b , 1

           No_of_bytes = 256 - Esf_pos
           X_x = No_of_bytes + Payload_pos
           If X_x > Esf_file_len Then
              No_of_bytes = Esf_file_len - Payload_pos
              Incr No_of_bytes
           End If

           For X_x = 1 To No_of_bytes
              Spiin B_b , 1
              Read_file = Read_file + Chr(b_b)
           Next

           Call Esf_spi_cs(0)
           Payload_pos = Payload_pos + No_of_bytes
           Incr Esf_block
           Call Df_pagetobuffer(1 , Esf_block)
           Esf_pos = 0
       Loop Until Payload_pos >= Esf_file_len
    End If
End Function

Function Read_line(byval Filename As String , Byval Directory As String, byval art as byte) As String
    local tmp_filename as string * 40
    Local Esf_block As Word , Esf_pos As Word , Esf_readpos As Dword
    Local Payload_pos As dWord , B_b As Byte , No_of_bytes As Word
    Local X_x As Word, Esf_help_block As dword
    Local Total As Word
    Read_line = ""
    If Directory <> "" Then
      Tmp_filename = Directory + "/" + Filename
    Else
      Tmp_filename = Filename
    End If
    B_b = Esf_find_file(tmp_filename)
    If B_b = 1  Then
       ' Reset Pointer to first line
       If Art = 1 Then File_read_line_pos = 0
       Esf_readpos = Esf_file_start + File_read_line_pos
       Total = File_read_line_pos
       If Total >= Esf_file_len Then
         Read_line = ""
         Exit Function
       End If
    '   Decr Esf_readpos
       Esf_help_block = Esf_readpos                         ' / 256
       Shift Esf_help_block , Right , 8
       Esf_block = Esf_help_block
       ' add offset Startaddress for Filedata in ESF
       Esf_block = Esf_block + 513
       Esf_pos = Esf_readpos Mod 256
       Call Df_pagetobuffer(1 , Esf_block)
       Payload_pos =  1

       '(
Print #1 , "Filename " ; Filename
Print #1 , "Length " ; Length
Print #1 , "Esf_readpos " ; Esf_readpos
Print #1 , "Esf_block " ; Esf_block
Print #1 , "Esf_pos " ; Esf_pos
Print #1 , "Payload_pos " ; Payload_pos
')

       ' // with loop
'       Buffer_address = Buffer + Bufferstart
       ' // with SPIIN
       Buffer_address = 1

       Do
           Call Esf_spi_cs(1)
           B_b = Buf1read                                   ' Buffer 1 Read Op -code
           Spiout B_b , 1                                   ' Buffer 1 Read Op -code
           B_b = 0
           Spiout B_b , 1
           B_b = High(esf_pos)                              ' Don't cares
           Spiout B_b , 1                                   ' Upper Part Of Internal Buffer Address
           B_b = Low(esf_pos)                               ' Don't cares
           Spiout B_b , 1                                   ' Lower Part Of Internal Buffer Address
           B_b = 0
           Spiout B_b , 1

           No_of_bytes = 256 - Esf_pos
           X_x = No_of_bytes + Payload_pos
           If X_x > Esf_file_len Then
              No_of_bytes = Esf_file_len - Payload_pos
              Incr No_of_bytes
           End If

           For X_x = 1 To No_of_bytes
              Spiin B_b , 1
              If B_b <> 13 Then
                Read_line = Read_line + Chr(b_b)
              Else
                Incr X_x
                Exit For
              End If
           Next

           Call Esf_spi_cs(0)

           Total = Total + x_x
           Payload_pos = Payload_pos + x_x
           File_read_line_pos = File_read_line_pos + X_x
           If B_b <> 13 Then
             Incr Esf_block
             Call Df_pagetobuffer(1 , Esf_block)
             Esf_pos = 0
           End If
       Loop Until Payload_pos >= 255 Or B_b = 13 Or Total >= Esf_file_len
    End If
End Function


Sub Get_filedate(byval Filename As String , Byref File_date As String)
     File_date = "00.00.0000"
End Sub

Sub Get_filetime(byval Filename As String , Byref File_time As String)
     File_time = "00:00:00"
End Sub

Sub List_first_file(byref Filename As String)

End Sub

Sub List_next_file(byref Filename As String)

End Sub




 'Look -up Table For These Sizes - > 512k , 1m , 2m , 4m , 8m , 16m , 32m , 64m
Df_pagebits_data:
 Data 9 , 9 , 9 , 9 , 9 , 10 , 10 , 11

 'Look -up Table For These Sizes - > 512k , 1m , 2m , 4m , 8m , 16m , 32m , 64m
Df_pagesize_data:
 Data 264% , 264% , 264% , 264% , 264% , 528% , 528% , 1056%


Sub Df_init()
   Local B_b As Byte
   Local Index_copy As Byte
   Local Res_byte As Byte

'   Set Esf_cs
'   Call Deactivate_all_spi_units
'   Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 1 , Spiin = 0       '    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1 , Spiin = 0
'   Set Spsr.spi2x
'   Spiinit


'256 Byte Mode
   Call Esf_spi_cs(1)
   B_b = &H3D
   Spiout B_b , 1
   B_b = &H2A
   Spiout B_b , 1
   B_b = &H80
   Spiout B_b , 1
   B_b = &HA6
   Spiout B_b , 1
   'with special Thanks to Erwin who find out, that the 4ms delay is missing!
   Waitms 4
'Power cycle the device...
   Call Esf_spi_cs(0)


   Status_register_value = Df_read_status()

   Index_copy = Df_read_status() And &H38                   ' Get The Size Info From Status Register
   Shift Index_copy , Right , 3
'Print #1 , "Status: " ; Index_copy
   Decr Index_copy
   Pagesize = Lookup(index_copy , Df_pagesize_data)
   Pagebits = Lookup(index_copy , Df_pagebits_data)
'Print #1 , "Pagebits: " ; Pagebits
'Print #1 , "Pagesize: " ; Pagesize

'Erase sector protect

   Call Esf_spi_cs(1)
   B_b = &H3D
   Spiout B_b , 1
   B_b = &H2A
   Spiout B_b , 1
   B_b = &H7F
   Spiout B_b , 1
   B_b = &HCF
   Spiout B_b , 1

   B_b = 0
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Spiout B_b , 1
   Call Esf_spi_cs(0)


End Sub

Sub Df_chip_erase()
   Local B_b As Byte
   Call Esf_spi_cs(1)
   B_b = &HC7
   Spiout B_b , 1
   B_b = &H94
   Spiout B_b , 1
   B_b = &H80
   Spiout B_b , 1
   B_b = &H9A
   Spiout B_b , 1
   Call Esf_spi_cs(0)
End Sub

Function Df_bufferreadbyte(byval Bufferno As Byte , Byval Intpageadr As Word) As Byte
   Local B_b As Byte

   Call Esf_spi_cs(1)
   If Bufferno = 1 Then                                     ' Read Byte From Buffer 1
      B_b = Buf1read
   Else
      B_b = Buf2read
   End If
   Spiout B_b , 1                                           ' Buffer 1 Read Op -code

   B_b = 0
   Spiout B_b , 1
   B_b = High(intpageadr)                                   ' Don't cares
   Spiout B_b , 1                                           ' Upper Part Of Internal Buffer Address
   B_b = Low(intpageadr)
   Spiout B_b , 1                                           ' Lower Part Of Internal Buffer Address
   B_b = 0
   Spiout B_b , 1
   Spiin Df_bufferreadbyte , 1                              ' Read Byte
   Call Esf_spi_cs(0)
End Function


Sub Df_bufferwritebyte(byval Bufferno As Byte , Byval Intpageadr As Word , Byval Databyte As Byte)
   Local B_b As Byte

   Call Esf_spi_cs(1)
   If Bufferno = 1 Then                                     ' write Byte to Buffer 1
      B_b = Buf1write
   Else
      B_b = Buf2write                                       ' write Byte to Buffer 2
   End If
   Spiout B_b , 1

   B_b = 0
   Spiout B_b , 1
   B_b = High(intpageadr)                                   ' Don't cares
   Spiout B_b , 1                                           ' Upper Part Of Internal Buffer Address
   B_b = Low(intpageadr)
   Spiout B_b , 1                                           ' Lower Part Of Internal Buffer Address
   Spiout Databyte , 1
   Call Esf_spi_cs(0)
End Sub



'--------------------------------------------------------------------------------
' Function name : df_read_status
'
' Returns :  One status byte. Consult Dataflash datasheet for further decoding info
'
' Parameters : None
'
' Purpose :  Status info concerning the Dataflash is busy or not.
'            Status info concerning compare between buffer and flash page
'            Status info concerning size of actual device
'
'Table 11-1. Status Register Format
'Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
'RDY/BUSY COMP 0 1 1 1 PROTECT PAGE SIZE
'--------------------------------------------------------------------------------
Function Df_read_status() As Byte
   Local B_b As Byte

   Call Esf_spi_cs(1)
   B_b = Statusreg
   Spiout B_b , 1                                           ' Send Status Register Read Op -code
   Spiin Df_read_status , 1                                 ' Send Status Register Read Op -code
   B_b = 0
   Spiout B_b , 1                                           ' Dummy Write To Get Result
   Spiin Df_read_status , 1                                 ' Dummy Write To Get Result
   Call Esf_spi_cs(0)
End Function


'--------------------------------------------------------------------------------
'
' Function name : DF_PageToBuffer
'
' Returns :  None
'
' Parameters : BufferNo -> Decides usage of either buffer 1 or 2
'     PageAdr  -> Address of page to be transferred to buffer
'
' Purpose :  Transfers a page from flash to dataflash SRAM buffer
'
'--------------------------------------------------------------------------------
Sub Df_pagetobuffer(byval Bufferno As Byte , Byval Pageadr As Word)
   Local B_b As Byte , B_c As Byte

   Call Esf_spi_cs(1)

   If Bufferno = 1 Then
      B_b = Flashtobuf1transfer
   Else
      B_b = Flashtobuf2transfer
   End If
   Spiout B_b , 1
   B_c = High(pageadr)
   Spiout B_c , 1                                           ' Dummy Write To Get Result

   B_c = Low(pageadr)
   Spiout B_c , 1

   B_b = 0
   Spiout B_b , 1                                           ' Dummy Write
   Call Esf_spi_cs(0)

   Call Esf_spi_cs(1)
   Do
     B_b = Df_read_status()
   Loop Until B_b.7 = 1

   Call Esf_spi_cs(0)
End Sub



Sub Df_buffertopage(byval Bufferno As Byte , Byval Pageadr As Word)
   Local B_b As Byte , B_c As Byte

   Call Esf_spi_cs(1)

   If Bufferno = 1 Then
      B_b = Buf1toflashwe
   Else
      B_b = Buf2toflashwe
   End If
   Spiout B_b , 1

   B_c = High(pageadr)
   Spiout B_c , 1                                           ' Dummy Write To Get Result

   B_c = Low(pageadr)
   Spiout B_c , 1

   B_b = 0
   Spiout B_b , 1                                           ' Dummy Write
   Call Esf_spi_cs(0)
   Waitus 10
   Call Esf_spi_cs(1)

   Do
     B_b = Df_read_status()
   Loop Until B_b.7 = 1

   Call Esf_spi_cs(0)
End Sub

'--------------------------------------------------------------------------------
'
' Function name : DF_BufferReadArray
'
' Returns :  None
'
' Parameters : BufferNo -> Decides usage of either buffer 1 or 2
'     IntPageAdr -> Internal page address
'     No_of_bytes -> Number of bytes to be read
'     *BufferPtr -> address of buffer to be used for read bytes
'
' Purpose :  Reads one or more bytes from one of the dataflash
'     internal SRAM buffers, and puts read bytes into
'     buffer pointed to by *BufferPtr
'
'--------------------------------------------------------------------------------
Sub Df_bufferreadarray(byval Bufferno As Byte , Byval Intpageadr As Word , Byval No_of_bytes As Word , Byref Bufferptr As Word)
   Local B_b As Byte

   Call Esf_spi_cs(1)
   If Bufferno = 1 Then                                     ' Read Byte From Buffer 1
      B_b = Buf1read                                        ' Buffer 1 Read Op -code
   Else
      B_b = Buf2read                                        ' Buffer 2 Read Op -code
   End If
   Spiout B_b , 1                                           ' Buffer 1 Read Op -code
   B_b = 0
   Spiout B_b , 1
   B_b = High(intpageadr)                                   ' Don't cares
   Spiout B_b , 1                                           ' Upper Part Of Internal Buffer Address
   B_b = Low(intpageadr)                                    ' Don't cares
   Spiout B_b , 1                                           ' Lower Part Of Internal Buffer Address


   Spiin Bufferptr , No_of_bytes

   Call Esf_spi_cs(0)
End Sub




'--------------------------------------------------------------------------------
'
' Function name : DF_BufferWriteEnable
'
' Returns :  None
'
' Parameters : IntPageAdr -> Internal page address to start writing from
'     BufferAdr -> Decides usage of either buffer 1 or 2
'
' Purpose :  Enables continous write functionality to one of the dataflash buffers
'     buffers. NOTE : User must ensure that CS goes high to terminate
'     this mode before accessing other dataflash functionalities
'
'--------------------------------------------------------------------------------
Sub Df_bufferwriteenable(byval Bufferno As Byte , Byval Intpageadr As Word)
   Local B_b As Byte

   Call Esf_spi_cs(1)
   If Bufferno = 1 Then                                     ' Read Byte From Buffer 1
      B_b = Buf1write                                       ' Buffer 1 Read Op -code
   Else
      B_b = Buf2write                                       ' Buffer 2 Read Op -code
   End If
   Spiout B_b , 1                                           ' Buffer 1 Read Op -code

   B_b = 0
   Spiout B_b , 1                                           ' Don't cares
   B_b = High(intpageadr)
   Spiout B_b , 1                                           ' Upper Part Of Internal Buffer Address
   B_b = Low(intpageadr)
   Spiout B_b , 1                                           ' Lower Part Of Internal Buffer Address
   Call Esf_spi_cs(0)
End Sub


'--------------------------------------------------------------------------------
'
' Function name : DF_BufferWriteStr
'
' Returns :  None
'
' Parameters : BufferNo -> Decides usage of either buffer 1 or 2
'     IntPageAdr -> Internal page address
'     No_of_bytes -> Number of bytes to be written
'     *BufferPtr -> address of buffer to be used for copy of bytes
'         from AVR buffer to dataflash buffer 1 (or 2)
'
' Purpose :  Copies one or more bytes to one of the dataflash
'     internal SRAM buffers from AVR SRAM buffer
'     pointed to by *BufferPtr
'
'--------------------------------------------------------------------------------
Sub Df_bufferwritestr(byval Bufferno As Byte , Byval Intpageadr As Word , Byval No_of_bytes As Word , Byref Bufferptr As Word)
   Local B_b As Byte

   Call Esf_spi_cs(1)
   If Bufferno = 1 Then                                     ' Read Byte From Buffer 1
      B_b = Buf1read                                        ' Buffer 1 Read Op -code
   Else
      B_b = Buf2read                                        ' Buffer 2 Read Op -code
   End If
   Spiout B_b , 1                                           ' Buffer 1 Read Op -code

   B_b = 0
   Spiout B_b , 1                                           ' Don't cares
   B_b = High(intpageadr)
   Spiout B_b , 1                                           ' Upper Part Of Internal Buffer Address
   B_b = Low(intpageadr)
   Spiout B_b , 1                                           ' Lower Part Of Internal Buffer Address

   Spiout Bufferptr() , No_of_bytes

   Call Esf_spi_cs(0)
End Sub



'--------------------------------------------------------------------------------
'
' Function name : Cont_Flash_Read_Enable
'
' Returns :  None
'
' Parameters : PageAdr  -> Address of flash page where cont.read starts from
'     IntPageAdr -> Internal page address where cont.read starts from
'
' Purpose :  Initiates a continuous read from a location in the DataFlash
'
'--------------------------------------------------------------------------------
Sub Cont_flash_read_enable(byval Pageadr As Word , Byval Intpageadr As Word)
   Local B_b As Byte , W_w As Word

   Call Esf_spi_cs(1)

   B_b = Contarrayread
   Spiout B_b , 1
   W_w = Pageadr                                            ' Upper Part Of Page Address
   B_b = 16 - Pagebits
   Shift W_w , Right , B_b
   Spiout W_w , 1                                           ' Dummy Write To Get Result

   W_w = Pageadr                                            ' Lower Part Of Page Address
   B_b = Pagebits - 8
   Shift W_w , Left , B_b
   Spiout W_w , 1

   B_b = 0
   Spiout B_b , 1                                           ' Perform 4 Dummy Writes
   Spiout B_b , 1                                           ' In Order To Intiate Dataflash
   Spiout B_b , 1                                           ' Address Pointers
   Spiout B_b , 1
   Call Esf_spi_cs(0)
End Sub

'-------------------------------------------------------------------------------
'  ESF_filelist  show filelist in ESF
'-------------------------------------------------------------------------------
Sub Esf_filelist()
' Structure of Filetable:
' &H5A <-- valid Filetable
' 1 Byte length filename|filename|3 Byte size|3 Bytes Startpos|
' 1 Byte length filename|filename|3 Byte size|3 Bytes Startpos|
' ...
' $00 <-- end of filetable
   Local Filesize As Dword , Filepos As Dword , Filname As String * 30 , Filenamelen As Byte
   Local Page As Word , Pagepos As Word , Valid_files As Byte       ', Count_pos As Dword
   Local Rx_byte As Byte , Ready As Byte , X As Byte

   Pagepos = 0
   Ready = 0

   Page = 513
   Call Df_pagetobuffer(1 , Page)

   Valid_files = Df_bufferreadbyte(1 , 0)
   Call Esf_check_pagepos(pagepos , Page)

   If Valid_files = &H5A Then
    Do
     Filenamelen = Df_bufferreadbyte(1 , Pagepos)
     Call Esf_check_pagepos(pagepos , Page)
     If Filenamelen = 0 Then
        Ready = 1
     End If
     If Ready = 0 Then
        Filname = ""
        For X = 1 To Filenamelen
          Rx_byte = Df_bufferreadbyte(1 , Pagepos)
          Filname = Filname + Chr(rx_byte)
          Call Esf_check_pagepos(pagepos , Page)
        Next

        Esf_file_len = 0
        Esf_file_len_1 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_len_2 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_len_3 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)

        Esf_file_start = 0
        Esf_file_start_1 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_start_2 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_start_3 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)

        Print #1 , Filname ; "  Size: " ; Str(Esf_file_len) ; "  Pos: " ; Str(esf_file_start)
     End If
   Loop Until Ready = 1
  End If
End Sub


Function Esf_find_file(byval Searchfile As String) As Byte
' Structure of Filetable:
' &H5A <-- valid Filetable
' 1 Byte length filename|filename|3 Byte size|3 Bytes Startpos|
' 1 Byte length filename|filename|3 Byte size|3 Bytes Startpos|
' ...
' $00 <-- end of filetable
   Local Filename As String * 50 , Filenamelen As Byte
   Local Page As Word , Pagepos As Word , Valid_files As Byte                    ' , Count_pos As Dword
   Local Rx_byte As Byte , Ready As Byte , X As Byte


   Pagepos = 0
   Ready = 0
   Esf_file_len = 0
   Esf_file_start = 0
   Esf_find_file = 0

   Page = 513
   Call Df_pagetobuffer(1 , Page)

   Searchfile = Ucase(searchfile)
   Valid_files = Df_bufferreadbyte(1 , 0)
   If Valid_files = &H5A Then
    Call Esf_check_pagepos(pagepos , Page)
    Do
     Filenamelen = Df_bufferreadbyte(1 , Pagepos)
     If Filenamelen = 0 Then
        Ready = 1
     End If
     If Ready = 0 Then
        Call Esf_check_pagepos(pagepos , Page)
        Filename = ""
        If Filenamelen > 50 Then Filenamelen = 50
        For X = 1 To Filenamelen
          Rx_byte = Df_bufferreadbyte(1 , Pagepos)
          Filename = Filename + Chr(rx_byte)
        Call Esf_check_pagepos(pagepos , Page)
        Next

        Esf_file_len = 0
        Esf_file_len_1 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_len_2 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_len_3 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)

        Esf_file_start = 0
        Esf_file_start_1 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_start_2 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)
        Esf_file_start_3 = Df_bufferreadbyte(1 , Pagepos)
        Call Esf_check_pagepos(pagepos , Page)

        Filename = Ucase(filename)
        If Filename = Searchfile Then
            Esf_find_file = 1
            Ready = 1
        Else
            Esf_file_len = 0
            Esf_file_start = 0
        End If
     End If
   Loop Until Ready = 1
   If Esf_find_file = 0 Then
      Esf_file_len = 0
      Esf_file_start = 0
   End If

  End If
End Function


Sub Esf_check_pagepos(byref Pagepos As Word , Byref Page As Word)
        Incr Pagepos
        If Pagepos > 255 Then
          Incr Page
          Pagepos = 0
          Call Df_pagetobuffer(1 , Page)
        End If
End Sub

0

18

Ещё один вариант работы с AT45DB DataFlash (тоже не удалось завестись , и по ходу этот код для Флешек с 256 и 512 байтовым секторм) кто разберется маякните и прошу прощения за корявые коменты (переводил с Китайского Гуглом , если кто-то грамотно подправит буду благодарен)

Код:
$regfile = "m64def.dat"
$crystal = 11059200
$baud = 9600                                                'set the baud rate for the first hardware UART.
$baud1 = 1200                                               'set the baud rate for the second hardware UART.
'----------------------------------------------------------------------------------------------------------------
$hwstack = 260                                              '60
$swstack = 260                                              '60
$framesize = 512                                            '110
'----------------------------------------------------------------------------------------------------------------
'$xramstart = &H1000
'$xramsize = &H8000
'$xa
'$waitstate
'----------------------------------------------------------------------------------------------------------------
'$lib "glcdKS108.lbx"                                      ' KS0108 поддержка LCD библиотека 
$lib "glcdKS108.lib"                                        ' KS0108 поддержка LCD библиотека 
'----------------------------------------------------------------------------------------------------------------
' настроить используемый вывод порта для I2C 
Config I2cdelay = 5                                         '5                                         ' default slow mode
Config Sda = Portd.1
Config Scl = Portd.0
' not needed since the pins are in the right state
 I2cinit
'----------------------------------------------------------------------------------------------------------------
'Инициализировать оборудование;SPI
Config Spi = Hard , Interrupt = Off , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1
Spiinit
Config Portb.0 = Output
Atdb161_cs Alias Portb.0
'--------------------------------------------------------------------------------------------------------------------------------------------------
'****************Конфигурация последовательного порта 1;
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'Config Serialin = Buffered , Size = 64
Config Serialout = Buffered , Size = 1
'****************Конфигурация последовательного порта 2;
Config Com2 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com2:" For Binary As #1                               '485Серийный номер устройства = # 1
'***************    
'----------------------------------------------------------------------------------------------------------------
'AT45DB161 SPI Функции и переменные памяти;
'----------------------------------------------------------------------------------------------------------------
Declare Sub Putspichar(byval Tx_data As Byte)
Declare Sub Wait_flash
Declare Sub Write_memory(byval Page_addr As Word , Byval Page_offset As Word , Byval Data_lenth As Word , Byval Head_lenth As Word)
Declare Sub Read_memory(byval Page_addr As Word , Byval Page_offset As Word , Byval Data_lenth As Word , Byval Head_lenth As Word)
Declare Sub Write_flash45db(byval Flash_addr As Long , Byval Lenth As Word)
Declare Sub Read_flash45db(byval Flash_addr As Long , Byval Lenth As Word)
'----------------------------------------------------------------------------------------------------------------
'
Dim Spi_read(256) As  Byte
Dim Spi_write(256) As  Byte
dim i as word
dim flash_addr1  as long
flash_addr1 =0  'memory space internal address
do

'TEST AT45DB161' READ AND WRITE
   
                                     'Write128 bytes
       Call Write_flash45db(flash_addr1 , 128)

                                'get 128 bytes
       Call Read_flash45db(flash_addr1 , 128)

WAIT 2

loop


end



'----------------------------------------------------------------------------------------------------------------
'AT45DB161 объем памяти;
'----------------------------------------------------------------------------------------------------------------
'Функция модуля: вывод одного байта через spi
'Параметры ввода: данные для вывода 
' Параметры экспорта : нет
' Описание процесса : отправьте данные в регистр отправки SPI , начните отправку , дождитесь завершения отправки , а затем сбросьте флаг завершения отправки
' Clear SPIF метод : первое чтение SPIF, а затем прочитать SPDR
'----------------------------------------------------------------------------------------------------------------
Sub Putspichar(byval Tx_data As Byte)

 Spdr = Tx_data                                             ' помещает данные в регистр передачи 

  While Spsr.7 = 0

  Wend                                                      ' Если SPIF = 1, означает, что операция передачи SPI (байта) завершена. 

End Sub

'-------------------------------------------------------------------------------
' Функция модуля : Ожидание Мигает пустой холостой ход
' Параметры входа : нет
' Параметры экспорта : нет
" Описание процесса : Отправить & H57 в флеш, читать возвращаемое значение регистра статуса , судит ли он занят , если он занят , продолжайте читать
' Отправить & h57 после , если нет нарастающего фронта CS , Flash было возвращено значение регистра состояния состояния
 '-------------------------------------------------------------------------------
Sub Wait_flash

   Local Status_reg As Byte                                 
  Status_reg = &H00                                         ' регистр статуса, подобный SPI 

  Atdb161_cs = 0
                                               ' Команда на начало передачи 
 Call Putspichar(&H57)

  While Status_reg.7 = 0

  Call Putspichar(&H00)
   Status_reg = Spdr
 Wend

   Atdb161_cs = 1

End Sub

'-------------------------------------------------------------------------------
'Функция модуля : Запись адрес определяет набор данных
' Входных параметров : адрес страницы , смещение страницы , первый адрес из данных, длина данных
' Параметры экспорта : нет
' Описание процесса :
' Прочитать указанную страницу основной памяти в buffer1   
' Записать данные для записи по адресу, указанному в buffer1   
' Buffer1 записывается в оперативную память указаны страницы
 '-------------------------------------------------------------------------------
Sub Write_memory(byval Page_addr As Word , Byval Page_offset As Word , Byval Data_lenth As Word , Byval Head_lenth As Word)

  Local I As Word , Temp As Word , Temp1 As Word , Tempchar As Byte

  Call Wait_flash()
   Atdb161_cs = 0

    ' Команда на начало передачи 
  Call Putspichar(&H53)                                     ' Прочитать указанную страницу основной памяти в buffer1 

  Temp = Page_addr
  Shift Temp , Right , 6                                    '  PutSPIchar ((uchar) (page_addr >> 6)); shift right 6 // адрес страницы PA11-PA6 
  Tempchar = Temp
 Call Putspichar(tempchar)


  Temp = Page_addr
  Shift Temp , Left , 2                                     '  PutSPIchar ((uchar) (page_addr << 2)); shift left 2 // адрес страницы PA5-PA0 
  Tempchar = Temp
 Call Putspichar(tempchar)



 Call Putspichar(&H00)                                      ' используется для генерации времени SCK 

   Atdb161_cs = 1

 Call Wait_flash()
   Atdb161_cs = 0                                           ' команда начать передачу 
 Call Putspichar(&H84)                                      ' Запишите данные для записи по адресу, указанному в buffer1   
 Call Putspichar(&H00)                                      ' 任意

  Temp = Page_offset
  Shift Temp , Right , 8                                    ' PutSPIchar ((uchar) (page_offset >> Cool); сдвиг вправо 8 // смещение страницы BA9-BA8 
  Tempchar = Temp
 Call Putspichar(tempchar)

  Temp = Page_offset                                        ' PutSPIchar ((uchar) (page_offset)); // смещение страницы BA7-BA0 
  Tempchar = Temp
 Call Putspichar(tempchar)


  While Data_lenth <> 0
     Tempchar = Spi_write(head_lenth)
      Call Putspichar(tempchar)                             ' запись данных 
    Incr Head_lenth
    Decr Data_lenth
  Wend

  Atdb161_cs = 1
   Call Wait_flash()
  Atdb161_cs = 0                                            ' команда начать передачу 
   Call Putspichar(&H83)                                    ' buffer1 записывается в основной памяти указаны страницы 

   Temp = Page_addr
   Shift Temp , Right , 6                                   ' Поместите SPIchar ((uchar) (АДРЕС СТРАНИЦЫ >> 6)) вправо , адрес 6 ' страницы PA11-PA6 
  Tempchar = Temp
  Call Putspichar(tempchar)

  Temp = Page_addr
  Shift Temp , Left , 2                                     ' Putspichar ((UCHAR) (PAGE ADDR << 2)) left 2 ' адреса страниц PA5-PA0 
  Tempchar = Temp
  Call Putspichar(tempchar)

 Call Putspichar(&H00)                                      ' используется для генерации времени SCK
  Atdb161_cs = 1

End Sub

'-------------------------------------------------------------------------------
' Функция модуля :  указана адрес чтении набора
' Параметры Въездные : страница адрес , страница смещения , чтение адреса записи данных , чтение данных длина
' Параметры экспорта : нет
' Описание процесса :
' Прочитать указанную страницу основной памяти в buffer1   
' Прочитать данные необходимой длины с адреса, указанного в buffer1 
 '-------------------------------------------------------------------------------
Sub Read_memory(byval Page_addr As Word , Byval Page_offset As Word , Byval Data_lenth As Word , Byval Head_lenth As Word)

  Local I As Word , Temp As Word , Temp1 As Word , Tempchar As Byte


 Call Wait_flash()
    Atdb161_cs = 0                                          ' команда начать передачу
 Call Putspichar(&H52)                                      ' Считывание данных из основной памяти 

   Temp = Page_addr
  Shift Temp , Right , 6                                    ' Поместите SPIchar ((uchar) (АДРЕС СТРАНИЦЫ >> 6)) вправо , адрес 6 ' страницы PA11-PA6  
  Tempchar = Temp
 Call Putspichar(tempchar)


  Temp = Page_addr
  Shift Temp , Left , 2

   Temp1 = Page_offset
  Shift Temp1 , Right , 8                                   ' PutSPIchar ((uchar) ((page_addr << 2) | (page_offset >> Cool)) ' Смещение страницы BA9-BA8 
  Temp = Temp Or Temp1
  Tempchar = Temp
 Call Putspichar(tempchar)

  Temp = Page_offset
  Tempchar = Temp
 Call Putspichar(tempchar)                                  ' Внутреннее смещение BA7-BA0 

 Call Putspichar(&H00)
 Call Putspichar(&H00)
 Call Putspichar(&H00)
 Call Putspichar(&H00)

  While Data_lenth <> 0

     Call Putspichar(&H00)                                  ' используется для генерации времени SCK        
        While Spsr.7 = 0
        Wend
     Spi_read(head_lenth) = Spdr
'        Printbin Spdr
    Incr Head_lenth
    Decr Data_lenth
  Wend


  Atdb161_cs = 1

 End Sub
'-------------------------------------------------------------------------------

Sub Write_flash45db(byval Flash_addr As Long , Byval Lenth As Word)

  Local Page_addr As Word , Page_offset As Word , Data_lenth As Word , Head_lenth As Word
  Local Temp As Word , Flash_tmp As Long

   Flash_tmp = Flash_addr / 512
   Page_addr = Flash_tmp

   Flash_tmp = Flash_addr Mod 512
   Page_offset = Flash_tmp

   Head_lenth = 1

  While Lenth <> 0

     If Lenth <= 511 Then
       Data_lenth = Lenth
     Else
       Data_lenth = 512 - Page_offset
     End If
         Lenth = Lenth - Data_lenth

      Call Write_memory(page_addr , Page_offset , Data_lenth , Head_lenth)

      Page_addr = Page_addr + 1
      Page_offset = 0
      Head_lenth = Head_lenth + Data_lenth

  Wend


End Sub

'-------------------------------------------------------------------------------
Sub Read_flash45db(byval Flash_addr As Long , Byval Lenth As Word)

  Local Page_addr As Word , Page_offset As Word , Data_lenth As Word , Head_lenth As Word
  Local Temp As Word , Flash_tmp As Long

   Flash_tmp = Flash_addr / 512
   Page_addr = Flash_tmp

   Flash_tmp = Flash_addr Mod 512
   Page_offset = Flash_tmp
   Head_lenth = 1

  While Lenth <> 0

     If Lenth <= 511 Then
       Data_lenth = Lenth
     Else
       Data_lenth = 512 - Page_offset
     End If

         Lenth = Lenth - Data_lenth

      Call Read_memory(page_addr , Page_offset , Data_lenth , Head_lenth)

      Page_addr = Page_addr + 1
      Page_offset = 0
      Head_lenth = Head_lenth + Data_lenth

  Wend

End Sub

'-------------------------------------------------------------------------------

Отредактировано Sonic Blast (2021-11-30 02:00:14)

0


Вы здесь » Программирование ATMEL в BASCOM. » Схемы » Программатор Dataflash AT45DBxx