5 января 2009
    AVR-CDC (CDC-232) - переходник USB-COM. Исходники скачаны с http://www.recursion.jp/avrcdc/cdc-232.html и перекомпилированы под ATmega16. Проект предназначен для AVR Studio 4.14.589, все опции компиляции берутся из default\Makefile.
    
    Изменены следующие опции:
1. usbconfig.h: #define USB_CFG_DMINUS_BIT 4 (раньше было 3)
2. default\Makefile: -DF_CPU=16000000UL (раньше было 12000000UL)
3. default\Makefile: MCU = atmega16 (раньше было atmega8)
4. Поменяны пути: 
## Include Directories
INCLUDES = -I".." -I"../usbdrv"
## Compile
usbdrvasm.o: ../usbdrv/usbdrvasm.S
usbdrv.o: ../usbdrv/usbdrv.c
oddebug.o: ../usbdrv/oddebug.c

В программе используется аппаратный последовательный порт ATmega16. Сигналов управления потоком нет (Flow Control, DTR/DSR, RTS/CTS, XON/XOFF). Сигналы приема/передачи RS232C будут на ножках ATmega16 (TQFP44):
RXD     выв.  9, PD0 (порт P17 макетки AVR-USB-MEGA16)
TXD     выв. 10, PD1 (порт P18 макетки AVR-USB-MEGA16)

Типичная настройка COM-порта в терминальной программе - скорость 9600 бит/сек, 8 бит данных, нет бита четности, 1 стоп-бит. Однако, как утверждается на сайте автора (Osamu Tamura @ Recursion Co.), внутренний UART конфигурируется от PC автоматически, и доступны настройки для 1200-57600 bps, данные 7/8 бит, четность N/E/O, стоп 1/2 бит.

При подключении устройства к CDC-232 к компьютеру на Windows в реестре в ветке HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_16c0&Pid_05e1 создаются папки типа 5&160f4e1&0&2, в которых прописаны параметры получающегося виртуального порта. При перетыкании из одного порта USB в другой номер получающегося COM-порта меняется. Например, в одном случае это может быть COM5, а в другом случае COM6, и т. д. Загадочное число в имени папки реестра 5&160f4e1&0&2 - это и есть серийный номер, который назначается Windows автоматически, если в устройстве серийный номер не задан. Изменить такое поведение (чтобы номер получаемого COM-порта не менялся) можно, введя серийный номер для нашего устройства CDC-232. Это делается правкой опций USB_CFG_SERIAL_NUMBER и USB_CFG_SERIAL_NUMBER_LEN файла usbconfig.h. По умолчанию они закомментированы (поэтому и меняется номер COM-порта), но нам надо их раскомментировать, и задать нужное значение, например (число в опции USB_CFG_SERIAL_NUMBER_LEN равно количеству символов в опции USB_CFG_SERIAL_NUMBER):
#define USB_CFG_SERIAL_NUMBER   '1', '2', '3', '4'
#define USB_CFG_SERIAL_NUMBER_LEN   4

В параметре USB_CFG_SERIAL_NUMBER можно указывать буквы и цифры. После подключения устройства с заданным серийным номером из нашего примера в реестре в ветке HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_16c0&Pid_05e1 создастся папка 1234 (это и есть заданный нами серийный номер устройства). Внимание - если Вы задали серийный номер устройства в usbconfig.h, то в компьютере нельзя одновременно использовать устройства CDC-232 с одинаковыми серийными номерами.

Фьюзы (fuse bits) для ATmega16 обычные - FUSE_L = ff, FUSE_H = 09.

------------------------------------------------------------------------------------------------------------
8 января 2010
    Разбираюсь с CDC-232. Пока удалось выяснить следующее:

1. main.c -> main() -> usbPoll()    весь функционал подсистемы USB.

2. main.c -> main() -> uartPoll()   весь функционал подсистемы UART.

3. uart.c -> uchar rx_buf[RX_SIZE], tx_buf[TX_SIZE];    буферы приема и передачи. Соответственно uart.h -> #define RX_SIZE 256 и #define TX_SIZE 128 их размеры.

4. uart.c: индексы буферов передачи и приема UART:
iwptr   указатель входа  приема
urptr   указатель выхода приема
uwptr   указатель входа  передачи
irptr   указатель выхода передачи

5. Буфер rx_buf заполняется в uartPoll (там все тривиально). Там же буфер опустошается, и вызовом usbSetInterrupt заказывается передача буфера. 

6. Буфер tx_buf опустошается в uartPoll (там все тривиально). Заполняется буфер в main.c -> usbFunctionWriteOut. Эта функция вызывается из usbProcessRx, которая в свою очередь вызывается из usbPoll.

Таким образом, что мне надо сделать для передачи моих сообщений из программы в виртуальный COM-порт:
a) Убрать из uartPoll вызовы usbSetInterrupt, по которым передается буфер RS232c.
b) Написать процедуру UsbSend, которая будет отправлять данные кольцевого буфера tx_usb с помощью той же usbSetInterrupt.
c) Написать процедурку, которая будет вставлять отправляемую строку данных в кольцевой буфер tx_usb.

Теперь что мне надо сделать для приема сообщений из виртуального COM-порта:
d) Переписать функцию usbFunctionWriteOut. Теперь она должна заполнять другой буфер rx_usb, который будет анализировать подпрограмма из main.
