Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Solved] [FreeDOS] - [Klawiatura]Odwraca kolejność bajtu klaw. modyfikacji i kodu klaw.

elektronockaut 05 Nov 2021 16:19 312 15
Termopasty
  • #1
    elektronockaut
    Level 10  
    Witam,

    Zrobiłem sobie na mikrokontrolerze klawiaturę USB, która ma wysłać do komputera kombinację klawiszy alt+f. Na Windowsie działa to bezbłędnie (na kilku komputerach).
    Najpierw wysyłany jest bajt klawisza modyfikującego (alt, ctrl, shift etc.) a później bajt z kodem klawisza. Na czystym FreeDosie jest nieprawidłowa kolejność czyli najpierw odczytuje klawisz "f" a później dołącza alt (f+alt).

    Mam ustawionego FreeDos'a na COUNTRY=001,858 ale przecież to chyba nie ma znaczenia...

    Nie mam pojęcia co jest nie tak....

    W załączniku programik pod DOS, który pokazuje aktualnie wciśnięty klawisz i jego kod. Testowałem nim moją "klawiaturę" na DOSBOX pod Windows, i na freeDos gdzie docelowo ma działać. Problem jest tylko na freeDos.
    Kamery 3D Time of Flight - zastosowania w przemyśle. Darmowe szkolenie 16.12.2021r. g. 10.00 Zarejestruj się
  • Termopasty
  • #2
    tzok
    Moderator of Cars
    Może FreeDOS za szybko "wstaje" i coś się gubi w transmisji? Z tego co pamiętam, to klawiatura wysyła nie tylko kod wciśnięcia ale i zwolnienia klawisza. Zwykła klawiatura jednak działa we FreeDOSie dobrze, więc nie szukałbym problemu po stronie DOSu, tylko własnego kodu.

    Może zamiast zaczynać od CTRL+F to spróbuj sobie wysłać jakieś "Hello, World!"... myślę, że wtedy łatwiej zlokalizujesz problem.
  • #3
    elektronockaut
    Level 10  
    Wysłałem rożne napisy, i jest ok. Program napisany jest w "Bascom"
    https://www.elektroda.pl/rtvforum/topic3754939.html
    Bez głębszej ingerencji w kod, mogę modyfikować tylko bajt "key modifier" czyli alt,shift, ctrl i bajt kodu klawisza.

    Zwykła klawiatura działa dobrze, ale ona nie wysyła sama kombinacji dwóch klawiszy. Wysyła taką kolejność z jaką je wcisnę.

    Dodano po 2 [godziny] 26 [minuty]:

    Próbowałem wszystkiego co przyszło mi na myśl, i po stronie kodu Bascom, i po stronie freeDos'a - wyczerpały mi się pomysły.

    Ratujcie!

    [FreeDOS] - [Klawiatura]Odwraca kolejność bajtu klaw. modyfikacji i kodu klaw.
  • Termopasty
  • #4
    tzok
    Moderator of Cars
    ATMega8 i USB to w ogóle jest loteria, dlaczego nie użyjesz MCU z natywną obsługą USB, np. ATMega32U4? Zapewne jest za małe opóźnienie między wysłaniem kodu modyfikatora i kodu klawisza...

    Ten kod też nie jest zbyt "piękny", pokaż jak wysyłasz to Alt+F.

    Powinieneś robić coś na ten kształt:
    Code:
    Sub TypeAltF()
    

       ' Key down
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 4                         'Left ALT
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 9                         'F
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)

       ' Key up
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 0                                   'Modifier keys (shift, ctl, alt, etc)
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 0                                   'key1
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)
    End Sub
  • #5
    elektronockaut
    Level 10  
    Chciał bym żeby to była ogólnodostępna Atmega8 - jak na Windows działa to i na DOSie w końcu ruszyć musi... No bez jaj... nie robię przecież urządzenia 2.0 które ma przesyłać dane z prędkością światła ;)

    Robię wszystko zgodnie z przykładami autora biblioteki:
    http://www.sloservers.com/swusb/

    Próbowałem tak jak zalecał:
    Code: vbnet
    Log in, to see the code






    Próbowałem też tak, odwołując się od razu do case 1:
    Code: vbnet
    Log in, to see the code


    Pierwszy bajt to klawisz modyfikujący (alt, ctrl etc.) a drugi to kod litery "f"

    Obydwa sposoby działają pięknie na Windows, ale nie na freeDos :/ Ręce mi opadają.

    Zamieniałem między sobą jeszcze bajty - całkiem klapa - brak logiki
  • #6
    tzok
    Moderator of Cars
    To spróbuj dokleić i wywołać moją funkcję TypeAltF()...

    ATMega8 nie jest ogólnodostępna, jest od dawna nieprodukowana i coraz ciężej ją kupić.
  • #7
    elektronockaut
    Level 10  
    Nawet nie wiedziałem że M8 jest już nie produkowane. Chyba trochę się zatrzymałem w czasie ;). Produkują jeszcze coś w obudowach dil? Czasami takie obudowy są wygodne.

    Mógł byś mi pokazać jak i gdzie dokleić Twoją funkcje?

    Dodano po 8 [minuty]:

    Obudziłeś mnie chyba ze snu :D 16zl - 30 zł za sztukę - ale się po robiło! Na pokładzie nie ma nic, a cena kosmos. Znam tylko (trochę) bascom, więc póki co jestem skazany na AVR. Orientujesz się czy jest cokolwiek jeszcze produkowane w obudowach dil? Czy tylko już smd?
  • #8
    tzok
    Moderator of Cars
    Dokleić możesz gdziekolwiek, przecież to funkcja, najlepiej doklej na samym na końcu. Tylko pamiętaj o jej wywołaniu w kodzie programu.

    W DIL (chyba) jeszcze jest produkowana ATMega328P. Jak lutowanie SMD wydaje się straszne (a w istocie jest łatwiejsze niż THT) to zawsze można używać modułów Arduino Nano lub Pro Mini.
  • #9
    elektronockaut
    Level 10  
    W lutowaniu problemu nie ma najmniejszego nawet i bga, ale problem jest z płytkami pcb. Jedynie domowo pozostaje mi termotransfer, choć drukarka już nie domaga. Cnc odpada bo mam śruby trapezowe i luzy. Tu Panie cały kłopot 😉 wygodniej było zrobić płytkę pod THT na frezarce. Zmartwiłeś mnie okrutnie, choć takie są realia ;)

    Jak wywołać tą funkcje? Jak się do niej odnieść? Bardzo Cię proszę o przykład dla laika (mnie) ;)
  • Helpful post
    #10
    tzok
    Moderator of Cars
    ...a w odpowiedzi na co ma być wywoływana ta funkcja?

    Płytki to ja zamawiam w PCBway albo JLCPCB, dawno przestałem się bawić w "domowe wyroby".
  • #11
    elektronockaut
    Level 10  
    Czasami coś jest potrzebne ;)
    Sprawdzałem teraz stan magazynowy moich przydasi. Mam 11 szt Atmega8, i 3 atmega32 w dil ;) nie wiedziałem że taki bogaty jestem :D

    Jeśli chodzi o program, to chciał bym się odwoływać powiedzmy pinb.1 = 0
  • Helpful post
    #12
    tzok
    Moderator of Cars
    ...ale to bę♠dzie naprzemiennie "naciskać" i "zwalniać" Alt+F tak długo jak PinB == 0.
    Code:
    $noramclear
    

    $hwstack = 30
    $swstack = 30
    $framesize = 40                                             '24 bytes reserved

    $regfile = "m8def.dat"
    $crystal = 12000000

    $eepromhex

    'Include the software USB library
    $lib "swusb.lbx"
    $external _swusb
    $external Crcusb

    $include "swusb_declarations.inc"

    Declare Sub Typemessage(message As String)
    Declare Sub Typekey(key As Byte)
    Declare Function Ascii2usage(ascii As Byte) As Word

    Call Usb_reset()

    Const _usb_intf = Intf0
    Config Int0 = Rising
    On Int0 Usb_isr Nosave
    Enable Int0
    Enable Interrupts

    Config PinB.1 = Input
    PortB.1 = 1

    Dim Resetcounter As Word
    Dim Message As String * 10
    Dim Akey As Byte

    Do
       Resetcounter = 0

       Call Usb_check_reset
       Akey = Usb_check_rx()

    '*******************************************************************************************************************************

    'PRZYCISK KLAWIATURY
       If PinB.1 = 0 Then
          call TypeAltF()
       end if


    '*******************************************************************************************************************************

    Loop

    End

    $include "swusb_routines.inc"

    Sub TypeAltF()

       ' Key down
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 4                         'Left ALT
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 9                         'F
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)

       ' Key up
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 0                                   'Modifier keys (shift, ctl, alt, etc)
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 0                                   'key1
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)
    End Sub

    #if _usb_use_eeprom = 1
       $eeprom
    #else
       $data
    #endif

    _usb_devicedescriptor:
    Data 18 , 18 , _usb_desc_device , _usb_specl , _usb_spech , _usb_devclass
    Data _usb_devsubclass , _usb_devprot , 8 , _usb_vidl , _usb_vidh , _usb_pidl
    Data _usb_pidh , _usb_devrell , _usb_devrelh , _usb_imanufacturer
    Data _usb_iproduct , _usb_iserial , _usb_numconfigs


    _usb_configdescriptor:
    Data _usb_descr_total , 9 , _usb_desc_config , _usb_descr_totall
    Data _usb_descr_totalh , _usb_numifaces , _usb_confignum , _usb_iconfig
    Data _usb_powered , _usb_maxpower

    '_usb_IFaceDescriptor
    Data 9 , _usb_desc_iface , _usb_ifaceaddr , _usb_alternate
    Data _usb_ifaceendpoints , _usb_ifclass , _usb_ifsubclass , _usb_ifprotocol
    Data _usb_iiface

    #if _usb_hids > 0
    '_usb_HIDDescriptor
    Data _usb_hid_descr_len , _usb_desc_hid , _usb_hid_releasel , _usb_hid_releaseh
    Data _usb_hid_country , _usb_hid_numdescriptors

    Data _usb_desc_report
    Data 63 , 0
    #endif

    #if _usb_endpoints > 1
    Data 7 , _usb_desc_endpoint , _usb_endp2attr , _usb_endp2type , 8 , 0
    Data _usb_endp2interval
    #endif

    #if _usb_endpoints > 2
    Data 7 , _usb_desc_endpoint , _usb_endp3attr , _usb_endp3type , 8 , 0
    Data _usb_endp3interval
    #endif

    #if _usb_hids > 0
    _usb_hid_reportdescriptor:
    Data 63
    Data &H05 , &H01                                            ' USAGE_PAGE (Generic Desktop)
    Data &H09 , &H06                                            ' USAGE (Keyboard)
    Data &HA1 , &H01                                            ' COLLECTION (Application)
    Data &H05 , &H07                                            '   USAGE_PAGE (Keyboard)
    Data &H19 , &HE0                                            '   USAGE_MINIMUM (Keyboard LeftControl)
    Data &H29 , &HE7                                            '   USAGE_MAXIMUM (Keyboard Right GUI)
    Data &H15 , &H00                                            '   LOGICAL_MINIMUM (0)
    Data &H25 , &H01                                            '   LOGICAL_MAXIMUM (1)
    Data &H75 , &H01                                            '   REPORT_SIZE (1)
    Data &H95 , &H08                                            '   REPORT_COUNT (8)
    Data &H81 , &H02                                            '   INPUT (Data,Var,Abs)
    Data &H95 , &H01                                            '   REPORT_COUNT (1)
    Data &H75 , &H08                                            '   REPORT_SIZE (8)
    Data &H81 , &H03                                            '   INPUT (Cnst,Var,Abs)
    Data &H95 , &H05                                            '   REPORT_COUNT (5)
    Data &H75 , &H01                                            '   REPORT_SIZE (1)
    Data &H05 , &H08                                            '   USAGE_PAGE (LEDs)
    Data &H19 , &H01                                            '   USAGE_MINIMUM (Num Lock)
    Data &H29 , &H05                                            '   USAGE_MAXIMUM (Kana)
    Data &H91 , &H02                                            '   OUTPUT (Data,Var,Abs)
    Data &H95 , &H01                                            '   REPORT_COUNT (1)
    Data &H75 , &H03                                            '   REPORT_SIZE (3)
    Data &H91 , &H03                                            '   OUTPUT (Cnst,Var,Abs)
    Data &H95 , &H06                                            '   REPORT_COUNT (6)
    Data &H75 , &H08                                            '   REPORT_SIZE (8)
    Data &H15 , &H00                                            '   LOGICAL_MINIMUM (0)
    Data &H25 , &H65                                            '   LOGICAL_MAXIMUM (101)
    Data &H05 , &H07                                            '   USAGE_PAGE (Keyboard)
    Data &H19 , &H00                                            '   USAGE_MINIMUM (Reserved (no event indicated))
    Data &H29 , &H65                                            '   USAGE_MAXIMUM (Keyboard Application)
    Data &H81 , &H00                                            '   INPUT (Data,Ary,Abs)
    Data &HC0                                                   ' END_COLLECTION
    #endif

    '*****************************String descriptors********************************
    'Yes, they MUST be written like "t","e","s","t".  Doing so pads them with
    '0's.  If you write it like "test," I promise you it won't work.

    'Default language descriptor (index 0)
    _usb_langdescriptor:
    Data 4 , 4 , _usb_desc_string , 09 , 04                     '&h0409 = English

    'Manufacturer Descriptor (unicode)
    _usb_mandescriptor:
    Data 14 , 14 , _usb_desc_string
    Data "o" , "l" , "l" , "o" , "p" , "a"

    'Product Descriptor (unicode)
    _usb_proddescriptor:
    Data 46 , 46 , _usb_desc_string
    Data "o" , "l" , "l" , "o" , "p" , "a" , "'" , "s" , " " , "k" , "e" , "y" , "b" , "o" , "a" , "r" , "d" , " "
    Data "v" , "1" , "." , "0"
    '*******************************************************************************
  • #13
    elektronockaut
    Level 10  
    Twoje rozwiązanie jest znacznie lepsze niż to pierwotne, i moim zdaniem bardziej logiczne. Zajmuje też mniej miejsca. Pozwoliłem sobie je niebo już usprawnić na próbę ;) Na pewno tak będę teraz korzystał z tej biblioteki - dzięki!

    Problem jest nadal ten sam :/ Na Windows działa bezbłędnie, a na FreeDOSie znowu pierwsza jest "f" a później "alt" - bez zmian :/
    Może konfiguracja FreeDos'a ?


    Code: Bascom
    Log in, to see the code



    Code: fdauto
    Log in, to see the code


    Code: fdconfig
    Log in, to see the code





    Dodano po 2 [godziny] 14 [minuty]:

    Zadziałał bardzo mało elegancki sposób:

    Code: vbnet
    Log in, to see the code


    Nie działa jednak w Windows ;) O co tu chodzi!?
    Ciekawe czy na każdym komputerze z freeDos będzie działało prawidłowo.
  • Helpful post
    #14
    tzok
    Moderator of Cars
    To spróbuj tak:
    Code:
    Sub TypeAltF()
    

       ' Key down
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 4                         'Left ALT
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 0                         'key1
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)

       ' Key down
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 4                         'Left ALT
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 9                         'F
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)

       ' Keys up
       Do : Loop Until _usb_tx_status2(1)._usb_txc = 1
       _usb_tx_buffer2(2) = 0                                   'Modifier keys (shift, ctl, alt, etc)
       _usb_tx_buffer2(3) = 0                                   'Reserved.  Always 0
       _usb_tx_buffer2(4) = 0                                   'key1
       _usb_tx_buffer2(5) = 0                                   'key2
       _usb_tx_buffer2(6) = 0                                   'key3
       _usb_tx_buffer2(7) = 0                                   'key4
       _usb_tx_buffer2(8) = 0                                   'key5
       _usb_tx_buffer2(9) = 0                                   'key6
       Call Usb_send(_usb_tx_status2(1) , 8)
    End Sub
  • #15
    elektronockaut
    Level 10  
    Niestety nic z tego... Zostanę na razie przy tym mało eleganckim rozwiązaniu. Zobaczymy czy na innych komputerach z free DOS będzie działało.