Технический форум по робототехнике.
Vooon » 26 май 2009, 21:03
Доделал кооперативный шедулер.
Нужно только сделать буферизированный ввод, а то он сейчас блокирует все.
Ну и дописать примитивы для временных задержек (возможно и синхронизации).
=DeaD= » 26 май 2009, 21:27
И еще UIDы разнёс по разным контроллерам зачем-то

может всё-таки не надо?
Добавлено спустя 17 минут 49 секунд:Я предлагаю интроспектором отвечать на запрос 0xFF последовательностью из 2 байт, в которой каждый бит 0..15 (A-Q) - это есть или нет этот порт на МК среди GPIO портов. Т.е. на OR-AVR-M32-D это будет
11110000b, 00000000b
На OR-AVR-M128-S это будет
10000100b, 00000000b
Внутри порты нумеруются по порядку букв, т.е. в регистрах GPIO на OR-AVR-M32-D будут в порядке A,B,C,D, а на OR-AVR-M128-S будут A,F.
blindman » 27 май 2009, 05:25
Vooon писал(а):Доделал кооперативный шедулер.
Нужно только сделать буферизированный ввод, а то он сейчас блокирует все.
Ну и дописать примитивы для временных задержек (возможно и синхронизации).
Не собирается. Нет определения GATE_CHECK_EVENT.
Vooon » 27 май 2009, 12:32
Странно, я вроде комитил последний код, в котором я отказался от эвента для запуска супертаска...
Добавлено спустя 10 минут 45 секунд:
Исправил.
=DeaD= » 27 май 2009, 12:42
Даёшь единые UIDы для всех GPIO драйверов!

blindman » 27 май 2009, 14:54
Добавил драйвер серв для OR-AVR-M64-S.
2 регистра. Нулевой пока зарезервировал. Базовый номер регистра сервоконтроллера в текущей сборке - 0x0C.
- Код: Выделить всё • Развернуть
L 40
S 40 00 01 S 41 06 P
SWAASR003001000C02P
# Установить длительность импульса на выходе №17 в 1200 мкс (0x04B0)
S 40 0D 11 B004 P
SWAAAAP
# Установить длительность импульса на выходах 0,1,2 в 512, 768 и 1024 мкс
S 40 0D 00 0002 01 0003 02 0004 P
SWAAAAAAAAAAP
blindman » 28 май 2009, 15:26
Добавил драйвер АЦП
Регистр 0 - конфигурация. Пишем 2 байта - биты конфигурации и маска.
Назначение битов конфигурации:
- Код: Выделить всё • Развернуть
Биты 0..2
00 - внешняя опора
01 - опора = AVCC
10, 11 - внутренняя опора
Бит 3
0 - 8-bit
1 - 11-bit
Маска определяет, какие биты порта будут использоваться как входы АЦП.
Регистр 1 - данные. Сначала туда записываем номер канала (n), потом читаем (8-n) значений. Почему 8-n - см. далее. Для 8-битного преобразования каждое значение - 1 байт, для 11-битного - 2 байта.
- Код: Выделить всё • Развернуть
L40
L40
# Внутренняя опора, 8 бит, все 8 каналов
S 40 0E 03 FF P
SWAAAP
# Читаем каналы 0-8
S 40 0F 00 S 41 08 P
SWAASRFFD7D7D6D5D4D3D2P
# AVCC, 8 бит, все 8 каналов
S 40 0E 01 FF P
SWAAAP
# Читаем каналы 0-8
S 40 0F 00 S 41 08 P
SWAASR12ABAAA8A6A5A4A2P
# Внутренняя опора, 16 бит, все 8 каналов
S 40 0E 07 FF P
# Читаем каналы 0-8
S 40 0F 00 S 41 10 P
SWAASR37005C0355034D03470340033A033203P
# Читаем каналы 1-8
S 40 0F 01 S 41 0E P
SWAASR5E0356034E03480341033C033703P
Вопросы:
- Следует ли сделать 8 регистров, по 1 на канал ?
- Следует ли всегда выдавать 16-битные числа, независимо от режима преобразования?
И пара вопросов общего характера.
- Драйвер не знает, сколько байт запрошено для чтения. Это не дает возможности эффективно реализовать автоинкремент. Например драйвер АЦП может выдать до 8 значений - но я вынужден был сделать, чтобы он всегда выдавал все значения до конца таблицы. Предлагаю в параметре data_len передавать драйверу количество запрошенных байт, а не доступный размер буфера.
- Надо определиться с порядком байт для 2-байтных(и более) значений. Мне кажется естественным передавать сначала младший байт, именно такой порядок используется в контроллерах AVR.
=DeaD= » 28 май 2009, 15:39
blindman писал(а):Следует ли сделать 8 регистров, по 1 на канал?
Думаю будет логичным сделать 8 регистров, но сделать возможность прочитать подряд несколько, а не по очереди их читать - значительно сократит трафик.
blindman писал(а):Следует ли всегда выдавать 16-битные числа, независимо от режима преобразования?
Конечно же нет, обязательно возвращаем 8 бит, если не в 11 битном режиме.
blindman писал(а):Драйвер не знает, сколько байт запрошено для чтения. Это не дает возможности эффективно реализовать автоинкремент. Например драйвер АЦП может выдать до 8 значений - но я вынужден был сделать, чтобы он всегда выдавал все значения до конца таблицы. Предлагаю в параметре data_len передавать драйверу количество запрошенных байт, а не доступный размер буфера.
Чем это плохо? Производительность?
blindman писал(а):Надо определиться с порядком байт для 2-байтных(и более) значений. Мне кажется естественным передавать сначала младший байт, именно такой порядок используется в контроллерах AVR.
Чисто визуально это будет тяжелее для понимания. Хотя мне всё равно, но как-то зафиксировать это надо.
blindman » 28 май 2009, 15:54
=DeaD= писал(а):blindman писал(а):Драйвер не знает, сколько байт запрошено для чтения. Это не дает возможности эффективно реализовать автоинкремент. Например драйвер АЦП может выдать до 8 значений - но я вынужден был сделать, чтобы он всегда выдавал все значения до конца таблицы. Предлагаю в параметре data_len передавать драйверу количество запрошенных байт, а не доступный размер буфера.
Чем это плохо? Производительность?
Плохо тем, что если драйвер может предоставить несколько значений, а клиенту могут понадобиться не все, то мы вынуждены или выдавать из драйвера всё сразу, или из драйвера выдавать по 1 значению и посылать несколько запросов. И то, и другое создает избыточный трафик. В принципе, тут и обсуждать нечего.
blindman » 29 май 2009, 05:50
Вопрос не решился. Попробую поподробнее описать суть проблемы.
Если работаем через уарт - проблем нет, количество байт для чтения известно до обращения к драйверу. Но при использовании шлюза как подчиненного на I2C, количество байт неизвестно, нужно возвращать по одному пока не прекратятся запросы. Вижу 2 варианта
- При поступлении запроса на чтение из регистра запрашиваем у драйвера некоторое количество байт и помещаем их в буфер. Байты выдаем из буфера, пока он не опустеет, затем опять обращаемся к драйверу за новой порцией. Состояние буфера сохраняем, и если следующий запрос приходит на чтение из того же регистра, сначала выдаем данные из буфера, иначе буфер сбрасываем, и обращаемся к соответствующему драйверу за порцией данных.
Pro: - Относительная простота реализации
- Быстродействие
Contra:
- Если между обращениями к одному регистру будут обращения к другому, часть данных будет потеряна.
- Запрашиваем данные у драйвера по одному байту. Драйвер при этом, если необходимо, поддерживает [небольшой] внутренний буфер.
Pro: - Произвольная последовательность обращения к регистрам
- Нет потерь данных
Contra:
- Более сложная логика работы драйвера
- Снижение быстродействия
В общем, обычный выбор быстро/хорошо/дёшево

=DeaD= » 29 май 2009, 07:53
Не понял логики. Я вроде как раз комбинированный способ предлагал - потерь данных нет, но и по 1 байту не мельчим. Читаем блоками. Длинные i2c запросы не запрещаем, просто если буфер кончился - отправляем драйверу запрос на продолжение банкета. Соответственно нужно определить, что будет считаться таким запросом и всё (например, чтение из регистра 0xFF, которого реально не может быть у драйвера, т.к. всего на контроллере 256 регистров и минимум 1 занят интроспекцией).
blindman » 29 май 2009, 09:08
Прочитали 20 байт в буфер, реально на шину ушло 15 - 5 байт потеряны навсегда.
Добавлено спустя 8 минут 47 секунд:
=DeaD=, недостаток твоего подхода в том, что он не позволяет драйверам сохранять состояние между запросами - только один запрос к определённому регистру, возможно разбитый на несколько более мелких, ограниченных размерами буферов или чем-то ещё. Последующие запросы никак не зависят от предыдущего
Vooon » 29 май 2009, 10:50
Порядок байт: старший — младший.
На данный момент и при работе через юсарт на уровне виртуального слейва
мы не знаем сколько байт запрошено.
Запись идет в буфер, потом по событию стоп или старт вызывается запись в регистр.
Чтение идет так: со событию старт (адрес чтения) происходит чтение из регистра в буфер, за тем чтение идет из буфера. Чтение последнего байта выдает NAck.
blindman » 29 май 2009, 10:53
Vooon писал(а):Порядок байт: старший — младший.
Есть этому какие-то веские причины?
Vooon писал(а):На данный момент и при работе через юсарт на уровне виртуального слейва
мы не знаем сколько байт запрошено.
Почему это не знаем, если это явно прописывается в запросе?
Vooon » 29 май 2009, 11:37
Сетевой порядок байт, легче читать.
Ключевые слова: на уровне виртуального слейва