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

Не углубляясь в предысторию проекта, мы создали файл BIN из некоторых стандартных текстовых полей, используя очень творческое кодирование. Проблем нет - он работал отлично. Затем мы записываем этот BIN-файл в микросхему EEPROM с помощью программатора под названием Aardvark. Для этого у него есть своя программа под названием FlashCenter, но также есть API. Поскольку программирование этого чипа было препятствием для некоторых сотрудников, мы хотели бы включить эту функцию в наш генератор файлов BIN (т.е. файл BIN создается, сохраняется и немедленно записывается в EEPROM).

Единственная проблема заключается в том, что это невероятно продвинуто для моих ограниченных знаний и я не могу понять, как передать данные файла BIN в EEPROM, используя код VB, предоставленный API Aardvark. Надеюсь, вы не возражаете, если я предоставлю образец кода, и, надеюсь, кто-нибудь поможет мне разобраться в этом.

Это образец кода 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

И конкретно о функции "записи":

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 должны соответствовать адресу slave. Самые верхние биты игнорируются. Подсистема Aardvark I2C соберет адрес вместе с битом чтения / записи после захвата шины. Для 10-битной адресации младшие 10 битов addr должны соответствовать адресу подчиненного устройства. Затем адаптер Aardvark преобразует адрес в правильный формат, как описано в спецификации Philips. Существует ограничение, заключающееся в том, что за одну транзакцию можно записать максимум 65534 байта, если используется 10-битный режим адресации.

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

Фактически возможно записать 0 байтов на ведомое устройство. Будет выполнено обращение к ведомому устройству, а затем адаптер Aardvark немедленно передаст условие остановки. Байты не отправляются ведомому устройству, поэтому аргумент данных игнорируется (т.е. он может быть 0 или указывать на недопустимую память).

Если количество записанных байтов равно нулю, возможны следующие условия.

Запрошенный ведомый не найден. Запрошенное ведомое устройство находится на шине, но отказывается подтвердить свой адрес. Адаптеру Aardvark не удалось захватить шину из-за наличия другого мастера I2C. Здесь арбитраж был потерян во время фазы адресации ведомого, результаты могут быть непредсказуемыми. Подчиненному устройству был адресован адрес, и в него не было записано ни одного байта, поскольку num_bytes был установлен в 0. Количество записанных байтов может быть меньше запрошенного количества байтов в транзакции из-за следующих возможностей.

Адаптер Aardvark теряет шину во время передачи данных из-за наличия другого мастера I2C. Подчиненное устройство отказывается принимать больше байтов.


Итак, очевидно, что мне нужно передать массив байтов, но я не совсем уверен, как кодировать файл BIN, чтобы его можно было передать. На этом низком уровне есть много преобразований, о которых я не уверен ... преобразование вещей в строки, байты, символы и т. Д. Я поигрался с ними достаточно, чтобы знать, что в некоторых случаях вы получаете ASCII, шестнадцатеричный код и т. Д., Но я не уверен, что в этом случае нужно, чтобы он работал.

Чтобы сделать это еще проще, я хотел бы передать в EEPROM ВСЕ. Независимо от того, что я изменяю в этом коде, я просто не могу ничего записать в EEPROM. Или, может быть, это так, а я просто не вижу этого. Когда вы запускаете этот код, функция «чтения» генерирует вывод «12345678910111213141516». В настоящее время 128 байтов фиктивного содержимого заполняют EEPROM, а 1–16 байтов НЕТ.

Если КТО-ТО сможет направить меня на правильный путь, это будет очень признательно !!!! Спасибо.


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


Ответы (3)


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

Скорее всего, он использует протокол Phillips, описанный в документации Aardvark здесь. В примере кода есть некоторые встроенные константы и предположения. Первое предположение заключается в том, что ваша сеть I2C работает на частоте 100 кГц, EEPROM является ведомым устройством и находится по адресу 0x54 (Const I2C_DEVICE As UShort = &H54 из примера кода).

Обращение

I2C может использовать как 7-битную, так и 10-битную адресацию устройства (шины). Старшие биты (MSB) используются для определения типа устройства. EEPROMS имеют тип устройства 1010 (0x8). Это занимает 4 старших бита в старшем байте адреса. Многие устройства имеют один или несколько контактов, которые используются для управления используемым им адресом 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 младшими битами (младшие значащие биты) байта адреса.

Чтение данных

Вы можете читать данные по байтам (произвольное чтение) или последовательно. Чтобы получить байт данных:

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

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

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

В начале обмена данными между ведущим устройством I2C и ведомым (-ми) ведущее устройство устанавливает контроль над шиной, подтягивая линию SDA (последовательные данные A) к низкому уровню, в то время как линия SCL (часы) имеет высокий уровень. (Во время нормальной передачи данных SDA не должен изменяться при высоком уровне вероятности нежелательной почты, но может изменяться при низком уровне вероятности нежелательной почты). Мастер сигнализирует об окончании управления, когда поднимает SDA при высоком уровне SCL. Это влияет на то, как вы пишете код и указываете флаги для чтения и записи.

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

  1. Запись по адресу 0xA8: data = 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 КБ. В вашем случае 0x54 будет увеличен до 0x55 и так далее. Рассчитайте количество квадрантов на основе общего размера EEPROM. Однако байтовый адрес будет одинаковым для каждого квадранта, то есть от 0x0000 до 0xFFFF

person RAHUL    schedule 26.02.2021