Язык LPH (т.е.
Языг Лоха и Лопуха) разработан
специально для описания
низкоуровневых протоколов
обмена с различными
устройствами. Рассмотрим
реализацию языка HPL в
трансляторе программатора Orange.
Cимволом (*) обозначены
примеры в данном документе.
Cимволом (W) обозначены
операторы и команды,
поддерживаемые только Windows
версией.
Символ ';' является признаком
комментария - конец строки
начиная с этого символа не
обрабатывается. Все пробелы
внутри текста удаляются, за
исключением текстовых строк.
Ключевые слова пишутся только
в верхнем регистре (большими
буквами).
- Числа. Числа могут
задаваться в двоичном,
десятичном и
шестнадцатеричном
формате:
(*) 1234 - десятичная
константа
(*) 010101B - двоичная
(*) 0x1234 или 01234H -
шестнадцатеричная.
- Строки. Текстовой строкой
является
последовательность
символов, заключенных в
двойные кавычки (*) "Test"
Пробелы внутри строк не
удаляются. При
необходимости
использования символа "
внутри самой строки, он
заменяется на две простые
кавычки: ' '.
- Адрес. Ключевое
слово ADR содержит
текущее значение
адресного регистра (32
разряда), по которому
выполняется чтение/запись
данных. Для адресного
регистра могут
использоваться операции
установки (только в
пользовательских секциях)
и инкремента (в секциях
блочного чтения и записи)
- Данные. Для
доступа к данным в буфере
по текущему адресу
используется ключевое
слово DATA. Данные
доступны пословно (8 или 16
бит в зависимости от
установленного типа
памяти) или поразрядно.
- Регистры. Для
выполнения математических
и логических операций,
описания констант и
хранения данных можно
использовать 16 (В Windows
версии 32) 32-разрядных
регистров R0...R9,RA...RF.
Регистры R0...R9
универсальные, регистры RA...RF
специального назначения.
Через них передаются
пераметры:
RA - передача параметров
RB - размер блока
чтения/записи (из cfg)
RC - адрес текущей
области
RD - номер области для
микросхем, имеющих
несколько областей памяти
(например, для
микроконтроллеров).
RE - глобальный код
операции (1-READ,2-VERIFY,3-WRITE,4-USER)
RF - полный размер
памяти (из cfg).
Параметры устанавливаются
автоматически перед
запуском секции. Если
значение, передаваемое
специальным регистром не
используется, он может
использоваться как
универсальный внутри
секций. Формат объявления
регистров дан ниже
Доступ к регистрам
специального назначения
возможен также через
символьные имена:
$SIZE - полный размер
памяти (из cfg),
$BLOCKSIZE - размер блока
чтения/записи (из cfg),
$VERIFY - режим сравнения (0
- отключен),
$CDELAY - задержка
(эквивалентна CDELAY),
$WDELAY - задержка записи,
$AREA - номер области
памяти,
$VERSION - версия hardware и
software.
Для Windows версии
рекомендуется
использовать символьные
имена.
Описание
протокола состоит из
нескольких секций, основными
являются три: начальная, [READ]
- чтение слова и [WRITE] -
записи слова.
Кроме этого, дополнительно
можно использовать следующие
секции:
[SETUP] - начальная
установка, вызывается
однократно при загрузке модуля
[INIT] - инициализация,
вызывается однократно перед
всеми операциями.
[WRITEINIT] - инициализации
записи, вызывается один раз
перед началом записи EEPROM.
[WRITEEND] - завершение записи,
вызывается один раз после
записи всех слов EEPROM.
[READBLOCK] - Чтение блока
[WRITEBLOCK] - Запись блока
[END] - завершение операции,
вызывается один раз для любой
операции.
При
необходимости могут быть
описаны дополнительные
пользовательские секции,
которые добавляются в меню под
своим именем. Их названия также
записываются в скобках [].
При использовании пробелов
имена следует дополнительно
заключать в кавычки:
(*)["Test 1"]
Секция с именем [---] служит для
использования в качестве
разделителя в меню и не
вызывается (W).
Можно использовать
локальные секции (функции). Для
описания функций перед именем
добавляется символ '_' :
(*) [_START]
Функции должны
быть описаны в модуле до их
использования. Вызов функции
осуществляется по имени:
(*) _START.
Передача
параметров возможна с
использованием регистров.
Разрешено использовать внутри
функций вызовы других функций.
Не рекомендуется
использование рекурсивных
вызовов.
Секции чтения и
записи вызываются при
выполнении операций Read и Write
для каждого слова.
Порядок
вызова секций в режиме чтения:
[INIT]
FOR (ADR=0,ADR<SIZE;ADR++{
[READ]
}
[END]
Порядок
вызова секций в режиме записи:
[INIT]
[WRITEINIT]
FOR (ADR=0,ADR<SIZE;ADR++{
[WRITE]
IF (Проверка записи)
[READ]
}
[WRITEEND]
[END]
Порядок
вызова для пользовательских
команд:
[INIT]
[USERSECTION]
[END]
Измение ADR внутри
секции не меняет глобального
значения.
В начальной секции
описываются:
- Входные и
выходные сигналы для
подключения к EEPROM (pins):
(*) PINO=SCL,0 - Выход, SCL - имя
сигнала, 0 - номер бита для
драйвера
(*) PINI=SDA,1 - Вход, SDA - имя
сигнала, 1 - номер бита для
драйвера
Входные и выходные сигналы
могут иметь одинаковые
имена. Имена должны быть не
длиннее восьми символов.
Имена не могут совпадать с
зарезервированными
ключевыми словами: "PINO",
"PINI", "BUSO",
"BUSI", "CDELAY",
"SOCKET", "CONST",
"REG", "GET",
"LOOP", "ADR",
"DATA", "MARK",
"POWER", "VCC",
"VPP". Символ # перед
именем является признаком
инверсии сигнала:
(*) PINO=#DTA,0
Дополнительно можно
указать реальный вывод
микросхемы, к которому
подключен сигнал:
(*) PINO=SDA,1,5
Это необходимо для
создания графического
изображения микросхем,
подключаемых через
адаптеры.
- Задержка после
каждой операции установки
пина (в микросекундах):
(*) CDELAY=10
Позволяет регулировать
скорость обмена. Реальные
задержки могут получаются
насколько больше заданных.
- Номер панельки
для установки EEPROM (по схеме
Orange-1)
(*) SOCKET=1
Если параметр SOCKET не
указан, он считается
равным 0. Можно создавать
свои новые Socket, но для того,
чтобы условное
графическое изображение
микросхемы отображалось в
окне Chip Info, таблица выводов
должна быть внесена в
драйвер или описана в
модуле.
Нумерация панелек
условная, соответствует
схеме Orange1:
1 I2C
2 MicroWire
3 SDA2506
4 SPI
5 NVM3060
6 S2100R
7 AT17XXX
8 M35080
В программаторах Orange4,
Orange-Omega трансляция номеров
выводов для заданного Socket
производится в драйвере
автоматически.
- Дополнительная
информация о модуле,
которая отображается в
нижнем окне. Не более одной
строки
(*) INFO="Новый модуль"
- Дополнительный
справочный файл
(вызывается из меню).
Рекомендуемый формат
файла - chm. (W).
(*) INFOFILE="megahelp.chm"
- Общее число
выводов в корпусе EEPROM (по
умолчанию 8)
(*) ALLPINS=14
- Объявления
регистров, доступных для
просмотра и
редактирования через меню
(Buffer->Registers). Имена
регистров не должны
совпадать. Если регистры
используются локально
внутри секций, объявлять
их не нужно.
(*) R0=Protect - где
"Protect" - имя регистра
После имени регистра через
запятую может быть указан
тип (режим отображения
значения) регистра: H - hex, D -
Dec, B - Bin, (W) L - List (W) C - CheckBox.
Если тип набран в нижнем
регистре, он не
отображается в окне
редактирования.
(*) R1=CODE,h
Для типов H,D,B,C
дополнительно может быть
указано число
отображаемых знаков:
(*) R2=FLAGS,B8
(*) R3=Box,C4
Для типа L добавляется
список текстовых строк.
Значение регистра
соответствует порядковому
номеру выбранной строки
начиная с 0.
(*) R0=Mode,L,On,Off
- POWER - режим
управления питанием:
1 - автоматическое
включение/выключение
0 - управление из модуля.
Все остальные
секции имеют одинаковый формат
записи. в одной строке может
быть описано несколько
инструкций, между собой они
разделяются запятыми.
Краткое описание
инструкций приведено ниже:
- Установка пина
константой, битом данных,
адреса или регистра:
(*) SDA=1
(*) SDA=DATA[2]
(*) SCL=ADR[3]
(*) PIN=R2[3]
- Проверка
текущего состояния пина
(линий ввода) или бита
регистра R0-R7
(*) DAT?1
(*) R2[4]?0
или всего регистра:
(*) R4?0x1234
Если
после операции сравнения в
скобках {} описан блок
инструкций, то он
выполняется при равенстве
бита(регистра) и константы,
иначе выполняется
инструкция следующая за
скобками. Если такой блок
не описан, при
несовпадении проверяемого
значения выполнение
операции прерывается с
выводом сообщения "Error:
Chip not respond!" и номером
строки HPL файла, на котором
произошла остановка.
(*) R2[4]?0 {P1=0}, P2=1
Если 4 бит регистра R2
равен 0, то выполняется
инструкция P1=0, а потом P2=1,
если бит равен 1 - то сразу P2=1
Если перед
сравниваемым числом стоит
символ !, то условие
меняется на
противоположное. (Блок
выполняется при
несовпадении значений).
(*) R2?!1234H {P1=0}
Если R2 не равен 1234H, то
выполняется инструкция P1=0,
если R2 = 1234H,
выполняется следующая
инструкция.
- Установка
константы. Значения
констант должны лежать в
пределах 0...65535.
(*) CONST=159
- Операции с
регистрами.
- Операции
присвоения
(копирования):
Регистр-регистр (*) R2=R5
Регистр-данные (*) R2=DATA
Данные-регистр (*) DATA=R3
Данные-число (*) DATA=0x45
Разрядность данных в
зависимости от
установленного типа
микросхемы составляет
8 либо 16 бит.
- Арифметические
и логические операции
(В операциях может
участвовать константа
или другой регистр):
установка
"=" (*) R0=356H
сложение
"+" (*) R0=+123 ; R0=R0+123
вычитание
"-" (*) R0=-R1 ; R0=R0-R1
умножение
"*" (*) R0=*R1 ; R0=R0*R1
деление
"/" (*) R0=/5 ; R0=R0/5
взятие
остатка "%" (*) R0=%10
; R0=R0%10
циклический
сдвиг ">>",
"<<" (*) R0=>>1
; сдвиг R0 вправо на
1 разряд (бит 0
переносится в бит 31,
бит 1 - в 0, бит 2 - в 1 и
т.д....)
Логическое И
- AND "&" (*) R0=*R2
; R0=R0 and R2
Логическое
ИЛИ - OR "|" (*) R0=|R2
; R0=R0 or R2
Исключающее
ИЛИ - XOR "^" (*) R0=^R2
; R0=R0 xor R2
В
операциях деления и
взятия остатка
запрещено
использовать
константу 0 либо
регистр, содержащий 0!
3) Битовые
операции с регистрами
(*) R0[R1]=1 - бит
регистра R0, равный R1
установить в 1
- LOOP - Циклы.
Переменная циклов может
быть 3 видов: адрес, данные
чтения/записи и константа.
Кроме того может быть
описан универсальный цикл,
без указания переменной, в
этом случае доступ
осуществляется через
счетчик (индекс) цикла I.
Универсальные циклы могут
быть вложенными, во
внутреннем цикле
непосредственно доступен
только счетчик
внутреннего цикла. Для
универсальных циклов
границы могут быть также
заданы через регистры. Для
совместимости с будущими
версиями рекомендуется
использовать только
универсальные циклы!
Константа должна
быть задана до начала
цикла с помощью инструкции
CONST Границы цикла
должны лежать в пределах:
0...32767 - для универсальных
циклов
0...32767 - для циклов CONST
0...1023 - для циклов DATA
0...31 - для циклов ADR
При выполнении кода для
универсальных циклов не
контролируется выход
индексов за пределы
реального размера DATA, ADR
и CONST.
Скобки "{","}"
ограничивают тело цикла.
(*) LOOP=(15,0) {DI=R0[I],...}
линия вывода DI
поочередно принимает
значения бит 15..0 значения
регистра R0. (*) LOOP=(7,0)
{DI=ADR[I],...} (*) LOOP=ADR(7,0)
{DI=I,...} - старый вариант
линия вывода DI поочередно
принимает значения бит 7..0
текущего значения
адресного слова.
(*) LOOP=(0,15) {DATA[I]=DO,..} (*) LOOP=DATA(0,15)
{I=DO,..} - старый вариант
поочередное считывание
бит 0..15 слова данных с
линии ввода DO.
(*) R1=10H
LOOP=(5,0) {D=R1[I],..}
(*) CONST=10H
LOOP=CONST(5,0) {D=I,..} - старый
вариант линия вывода D
поочередно принимает
значения бит 5..0 константы
(10H)
(*) LOOP=(R1,R2) {R3[I]=DATA[I]}
Копирование битов от R1 до R2
адресного слова в
соответствующие биты
регистра R3
(*) LOOP=(0,7){ P1=0,LOOP=(6,1){P1=0,P1=1} }
Вложенные циклы.
- BREAK - выход из
текущего цикла.
(*) LOOP=(7,0) {PI?0{BREAK}}
- Задержка (в
микросекундах). Значение
задержки может быть в
пределах 1мкс...65с.
(*) P=200
- PRINT Вывод
сообщения. Вывод на экран
окна с сообщением, строка
должна быть заключена в
кавычки. Внутри строки
можно использовать
стандартные модификаторы
аналогичные используемым
в языке C для
printf() . (В
DOS версии для всех числовых
аргументов необходим
дополнительный параметр l
(long int)).%X -
шестнадцатеричное
значение
%u - десятичное значение
Для самостоятельного
использования символа %
(процент) внутри строки, он
должен быть повторен
дважды %%. Транслятор не
проверяет правильность и
количество передаваемых
аргументов!
(*) PRINT=("Hello, World")
(*) PRINT=("Code=%04lX",R1) -
Вывод значения регистра R1
в шестнадцатеричном виде -
минимум 4 цифры.
Можно также использовать
дополнительные
модификаторы,
определяющие тип окна:
E - Error - сообщение об
ошибке
(*) PRINT=E("Hello, Mr. Bug!")
S - Status - запись в
статусное окно
(*) PRINT=S("Progress %03lu",R0)
L - Log - запись в окно
протокола (W)
(*) PRINT=L("Operation %02lu",R0)
A - Ask - запрос
подтверждения
пользователя
Значение возвращается в
регистре RA (Ok=1,Cancel=0)
PRINT=A("Are you ready ?")
- GET Ввод
значений. На экран
выводится окно с запросом
данных. Строка в скобках
задает заголовок окна.
Одновременно могут быть
введены сразу несколько
значений в заданные
регистры. Имена регистров
и формат данных
соответствуют описанным в
начальной секции.
(*) GET=("Enter value",R7,R8)
- MARK Установка и
получение отметки
(выделения) текущего слова.
Адрес соответствует
значению ADR.
(*) MARK=R1
(*) R2=MARK
- EXIT - Завершение
работы секции.
- RETURN - Выход из
функции. Не может
использоваться для
прерывания цикла.
- VCC - Управление
напряжением питания
(включение, выключение,
установка):
(*) VCC=1 - включить
(*) VCC=0 - выключить
(*) VCC=3000 - установить
напряжение 3,0 V (значение в
милливольтах)
- VPP - Управление
напряжением
программирования
(включение, выключение,
установка):
(*) VPP=1 - включить
(*) VPP=0 - выключить
- IDISABLE/IENABLE
Запрет/Разрешение
прерываний. Используются
для выполнения критичных
по времени операций.
Подробней
изучить конструкции языка
можно примере поставляемых в
составе программатора файлов
*.hpl.
|