source file: uart.fts
\ 12.11.2012 m0leg
\ Copyright [C] 2012 mOleg mOlegg@ya.ru
\ работа с последовательными портами В\В (COM, USB)
vocs/ unit.fts
vocs/ struct.fts
exc/ demand.fts
os/ heap.fts
Unit: UART
ALSO IMPORT KERNEL32.DLL
UART
0 Struct: DCB
Cell[] length \ задает длину, в байтах, структуры DCB.
Cell[] BaudRate \ скорость передачи данных.
Cell[] Mode \ включает двоичный режим обмена (это флаги).
Word[] wReserved \ не используется, должно быть установлено в 0.
Word[] XonLim \ минимальное число символов в приемном буфере перед посылкой символа XON.
Word[] XoffLim \ количество байт в приемном буфере перед посылкой символа XOFF.
Byte[] ByteSize \ число информационных бит в передаваемых и принимаемых байтах. 4-8
Byte[] Parity \ схема контроля четности: 0-4=дополнить до четности,1,отсутствует,дополнить до нечетности,0
Byte[] StopBits \ задает количество стоповых бит. 0,1,2 = 1, 1.5, 2
Byte[] XonChar \ задает символ XON используемый как для приема, так и для передачи.
Byte[] XoffChar \ задает символ XOFF используемый как для приема, так и для передачи.
Byte[] ErrorChar \ задает символ, использующийся для замены символов с ошибочной четностью.
Byte[] EofChar \ задает символ, использующийся для сигнализации о конце данных.
Byte[] EvtChar \ задает символ, использующийся для сигнализации о событии.
Word[] wReserved1 \ зарезервировано и не используется.
EndStruct
0 Struct: TIMEOUTS \ в милисекундах
Cell[] ReadInterval \ Максимальное время, допустимое между двумя последовательными символами, считы-ваемыми с коммуникационной линии.
Cell[] ReadTotalMultiplier \ множитель используемый для вычисления общего тайм-аута операции чтения.
Cell[] ReadTotalConstant \ константа используемая для вычисления общего тайм-аута операции чтения.
Cell[] WriteTotalMultiplier \ множитель используемый для вычисления общего тайм-аута операции записи.
Cell[] WriteTotalConstant \ константа используемая для вычисления общего тайм-аута операции записи.
EndStruct
Unit: PURGE{
0x01 CONSTANT TX_ABORT \ Terminates all outstanding write operations and returns immediately, even if the write operations have not been completed.
0x02 CONSTANT RX_ABORT \ Terminates all outstanding read operations and returns immediately, even if the read operations have not been completed.
0x04 CONSTANT TX_CLEAR \ Clears the output buffer (if the device driver has one).
0x08 CONSTANT RX_CLEAR \ Clears the input buffer (if the device driver has one).
F: } ( h -> ) SWAP PurgeComm WIN-ERR ;F
EndUnit
\ Константы
0x80000000 CONSTANT GENERIC_READ
0x40000000 CONSTANT GENERIC_WRITE
3 CONSTANT OPEN_EXISTING
\ структура описателя порта
0 Struct: PORT
Cell[] off_id \ идентификатор открытого порта
DCB /size record off_DCB \ начало записи DCB
Cell[] off_accep \ количество принятых в буфер байт
Cell[] off_size \ размер буфера для приема данных
Zero[] off_body \ начало буфера приема данных
EndStruct
\ открыть порт, заданный именем asc # ( например, s" COM1")
\ создать буфер для приема данных, длиной buf# байт
F: open ( asc # buf# --> port )
DUP PORT /size + DCB /size + BLOCK DUP >L PORT off_size !
DROP >L 0 0 OPEN_EXISTING 0 0 GENERIC_READ GENERIC_WRITE OR L>
CreateFileA -IF L> RELEASE GetLastError THROW THEN
*IF L@ PORT off_id ! L> ;THEN
L> RELEASE GetLastError THROW ;F
\ закрыть порт, освободить занимаемую память
F: close ( port --> )
DUP PORT off_id @ SWAP RELEASE CloseHandle WIN-ERR THROW ;F
\ инициализация порта
F: init ( port --> )
DUP PORT off_id @ >R
PORT off_DCB >L
DCB /size L@ DCB length !
L@ R@ GetCommState WIN-ERR THROW \ настройки по-умолчанию:
9600 L@ DCB BaudRate ! \ 9600 бод
8 L@ DCB ByteSize B! \ 8 бит на символ
0 L@ DCB StopBits B! \ 1 стоповый бит
0 L@ DCB Parity B! \ нет контроля четности
L> R> SetCommState WIN-ERR THROW ;F
\ изменить скорость обмена
F: !speed ( bod port --> )
DUP PORT off_id @ >R
PORT off_DCB DUP >L DCB BaudRate !
L> R> SetCommState WIN-ERR THROW ;F
\ Очищает очередь приема/передачи в драйвере com порта
F: clear ( port -> )
PORT off_id @ PURGE{ TX_CLEAR RX_CLEAR OR } THROW ;F
\ отправить строку в порт
F: send ( asc # port --> ) PORT off_id @ WRITE-FILE THROW ;F
\ принять строку из порта длиной не более #1 символов
F: take ( port #1 --> asc #2 ) >R
DUP >L PORT off_body DUP
L@ PORT off_size @ R> UMIN
L> PORT off_id @
READ-FILE THROW ;F
PREVIOUS PREVIOUS
EndUnit
пример использования:
s" COM1" 256 UART open VALUE Port \ открыть указанный последовательный порт В\В
Port UART init \ настройка режима работы порта В\В
Port UART clear \ очистка буферов В\В последовательного порта
s" sample string" UART Port send \ отправка строки в порт
Port 20 UART take TYPE \ принять из порта строку длиной не более 20 символов
Port UART close \ закрыть открытый последовательный порт В\В