Проблем с програмирането на Aardvark I2C VB API е двусмислен по отношение на функцията WRITE

Без да навлизаме дълбоко в основата на проекта, ние създадохме BIN файл от някои стандартни текстови полета, чрез използването на много креативно кодиране. Няма проблеми - работи перфектно. След това записваме този BIN файл в EEPROM чип с помощта на програмист, наречен Aardvark. Има собствена програма за това, наречена FlashCenter, но също така предлага API. Тъй като програмирането на този чип е било пречка за някои от служителите, ние бихме искали да включим тази функционалност в нашия генератор на BIN файлове (т.е. - BIN файлът се генерира, съхранява и незабавно се записва в EEPROM).

Единственият проблем е, че това е невероятно напреднало за моите ограничени познания и не мога да разбера как да предам данните от BIN файла към EEPROM с помощта на VB кода, предоставен от Aardvark API. Надявам се, че нямате нищо против, ако предоставя примерен код и се надявам, че някой може да ми помогне да разбера това.

Това е примерният VB код, предоставен в API на Aardvark: Код:

'==========================================================================
' (c) 2004-2009  Total Phase, Inc.
  '--------------------------------------------------------------------------
' Project : Aardvark Sample Code
' File    : aai2c_eeprom.bas
   '--------------------------------------------------------------------------
' Perform simple read and write operations to an I2C EEPROM device.
'--------------------------------------------------------------------------
' Redistribution and use of this file in source and binary forms, with
' or without modification, are permitted.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
' "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
' LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
' FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
' COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
' INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
' BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
' CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
' LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
' ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
' POSSIBILITY OF SUCH DAMAGE.
'==========================================================================
Imports TotalPhase

Module aai2c_eeprom

    '==========================================================================
' CONSTANTS
'==========================================================================
Const I2C_BITRATE As Integer = 100  'kHz
Const I2C_BUS_TIMEOUT As UShort = 150  'ms
Const I2C_DEVICE As UShort = &H54


'==========================================================================
' MAIN PROGRAM
'==========================================================================
Sub aai2c_eeprom_run(ByRef sampletext As Windows.Forms.TextBox)
    Dim handle As Long

    handle = AardvarkApi.aa_open(0)
    If (handle <= 0) Then
        sampletext.Text &= "Unable to open Aardvark device on port 0" & vbCrLf
        sampletext.Text &= "Error code = " & handle & vbCrLf
        Exit Sub
    End If

    ' Ensure that the I2C subsystem is enabled
    Call AardvarkApi.aa_configure(handle, AardvarkConfig.AA_CONFIG_SPI_I2C)

    ' Enable the I2C bus pullup resistors (2.2k resistors).
    ' This command is only effective on v2.0 hardware or greater.
    ' The pullup resistors on the v1.02 hardware are enabled by default.
    Call AardvarkApi.aa_i2c_pullup(handle, AardvarkApi.AA_I2C_PULLUP_BOTH)

    ' Power the board using the Aardvark adapter's power supply.
    ' This command is only effective on v2.0 hardware or greater.
    ' The power pins on the v1.02 hardware are not enabled by default.
    Call AardvarkApi.aa_target_power(handle, AardvarkApi.AA_TARGET_POWER_BOTH)

    ' Set the bitrate
    Dim bitrate As Long
    bitrate = AardvarkApi.aa_i2c_bitrate(handle, I2C_BITRATE)
    sampletext.Text &= "Bitrate set to " & bitrate & " kHz" & vbCrLf

    ' Set the bus lock timeout
    Dim bus_timeout As Long
    bus_timeout = AardvarkApi.aa_i2c_bus_timeout(handle, I2C_BUS_TIMEOUT)
    sampletext.Text &= "Bus lock timeout set to " & bus_timeout & " ms" & vbCrLf

    ' Write the offset and read the data
    'Dim offset(15) As Byte
    Dim offset() As Byte = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}  'THIS IS JUST A TEST STRING, but doesn't seem to ever get written
    Dim data(128) As Byte
    Dim result As Long
    Dim k As String = String.Empty

    offset(0) = 1
    Call AardvarkApi.aa_i2c_write(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_STOP, 128, offset)


    result = AardvarkApi.aa_i2c_read(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_FLAGS, 128, data)

    If result <= 0 Then
        sampletext.Text &= "i2c read error" & vbCrLf
    Else
        Dim i As Integer
        sampletext.Text &= "Read data bytes:"
        For i = 0 To 127
            k &= System.Convert.ToChar(data(i)).ToString
        Next
        sampletext.Text &= k
        sampletext.Text &= vbCrLf
    End If

    ' Close the device and exit
    AardvarkApi.aa_close(handle)
End Sub
End Module

И по-конкретно работа с функцията "write":

Call AardvarkApi.aa_i2c_write(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_STOP, 128, offset)

...ето какво определят документите за поддръжка:

Главно писане (aa_i2c_write)

      int aa_i2c_write (Aardvark         aardvark,
                        aa_u16           slave_addr,
                        AardvarkI2cFlags flags,
                        aa_u16           num_bytes,
                        const aa_u08 *   data_out);

Запишете поток от байтове към подчиненото I2C устройство. Аргументи aardvark манипулатор на адаптер Aardvark slave_addr подчиненото устройство, от което да се чете, флагове специални операции, както е описано в раздела "Бележки", num_bytes броят байтове за запис (максимум 65535) data_out указател към данни Връщана стойност Брой записани байтове.

Специфични кодове за грешка AA_I2C_WRITE_ERROR Възникна грешка при четене на потвърждението от адаптера Aardvark. Това най-вероятно е резултат от комуникационна грешка. Подробности За обикновено 7-битово адресиране, долните 7 бита на slave_addr трябва да съответстват на подчинения адрес. Най-горните битове се игнорират. Подсистемата Aardvark I2C ще сглоби адреса заедно с R/W бита след грабване на шината. За 10-битово адресиране долните 10 бита на адрес трябва да съответстват на подчинения адрес. След това адаптерът Aardvark ще сглоби адреса в правилния формат, както е описано в спецификацията на Philips. Има ограничение, че максимум само 65534 байта могат да бъдат записани в една транзакция, ако се използва 10-битов режим на адресиране.

Slave_addr 0x00 е запазен в спецификацията на протокола I2C за общо адресиране на повиквания. I2C подчинените устройства, които са разрешени да отговарят на общо повикване, ще потвърдят този адрес. Общото повикване не се третира специално в Aardvark I2C master. Потребителят на този API може ръчно да сглоби първия байт данни, ако се изисква функцията за програмиране на хардуерен адрес с общо извикване.

Всъщност е възможно да запишете 0 байта на подчинено устройство. Подчиненият ще бъде адресиран и след това условието за спиране ще бъде незабавно предадено от адаптера Aardvark. Към подчинения не се изпращат байтове, така че аргументът за данни се игнорира (т.е. може да бъде 0 или да сочи към невалидна памет).

Ако броят на записаните байтове е нула, възможни са следните условия.

Исканият роб не беше намерен. Исканият роб е в автобуса, но отказва да признае адреса си. Адаптерът Aardvark не успя да завземе шината поради наличието на друг I2C мастер. Тук арбитражът е загубен по време на фазата на адресиране на подчинено, резултатите могат да бъдат непредвидими. Подчиненото устройство беше адресирано и към него не бяха записани байтове, тъй като num_bytes беше зададен на 0. Броят на записаните байтове може да бъде по-малък от заявения брой байтове в транзакцията поради следните възможности.

Адаптерът Aardvark губи шината по време на предаването на данни поради наличието на друг I2C master. Подчиненото устройство отказва приемането на повече байтове.


Така че ясно трябва да предам байтов масив, но не съм напълно сигурен как да кодирам BIN файла, така че да може да бъде предаден. Има много преобразувания на това ниско ниво, за които съм облачен... преобразуването на нещата в низове, или в байтове, или в char, и т.н. Играл съм си с тях достатъчно, за да знам, че в някои случаи стигате до ASCII, или шестнадесетичен и т.н... но не съм сигурен какво е необходимо в този случай, за да работи.

За да направя това още по-просто, бих искал да предам НЕЩО на EEPROM. Без значение какво променям в този код, просто не мога да накарам нищо да запиша в EEPROM. Или може би е така и просто не го виждам. Когато стартирате този код, функцията "четене" генерира изхода "12345678910111213141516". В момента има 128 байта фиктивно съдържание, запълващо EEPROM, и 1-16 НЕ са там.

Ако НЯКОЙ може да ме вкара в правия път, ще бъда изключително оценен!!!! Благодаря ти.


person prosper50    schedule 06.03.2015    source източник


Отговори (3)


Правилното програмиране и четене на вашия EEPROM зависи от протокола, който вашият EEPROM използва и как е физически конфигуриран на платката, която се програмира.

Най-вероятно той използва протокола Phillips, обсъден в документите на Aardvark тук. Примерният код има някои вградени константи и предположения. Първото предположение е, че вашата I2C мрежа работи на 100KHz, EEPROM е подчинен и е на адрес 0x54 (Const I2C_DEVICE As UShort = &H54 от примерния код).

Адресиране

I2C може да използва 7-битово или 10-битово адресиране на устройство (шина). Най-значимите битове (MSB) се използват за идентифициране на типа устройство. EEPROMS имат тип устройство 1010 (0x8). Това заема 4-те MSB в байта на високия адрес. Много устройства имат един или повече извода, които се използват за управление на I2C адреса, който използва. Например, ако EEPROM е 4K Atmel AT24C04C устройство с щифт A1 ниско (заземен) и щифт A2, изтеглен високо (+Vcc), то ще бъде адресирано чрез (в двоичен) 101010XY. Където X=0 за страница 0 на устройството и 1 за страница 1 и Y=1 за четене на устройството и Y=0 за запис на устройството. Адресите на устройството ще бъдат както следва:

  • 0xA8 = write page 0
  • 0xAC = write page 1
  • 0xA9 = read page 0
  • 0xAB = read page 1

Това, което ни интересува, са адресните линии на чипа (A2 и A1), комбинирани с адресното пространство в EEPROM (0 до 512 за 4Kbit EEPROM). За съжаление, тъй като битът R/_W е бит 0 от байта на адреса на шината, а битът на страницата е бит 1 от байта на адреса на шината. Така че адресното пространство на EEPROM не е съседно от гледна точка на API. Така че физическият адрес на шината винаги е един от горните. Когато адресът на шината се комбинира с друг байт адрес на паметта, това указва какво всъщност четем или записваме в определен EEPROM на I2C шината.

Памет на устройството

Както беше отбелязано по-горе, EEPROMS може да има различни страници от паметта. Размерите на страницата са специфични за устройството. AT24C04C има 8 страници по 16 байта на страница. В този пример адресът в една страница се определя от 4-те LSB (най-малко значими бита) на байта на адреса.

Четене на данни

Можете да четете данни байт по байт (произволно четене) или последователно. За да получите байт данни:

  1. Напишете на устройството от кой адрес искате да четете
  2. Прочетете байта от устройството

Устройството има вътрешен брояч на адреси. Ако искате да извършите последователно четене на повече от един байт, просто продължете да четете от устройството и то ще продължи да изпраща следващия байт в паметта си. Броячите на адреси на повечето устройства се преобръщат, така че трябва да внимавате да не поискате повече данни, отколкото устройството действително има, или това може да ви даде неочаквани резултати.

Сигнали за стоп и старт

В началото на комуникацията от I2C главен към подчинен(и) главният потвърждава контрола на шината, като изтегля линията SDA (серийни данни A) ниско, докато линията SCL (часовник) е висока. (По време на нормални трансфери на данни SDA не трябва да се променя, докато SCL е високо, но може да се промени, докато SCL е ниско). Главният сигнализира край на контрола, когато повишава SDA, докато SCL е високо. Това има последици за начина, по който пишете кода и задавате флагове за четене и запис.

Пример: Прочетете първите 32 байта

  1. Пишете на адрес 0xA8: данни=0x00
  2. Прочетете от адрес 0xA9
  3. Повторете стъпка 2 (още 31 пъти)

В код това може да изглежда нещо като:

Const DEV0_READ__PAGE0 As Integer = &HA9
Const DEV0_WRITE_PAGE0 As Integer = &HA8
Dim startAddress() As Byte = New Byte() {0}
Dim data() as Byte = new Byte(32)
Dim writeResult As Integer = _
    AardvarkApi.aa_i2c_write( _
        handle, DEV0_WRITE_PAGE0, _
        AardvarkI2cFlags.AA_I2C_NO_STOP, 1, startAddress)
Dim readResult As Integer = _
    AardvarkApi.aa_i2c_read( _
        handle, DEV0_READ__PAGE0,
        AardvarkI2cFlags.AA_I2C_NO_FLAGS, 32, data)
If readResult <> 32 Then
    Console.WriteLine("Read Error {0} bytes requested, {1} bytes received", 32, readResult)
Else
    For i As Integer = 0 to 31
        Console.Write(data(i).ToString() & ", ")
    Next
End If

Трябва да прочетете ръководството на EEPROM, за да разберете последователността от четения и записи, включени за извършване на дадена операция и как да посочите адреса на шината на устройството и адреса на паметта в EEPROM.

person labradore    schedule 08.04.2015

Устройството Nusbio улеснява четенето/записването на EEPROM от C# или VB.NET. Вижте техните проби в github

https://github.com/madeintheusb/Nusbio.Samples/tree/master/CS/MadeInTheUSB.Nusbio.SPI.EEPROM_25AA1024

https://github.com/madeintheusb/Nusbio.Samples/tree/master/CS/MadeInTheUSB.Nusbio.I2C.EEPROM_24LC256

using (var nusbio = new Nusbio(serialNumber))
{
var _eeprom = new EEPROM_25AA1024(
nusbio: nusbio, clockPin: NusbioGpio.Gpio0,mosiPin: NusbioGpio.Gpio1,
misoPin: NusbioGpio.Gpio2, selectPin: NusbioGpio.Gpio3
);
byte[] buf;

var r = _eeprom.ReadPage(p * _eeprom.PAGE_SIZE, _eeprom.PAGE_SIZE);
if (r.Succeeded)
{
    buf = r.Buffer;
}

}

person Frederic Torres    schedule 10.12.2016

Можете да напишете скрипт, който увеличава адреса на устройството след запис във всеки квадрант, т.е. 64 KB. Във вашия случай 0x54 ще бъде увеличен до 0x55 и т.н. Изчислете броя на квадрантите въз основа на общия размер на EEPROM. Въпреки това байтовият адрес ще бъде един и същ за всеки квадрант, т.е. 0x0000 до 0xFFFF

person RAHUL    schedule 26.02.2021