Deploying to gh-pages from @ osiweb/unified_retro_keyboard@232b99a962 🚀
This commit is contained in:
parent
51022040f1
commit
9a201209fb
|
@ -0,0 +1,4 @@
|
|||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: a2eb8b3dc1e4b438d766803263306bf7
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,23 +0,0 @@
|
|||
#MacOS related
|
||||
.DS_Store
|
||||
|
||||
#KiCAD related
|
||||
*.bak
|
||||
*.bck
|
||||
*.sch-bak
|
||||
*.dcm
|
||||
*-cache.lib
|
||||
*.kicad_pcb-bak
|
||||
fp-lib-table
|
||||
fp-info-cache
|
||||
*-rescue.lib
|
||||
|
||||
#C related
|
||||
*.o
|
||||
*.elf
|
||||
*.map
|
||||
|
||||
#misc
|
||||
\*scratch\*
|
||||
/.gitignore~
|
||||
*.hex
|
29
README.md
29
README.md
|
@ -1,29 +0,0 @@
|
|||
## Unified Retrocomputer Keyboard Project
|
||||
|
||||
This project aims to provide a unified collection of keyboards and encoders for vintage computers, with modular design to reuse as many elements as possible across the designs.
|
||||
|
||||
Home computers of the 1970's typically either polled a switch matrix, or interfaced to a parallel ASCII keyboard via a parallel port.
|
||||
|
||||
The keyboard allows use of Cherry MX keys, or Futaba MD-4PCS (aka George Risk KBM-01-01) keys.
|
||||
|
||||
The keyboard is designed using KiCad in order to be the most useful for anybody wishing to modify the keyboard for more specific uses, or to add to the project.
|
||||
|
||||
### Capabilities so far:
|
||||
- Replacement keyboard for OSI computers
|
||||
- Replacement keyboard for Apple II/II+ computers
|
||||
- Replacement keyboard for the Sol-20 computer
|
||||
- Generic ADM-3A/Teletype style keyboard
|
||||
- Apple I keyboard (multiple styles)
|
||||
|
||||
### Coming soon:
|
||||
- Replace encoder board on Apple II/II+ keyboards
|
||||
- Convert an OSI 542 keyboard into a generic ASCII keyboard
|
||||
- Replica for Knight keyboard
|
||||
|
||||
### This keyboard project so far consists of:
|
||||
- A classic retro-style ASCII keyboard, modeled after the ADM-3A keyboard, which
|
||||
can be also be populated to fit perfectly in an Apple II/II+ case (with corresponding Apple II keymaps), or an OSI
|
||||
case (with OSI adapter).
|
||||
- A Sol-20 compatible keyboard.
|
||||
- Keyscan/decoder interface modules that can output parallel ASCII, and can be adapted for other protocols.
|
||||
- An OSI interface module, to connect the classic keyboard to an OSI computer.
|
|
@ -0,0 +1,447 @@
|
|||
:1000000085C20000A3C20000A1C200009FC2000080
|
||||
:100010009DC200009BC2000099C2000097C2000070
|
||||
:1000200095C2000093C2000091C200008FC2000080
|
||||
:100030008DC200008BC2000089C2000087C2000090
|
||||
:1000400085C2000083C2000081C200007FC20000A0
|
||||
:100050007DC20000C3C3000079C2000077C2000067
|
||||
:1000600075C2000073C2000071C200006FC20000C0
|
||||
:100070006DC200006BC2000069C2000067C20000D0
|
||||
:1000800065C2000063C2000061C200005FC20000E0
|
||||
:100090005DC200005BC2000059C2000057C20000F0
|
||||
:1000A00055C2000053C2000051C200004FC2000000
|
||||
:1000B0004DC200004BC2000049C2000047C2000010
|
||||
:1000C00045C2000043C2000041C200003FC2000020
|
||||
:1000D0003DC200003BC2000039C2000037C2000030
|
||||
:1000E00035C20000A0A1A1A01B09A51CA010A0A0C2
|
||||
:1000F000201A0111B12C0D0E02160318A00B0A08CC
|
||||
:1001000007060413A009151914120517A0A6A40DBB
|
||||
:100110000A0F0CA0A01D1BA0A0C0BFBE00BDBCBB91
|
||||
:10012000BAB9B8B7A8A9AAAB0000ADACA0A1A1A06C
|
||||
:100130001B09A55C7F503B2F205A4151A02C4D4EEE
|
||||
:1001400042564358A04B4A4847464453A049555944
|
||||
:1001500054524557A0A6A40D0A4F4C2E7E5D5B2D30
|
||||
:100160003A3039384037363534333231A8A9AAAB62
|
||||
:100170000000ADACA0A1A1A01B09A57C7F502B3F26
|
||||
:10018000205A4151B23C4D4E42564358A04B4A482A
|
||||
:1001900047464453A049555954524557A0A6A40D6B
|
||||
:1001A0000A4F4C3E7E7D7B3D2A302928602726253C
|
||||
:1001B00024232221A8A9AAAB0000ADACA0A1A1A034
|
||||
:1001C0001B09A55C7F703B2F207A6171A02C6D6E9E
|
||||
:1001D00062766378A06B6A6867666473A0697579F4
|
||||
:1001E00074726577A0A6A40D0A6F6C2E7E5D5B2DE0
|
||||
:1001F0003A3039384037363534333231A8A9AAABD2
|
||||
:100200000000ADACA4A1A1A0A01BA515A010A0A0AA
|
||||
:10021000201A0111A02C0D0E02160318A00B0A08BB
|
||||
:1002200007060413A009151914120517A0A0A00DA4
|
||||
:10023000A60F0CA0A0A0B1A0A0C0BFBE08BDBCBBB3
|
||||
:10024000BAB9B8B7A8A9AAAB0000ADACA4A1A1A047
|
||||
:10025000A01BA515A0503B2F205A4151A02C4D4E5C
|
||||
:1002600042564358A04B4A4847464453A049555923
|
||||
:1002700054524557A0A0A00DA64F4C2EA0A0A02DD3
|
||||
:100280003A3039380837363534333231A8A9AAAB79
|
||||
:100290000000ADACA4A1A1A0A01BA515A0402B3FC0
|
||||
:1002A000205A4151A03C4D5E42564358A04B4A480B
|
||||
:1002B00047464453A049555954524557A0A0A00D54
|
||||
:1002C000A64F4C3EA0A0B23D2A302928082726255B
|
||||
:1002D00024232221A8A9AAAB0000ADACA4A1A1A00F
|
||||
:1002E000A01BA515A0502B3F205A4151A03C4D4EBC
|
||||
:1002F00042564358A04B4A4847464453A049555993
|
||||
:1003000054524557A0A0A00D404F4C3EA0A0B23D76
|
||||
:100310002A3029280827262524232221A8A9AAAB88
|
||||
:100320000000ADACA4A1A1A0A01BA5157F703B2F20
|
||||
:10033000207A6171A02C6D6E62766378A06B6A681A
|
||||
:1003400067666473A069757974726577A0A0A00D63
|
||||
:100350005E6F6C2EA0A0A02D3A30393808373635A4
|
||||
:1003600034333231A8A9AAAB0000ADACA5A2011369
|
||||
:10037000040607080A0B0C0B0A7FB1A5A4A11A18E2
|
||||
:100380000316020E0D0C0E0FA180A0A01B0102038C
|
||||
:10039000040506070809000D1E1B1C1DB2091117D4
|
||||
:1003A0000512141915090F10000D0A8CA8A9AAAB83
|
||||
:1003B0000000ADACB3978120939A8E8B2D372A38ED
|
||||
:1003C0002F39A0A0343135323633A0A0302E2BA0E7
|
||||
:1003D000A0A0A0A0A5A24153444647484A4B4C3B8D
|
||||
:1003E0003A5FA6A5A4A15A584356424E4D3C3E3F03
|
||||
:1003F000A180A0A01B212223242526272829203DD7
|
||||
:100400007E5B5C5DB20951574552545955494F5076
|
||||
:10041000600D0A8CA8A9AAAB0000ADACB3978120EF
|
||||
:10042000939A8E8B2D372A382F39A0A0343135324C
|
||||
:100430003633A0A0302E2BA0A0A0A0A0A5A241538F
|
||||
:10044000444647484A4B4C3B3A7FA6A5A4A15A587C
|
||||
:100450004356424E4D2C2E2FA180A0A01B3132338B
|
||||
:10046000343536373839302D5E5B5C5DB209515713
|
||||
:100470004552545955494F50400D0A8CA8A9AAAB72
|
||||
:100480000000ADACB3978120939A8E8B2D372A381C
|
||||
:100490002F39A0A0343135323633A0A0302E2BA016
|
||||
:1004A000A0A0A0A0A5A26173646667686A6B6C3B9C
|
||||
:1004B0003A7FA6A5A4A17A786376626E6D2C2E2F62
|
||||
:1004C000A180A0A01B313233343536373839302D76
|
||||
:1004D0005E5B5C5DB20971776572747975696F7086
|
||||
:1004E000400D0A8CA8A9AAAB0000ADACB39781203F
|
||||
:1004F000939A8E8B2D372A382F39A0A0343135327C
|
||||
:100500003633A0A0302E2BA0A0A0A0A011241FBE87
|
||||
:10051000CFEFD1E2DEBFCDBF00E00CBF13E0A0E023
|
||||
:10052000B2E0E4EAFAE100E00BBF02C007900D92EE
|
||||
:10053000A033B107D9F724E0A0E3B3E001C01D92D6
|
||||
:10054000A43CB207E1F7A6D70C94220D59CD805AEE
|
||||
:10055000813208F00895E82FF0E08827EC5DF24F33
|
||||
:100560008F4FBAC784E0A6C28DE0A4C28CE0A2C2BD
|
||||
:100570008BE0A0C28AE09EC289E09CC288E09AC259
|
||||
:1005800087E098C286E096C285E094C286E0F2C514
|
||||
:1005900085E0F0C584E0EEC583E0ECC582E0EAC505
|
||||
:1005A00081E0E8C589E0E6C588E0E4C587E0E2C50A
|
||||
:1005B0007BC12AC5E2C3A1C360C31FC33BC54BC4F3
|
||||
:1005C0003EC432C429C422C4815A8D3008F0089533
|
||||
:1005D000E82FF0E08827EB5BF24F8F4F7DC73FC4D9
|
||||
:1005E00043C440C5EAC229C368C3A7C3F9C45FC1F5
|
||||
:1005F000CF93C82F8A3041F06C2F8091320315D2EF
|
||||
:100600008C2F90E0CF9108956DE0809132030DD250
|
||||
:10061000F3CFCF93809132032AD2C82F803A41F092
|
||||
:10062000809130039091310354D18C2FCF91089554
|
||||
:1006300080913303CF911BC290E09093310380935C
|
||||
:10064000300308955F926F927F928F929F92AF9244
|
||||
:10065000BF92CF92DF92EF92FF920F931F93CF93AF
|
||||
:10066000DF9381E036D25C0183E024D200E03AE0FF
|
||||
:10067000732E88248394912C50EA652E71D208172A
|
||||
:1006800008F06BC0802FF5011995D82F802F90E0CE
|
||||
:100690009C012B543C4F6901F90110811D27C0E0DA
|
||||
:1006A000880F991F880F991F880F991F9C012B5C39
|
||||
:1006B0003C4F790105C0811115C01695D695CF5FC5
|
||||
:1006C0005AD2C81708F044C08D2F817010FFF3CFA5
|
||||
:1006D000F701EC0FF11D90812FEF290F9130F9F008
|
||||
:1006E0002083EBCFC4D3482F6C2F802F66D39091FB
|
||||
:1006F00034039813E2CFC3D48823F9F25090340323
|
||||
:10070000F0EAF51510F1652D809133038ED18091BB
|
||||
:100710003403581691F25092340359D4CECF7082DC
|
||||
:10072000F601908194010C2E01C0220F0A94EAF781
|
||||
:10073000882319F1922B90839AD3482F6C2F802F06
|
||||
:100740003CD3582EF0EAF817F0F6852D00DFB5CF30
|
||||
:100750000F5F06D2081708F495CFDF91CF911F9154
|
||||
:100760000F91FF90EF90DF90CF90BF90AF909F9050
|
||||
:100770008F907F906F905F9008952095292320831C
|
||||
:1007800076D3482F6C2F802F18D3813A38F490916C
|
||||
:100790003403981392CF609234038FCF15DF8DCF3F
|
||||
:1007A00080EA809334030DD103D4F0D180E190E04E
|
||||
:1007B0000FD18093330380E890E00AD18093320315
|
||||
:1007C000E5EBF3E080E1DF011D928A95E9F740E86F
|
||||
:1007D00050E06AE070E085E393E09AC68F9381E091
|
||||
:1007E0008093C6038F9118958091C6031092C6031B
|
||||
:1007F0000895882311F05D9808955D9A08958823DF
|
||||
:1008000011F05E9808955E9A0895882311F05F981C
|
||||
:1008100008955F9A08950895882319F02D9A259ACE
|
||||
:1008200008952D98259A0895882319F025982D9AD2
|
||||
:1008300008952D98259A0895882319F02D9A259AC0
|
||||
:10084000089525982D980895882319F02E9A269AB0
|
||||
:1008500008952E98269A0895882319F026982E9A9E
|
||||
:1008600008952E98269A0895882319F02E9A269A8C
|
||||
:10087000089526982E980895882319F02F9A279A7C
|
||||
:1008800008952F98279A0895882319F027982F9A6A
|
||||
:1008900008952F98279A0895882319F02F9A279A58
|
||||
:1008A000089527982F9808952C98249A08952C9AA3
|
||||
:1008B000249A089585E38A95F1F7000008952FEFB3
|
||||
:1008C00080E792E0215080409040E1F700C00000B6
|
||||
:1008D00008959C01892B61F090E080E0EFE9FFE052
|
||||
:1008E0003197F1F700C00000019628173907B1F7DA
|
||||
:1008F0000895F8941092C60387E0809361001092E7
|
||||
:10090000C60389EF87BD15BC82E084BD80936E006D
|
||||
:1009100083E085BD8091C503809302018FEF8093B2
|
||||
:1009200001011092C5032C98249A559A569A579A09
|
||||
:1009300081B98093040117B888B978940895282F55
|
||||
:1009400081E090E0A0E0B0E004C0880F991FAA1FEA
|
||||
:10095000BB1F2A95D2F780959095A095B09580936E
|
||||
:10096000050125E12A95F1F70000892F9A2FAB2F79
|
||||
:10097000BB2782B985E18A95F1F7000086B18095A1
|
||||
:1009800008959091C5038927809302011C9A85E3FD
|
||||
:100990008A95F1F700001C9A0895833049F028F4F5
|
||||
:1009A000813041F0823029F4A0C4843011F434C580
|
||||
:1009B000CFC42CC45DC4982F81E0953008F080E04E
|
||||
:1009C00008951092C9031092C8031092C7030895A6
|
||||
:1009D0009C018091C703843034F54091C803509145
|
||||
:1009E000C90360E970E0641B750B62177307DCF0E4
|
||||
:1009F00091E0980F9093C70397E08902F0011124CA
|
||||
:100A0000E653FC4F33832283BA016A517C4F7183D2
|
||||
:100A10006083148215821682420F531F5093C903BC
|
||||
:100A20004093C80308958FEF089587FD1EC09091ED
|
||||
:100A3000C7038917DCF497E08902F0011124E6531B
|
||||
:100A4000FC4F2681428153812417150674F484815A
|
||||
:100A500090E0A081B181A80FB91F6C930196BA01F3
|
||||
:100A600028D584832F5F268308950895089587FDF0
|
||||
:100A700004C09091C70389171CF030EA832F0895B2
|
||||
:100A800097E08902F0011124E653FC4F26812223CE
|
||||
:100A9000A1F3858190E0A081B181A80FB91F3C919D
|
||||
:100AA00001966281738105D5858321502683832F2A
|
||||
:100AB000089508959FEF980F9D3050F4E82FF0E0CF
|
||||
:100AC000EE0FFF1FEA58FB4F0190F081E02D1994C3
|
||||
:100AD00008959FEF980F9D3048F4E82FF0E0EE0F57
|
||||
:100AE000FF1FEA58FB4F80819181089589E595E0C9
|
||||
:100AF00008959FEF980F9D3040F4E82FF0E0EE0F3F
|
||||
:100B0000FF1FEA58FB4F608371830895E6E7F4E026
|
||||
:100B100089E595E08193919324E0E239F207D1F7DA
|
||||
:100B20008FE994E0909379048093780481EC94E0C9
|
||||
:100B300090937B0480937A040895643080F441316B
|
||||
:100B400070F4293060F4E62FF0E0EE0FFF1FEE0F97
|
||||
:100B5000FF1FED56FB4F80839183428323830895CB
|
||||
:100B600086D1E82FF0E0EE0FFF1FEE0FFF1FED56CE
|
||||
:100B7000FB4F828108957BD1E82FF0E0EE0FFF1F3D
|
||||
:100B8000EE0FFF1FED56FB4F8381089580E013DFCA
|
||||
:100B9000811101C0089510929204ABDEE3E9F4E004
|
||||
:100BA0001182108212821382349684E0E33AF807AD
|
||||
:100BB000B9F70AD3ABDF80E0F0CECF9380919204F7
|
||||
:100BC000C82FCE7F80FD02C0CF9108958C2FF3DE19
|
||||
:100BD0008823D1F3C09392048CDEE3E9F4E0118220
|
||||
:100BE000108212821382349684E0E33AF807B9F750
|
||||
:100BF000EBD28CDF8C2FCF91D0CECF93809192040B
|
||||
:100C0000C82FC16080FF02C0CF9108958C2FD3DE22
|
||||
:100C10008823D1F3C09392046CDEE3E9F4E01182FF
|
||||
:100C2000108212821382349684E0E33AF807B9F70F
|
||||
:100C3000CBD26CDF8C2FCF91B0CECF93809192042A
|
||||
:100C4000C82FCD7F81FD02C0CF9108958C2FB3DED8
|
||||
:100C50008823D1F3C09392044CDEE3E9F4E01182DF
|
||||
:100C6000108212821382349684E0E33AF807B9F7CF
|
||||
:100C7000ABD24CDF8C2FCF9190CECF93809192044A
|
||||
:100C8000C82FC26081FF02C0CF9108958C2F93DEE0
|
||||
:100C90008823D1F3C09392042CDEE3E9F4E01182BF
|
||||
:100CA000108212821382349684E0E33AF807B9F78F
|
||||
:100CB0008BD22CDF8C2FCF9170CECF93809192046A
|
||||
:100CC000C82FCB7F82FD02C0CF9108958C2F73DE99
|
||||
:100CD0008823D1F3C09392040CDEE3E9F4E011829F
|
||||
:100CE000108212821382349684E0E33AF807B9F74F
|
||||
:100CF0006BD20CDF8C2FCF9150CECF93809192048A
|
||||
:100D0000C82FC46082FF02C0CF9108958C2F53DE9C
|
||||
:100D10008823D1F3C0939204ECDDE3E9F4E011827F
|
||||
:100D2000108212821382349684E0E33AF807B9F70E
|
||||
:100D30004BD2ECDE8C2FCF9130CECF9380919204AA
|
||||
:100D4000C82FC77F83FD02C0CF9108958C2F33DE5B
|
||||
:100D50008823D1F3C0939204CCDDE3E9F4E011825F
|
||||
:100D6000108212821382349684E0E33AF807B9F7CE
|
||||
:100D70002BD2CCDE8C2FCF9110CECF9380919204CA
|
||||
:100D8000C82FC86083FF02C0CF9108958C2F13DE57
|
||||
:100D90008823D1F3C0939204ACDDE3E9F4E011823F
|
||||
:100DA000108212821382349684E0E33AF807B9F78E
|
||||
:100DB0000BD2ACDE8C2FCF91F0CD982FA091920466
|
||||
:100DC000B0E0AA0FBB1FAA0FBB1FAD56BB4F1396B7
|
||||
:100DD0008C9113978823C9F012962C912223A1F0AD
|
||||
:100DE000E42FF0E0EE0FFF1FEE0FFF1FED56FB4F5D
|
||||
:100DF00070E0899F600D711D11240190F081E02D3C
|
||||
:100E0000E60FF71F8491089580E0089581E08093B4
|
||||
:100E1000A50462E08BE049C18091A50482608093C3
|
||||
:100E2000A50461E08BE041C18091A50492E089278F
|
||||
:100E30008093A50462E081FD61E08BE036C1909172
|
||||
:100E4000A40481E089278093A40462E0913009F032
|
||||
:100E500061E08AE02AC181E08093A30408951092A2
|
||||
:100E6000A50462E08BE021C11092A3040895E1E0A3
|
||||
:100E70008091A504811101C0E0E08091A40481115A
|
||||
:100E8000E2608091A3048111E460F0E0EE5BFD4F2D
|
||||
:100E900080810895CF93DF93C82FD0E0CC0FDD1F62
|
||||
:100EA000CC0FDD1FC050DE4FE881F98181E019953C
|
||||
:100EB00081E08A83DF91CF910895CF93DF93C82F8C
|
||||
:100EC000D0E0CC0FDD1FCC0FDD1FC050DE4FE8811E
|
||||
:100ED000F98180E019951A82DF91CF9108951F93CF
|
||||
:100EE000CF93DF93C82FD0E0CC0FDD1FCC0FDD1FD9
|
||||
:100EF000FE01E050FE4F11E08281811110E0C050F0
|
||||
:100F0000DE4FE881F981812F19951A83DF91CF9106
|
||||
:100F10001F910895E82FF0E0EE0FFF1FEE0FFF1F67
|
||||
:100F2000E050FE4F83810895582F8091030288235B
|
||||
:100F300091F0581303C027C0581771F0282F30E0E4
|
||||
:100F4000982F220F331F220F331FF901E050FE4F5D
|
||||
:100F500083818111F1CF089581508C30B8F49D3098
|
||||
:100F6000A9F0E52FF0E0EE0FFF1FEE0FFF1FE0509E
|
||||
:100F7000FE4F838120503E4FD90113968C9363839B
|
||||
:100F8000428381E0089581508C3010F080E0089514
|
||||
:100F900030E020E0E6CFE2E0F2E080E091E0908314
|
||||
:100FA0008F5F818334968D30D1F71092330208958C
|
||||
:100FB0008DE092E09093A9048093A8049093AB04F1
|
||||
:100FC0008093AA049093A7048093A6040895809127
|
||||
:100FD000AA049091AB049093A7048093A60408956B
|
||||
:100FE0001092A9041092A8048091AA049091AB04D5
|
||||
:100FF0008234910541F01092AB041092AA04109231
|
||||
:10100000A7041092A60408958DE092E09093A9049D
|
||||
:101010008093A8042091AA043091AB0422343105B6
|
||||
:1010200041F09093AB048093AA049093A70480931B
|
||||
:10103000A60408958091A6049091A7048334910595
|
||||
:1010400030F48091AA049091AB04892B51F482E48E
|
||||
:1010500090E09093AB048093AA049093A7048093AC
|
||||
:10106000A60408958091A8049091A9049093AB04DC
|
||||
:101070008093AA049093A7048093A6040895809176
|
||||
:10108000A6049091A704009771F0019741F482E4BF
|
||||
:1010900090E09093A7048093A60481E00895909334
|
||||
:1010A000A7048093A60480E00895CF93DF93E82FF0
|
||||
:1010B000F0E0EE0FFF1FE455FB4FC081633051F1AC
|
||||
:1010C00080F0643009F43BC0653031F007C08C2FEC
|
||||
:1010D00006DF8C2F1FDFC82FC111F9CFDF91CF9111
|
||||
:1010E0000895613091F0623031F0F8CF8C2FE5DE59
|
||||
:1010F0008C2F10DFC82FC111F9CFDF91CF91089548
|
||||
:101100008C2FC8DE8C2F06DFC82FC111F9CFDF91DD
|
||||
:10111000CF910895DC2FCC2339F18D2FE0DE8D2F78
|
||||
:10112000F9DED82F8111F9CFC5DB8C2FD8DE8C2FBB
|
||||
:10113000F1DEC82F8111F9CFDF91CF910895DC2F17
|
||||
:10114000CC23A9F08D2FCBDE8D2FE4DED82F81119B
|
||||
:10115000F9CFB5DB8C2FC3DE8C2FDCDEC82F8111DD
|
||||
:10116000F9CFDF91CF910895DF91CF91A3CBDF919C
|
||||
:10117000CF91A5CBE82FF0E0EE0FFF1FE455FB4F1A
|
||||
:10118000618193CF0F931F93CF93DF93162F042F7B
|
||||
:101190009FEF980F9B3028F0DF91CF911F910F9117
|
||||
:1011A0000895C82FD0E0CC0FDD1FC455DB4F422F70
|
||||
:1011B0006881812FB9DE882379F318830983DF9151
|
||||
:1011C000CF911F910F910895E6DEECEAF4E01182D1
|
||||
:1011D0001082329684E0E43CF807C9F70895CF9373
|
||||
:1011E000DF93CDB7DEB7FE01369661917191AF0105
|
||||
:1011F00084E392E094D1DF91CF9108958AE492E064
|
||||
:101200009F938F93ECDF0F900F90089588E214DA8C
|
||||
:1012100060E080E057D062E081E054D061E082E09D
|
||||
:1012200051D063E083E04ED06EEF78E08DE061DC7A
|
||||
:1012300062ED79E08CE05DDC21E040E06AE087E08F
|
||||
:10124000A1DF20E040E06CE08AE09CDF21E043E0A9
|
||||
:1012500068E081E097DF20E044E063E082E092CF45
|
||||
:101260008AE492E09F938F93BADF0F900F900895D6
|
||||
:1012700088E2E2D960E081E025D062E081E022D01E
|
||||
:1012800061E082E01FD063E083E01CD060E379E09E
|
||||
:101290008DE02FDC62ED79E08CE02BDC21E040E09A
|
||||
:1012A0006AE087E06FDF20E040E06CE087E06ADF23
|
||||
:1012B00021E043E068E081E065DF20E044E063E0B6
|
||||
:1012C00082E060CFE82FF0E0EE0FFF1FE35AFD4F02
|
||||
:1012D00028E049E08081918130CC85E692E09F93BF
|
||||
:1012E0008F937DDF0F900F90089588E2A5D960E07D
|
||||
:1012F00080E07FD062E081E07CD061E082E079D064
|
||||
:1013000063E084E076D062ED79E08CE0F2DB6DE6BC
|
||||
:1013100079E08DE0EEDB20E040E06AE08AE032DF59
|
||||
:1013200020E040E06CE088E02DDF21E043E068E071
|
||||
:1013300081E028DF20E044E063E082E023DF7FCD2E
|
||||
:1013400082E892E09F938F934ADF0F900F90089569
|
||||
:1013500088E272D960E081E04CD062E081E049D05F
|
||||
:1013600061E083E046D063E084E043D062ED79E061
|
||||
:101370008CE0BFDB60EA79E08DE0BBDB20E040E0A1
|
||||
:101380006AE087E0FFDE20E040E06CE088E0FADE23
|
||||
:1013900021E043E068E081E0F5DE20E044E063E046
|
||||
:1013A00082E0F0CE89E992E09F938F9318DF84EA80
|
||||
:1013B00092E09F938F9313DF84EB92E09F938F9340
|
||||
:1013C0000EDF8EED92E09F938F9309DF84EF92E022
|
||||
:1013D0009F938F9304DF8AE093E09F938F93FFDEC8
|
||||
:1013E0008DB79EB70C960FB6F8949EBF0FBE8DBFFB
|
||||
:1013F0000895E82FF0E0EE0FFF1FEA5EFC4F28E0B3
|
||||
:1014000049E08081918199CB80E293E09F938F9313
|
||||
:10141000E6DE0F900F90089528E04DE060E084EA4A
|
||||
:1014200094E08BDB28E04DE062E08CE394E085DB28
|
||||
:1014300028E04DE061E084ED93E07FDB28E04DE0C3
|
||||
:1014400063E08CE693E079DB88E2F6D820E040E0C8
|
||||
:101450006AE08AE097DE20E040E06CE08BE092DE1C
|
||||
:1014600021E045E061E083E08DDE20E045E06BE0D7
|
||||
:1014700083E088DE21E043E068E081E083DE21E074
|
||||
:1014800044E064E082E07EDEDADC11DA64E07AE0F7
|
||||
:101490008DE02FCB85D9A8D98823E9F3BAD8C82FF6
|
||||
:1014A000803A29F082E015DBFC018C2F1995CAD80F
|
||||
:1014B000F2CF97FB072E16F4009406D077FD08D0E4
|
||||
:1014C00013D007FC05D03EF4909581959F4F089569
|
||||
:1014D000709561957F4F0895EE0FFF1F881F8BBF9A
|
||||
:1014E0000790F691E02D1994AA1BBB1B51E107C090
|
||||
:1014F000AA1FBB1FA617B70710F0A61BB70B881FA4
|
||||
:10150000991F5A95A9F780959095BC01CD01089532
|
||||
:10151000DC0101C06D9341505040E0F708952F92D7
|
||||
:101520003F924F925F926F927F928F929F92AF9273
|
||||
:10153000BF92CF92DF92EF92FF920F931F93CF93C0
|
||||
:10154000DF93CDB7DEB72F970FB6F894DEBF0FBE8F
|
||||
:10155000CDBF7C013B018A01DC0117961C921E92D3
|
||||
:10156000169713968C9181FFC6C19AE0292EFE0131
|
||||
:1015700031964F01D70113969C91F30193FD85910C
|
||||
:1015800093FF81913F01882309F43AC1853239F4F0
|
||||
:1015900093FD859193FF81913F01853221F4B7013D
|
||||
:1015A00090E0C2D1E7CFB12C412C512CBFE1B51551
|
||||
:1015B00038F08B3209F188F4803201F1833221F165
|
||||
:1015C00057FC3AC020ED280F2A3040F556FE1FC0C8
|
||||
:1015D000B29C200D1124B22E06C08D3291F08033C2
|
||||
:1015E00079F7689450F8F30193FD859193FF819109
|
||||
:1015F0003F018111DBCF20C0689451F8689452F804
|
||||
:10160000F2CF689453F8EFCF689454F8ECCF429C33
|
||||
:10161000200D1124422E689455F8E5CF8E3229F41E
|
||||
:1016200056FCEEC0689456F8DECF8C3619F46894F8
|
||||
:1016300057F8D9CF8836B9F2982F9F7D95549330BB
|
||||
:10164000B8F0833671F1833791F1833509F056C0D4
|
||||
:10165000D801CD90DD908D016B2D70E056FC02C05D
|
||||
:101660006FEF7FEFC6014AD15C01689457F80AC05A
|
||||
:101670000C5F1F4FEFE3E983AA24A394B12C64010C
|
||||
:10168000E89457F853FE26C0342CA114B10439F560
|
||||
:10169000332009F46FCFB70180E290E045D13A944E
|
||||
:1016A000F7CFD8018C9189830E5F1F4FE5CFF801EA
|
||||
:1016B000C190D1908F016B2D70E056FC02C06FEF8E
|
||||
:1016C0007FEFC60126D15C01DBCFB70180E290E05D
|
||||
:1016D0002BD14A944A141B0409F0B8F7D5CFF60170
|
||||
:1016E00057FC859157FE81916F01B70190E01CD1A5
|
||||
:1016F00031103A94B1E0AB1AB108C7CF843619F073
|
||||
:10170000893609F06DC0F80157FE63C0619171918F
|
||||
:10171000819191918F01E52DEF76DE2E97FF09C023
|
||||
:1017200090958095709561957F4F8F4F9F4F6894EE
|
||||
:10173000D7F82AE030E0A40127D1C82EC818AC2C75
|
||||
:101740005D2CD6FE0CC0E89450F8CB1440F4D4FEC7
|
||||
:1017500005C0D2FC03C05D2D5E7E552EAB2C54FE21
|
||||
:10176000A4C0FE01EC0DF11D8081803309F096C00C
|
||||
:10177000652D697E562E752D7870372E53FCA3C0CB
|
||||
:1017800050FE9DC0BC2CA41410F4B40CBA1854FE26
|
||||
:10179000A0C0B70180E390E0C7D052FE06C088E742
|
||||
:1017A00051FC88E590E0B701BFD0CB1408F49DC090
|
||||
:1017B000CA94D12C8FEFC81AD80AC80CD91CD601EC
|
||||
:1017C0008E916D01B70190E0AFD08C149D04B9F7F4
|
||||
:1017D0005FCF61917191072E000C880B990B9ACF06
|
||||
:1017E000D52CE894D4F82AE08537D1F1F52DF97F8E
|
||||
:1017F000DF2E803749F100F5883549F18F3679F1D0
|
||||
:10180000F701868197812F960FB6F894DEBF0FBE41
|
||||
:10181000CDBFDF91CF911F910F91FF90EF90DF909F
|
||||
:10182000CF90BF90AF909F908F907F906F905F9080
|
||||
:101830004F903F902F900895883711F7D4FE02C043
|
||||
:101840006894D2F820E10CC06894D4F8F7CF54FE25
|
||||
:1018500003C02F2F2660D22E20E132E002C028E004
|
||||
:1018600030E0F801D7FE14C041915191619171911E
|
||||
:101870004C875D876E877F878F01A4016C857D858E
|
||||
:101880008E859F8581D0C82EC818E894D7F857CF89
|
||||
:1018900081919191AC0170E060E0EACF52FC02C00E
|
||||
:1018A000A39469CFA394A39466CF852D867809F479
|
||||
:1018B00062CFF6CFB70180E290E036D0A394A414B3
|
||||
:1018C000C8F3312C64CF342C3A18A41408F45FCF39
|
||||
:1018D000F8CF852D867809F468CF8BE251FE80E23F
|
||||
:1018E00057FC8DE2B70190E05FCFB70180E390E055
|
||||
:1018F0001BD0BA945ACF8FEF9FEF85CFFC01059094
|
||||
:10190000615070400110D8F7809590958E0F9F1F01
|
||||
:101910000895FC016150704001900110D8F7809546
|
||||
:1019200090958E0F9F1F08950F931F93CF93DF9372
|
||||
:10193000182F092FEB018B8181FD09C01FEF0FEFDD
|
||||
:10194000812F902FDF91CF911F910F91089582FFEA
|
||||
:1019500014C02E813F818C819D81281739073CF46A
|
||||
:10196000E881F981CF0101969983888310838E8164
|
||||
:101970009F8101969F838E83E3CFE885F985812F30
|
||||
:101980001995892BA1F3DACFFA01AA27283051F152
|
||||
:10199000203181F1E8946F936E7F6E5F7F4F8F4FA0
|
||||
:1019A0009F4FAF4FB1E03ED0B4E03CD0670F781FFF
|
||||
:1019B000891F9A1FA11D680F791F8A1F911DA11DE4
|
||||
:1019C0006A0F711D811D911DA11D20D009F468941D
|
||||
:1019D0003F912AE0269F11243019305D3193DEF6C5
|
||||
:1019E000CF010895462F4770405D4193B3E00FD07B
|
||||
:1019F000C9F7F6CF462F4F70405D4A3318F0495D66
|
||||
:101A000031FD4052419302D0A9F7EACFB4E0A69548
|
||||
:101A10009795879577956795BA95C9F7009761056A
|
||||
:101A2000710508959B01AC010A2E069457954795C0
|
||||
:101A300037952795BA95C9F7620F731F841F951FB5
|
||||
:101A4000A01D0895F894FFCFB202E302E202E10282
|
||||
:101A5000E002DF02DE02B202DD02DC02DB02DA02B9
|
||||
:101A6000D902D802D602D402D202D002CE02CC02CF
|
||||
:101A7000CA02C802C602B202C402C202C002BE0248
|
||||
:101A8000BC02BA02B802B602B402EF02E702E702F1
|
||||
:101A9000E702F002F102E702F202F302F402F502B9
|
||||
:041AA000F602F70251
|
||||
:101AA4000B0400000C040000140400001C040000DB
|
||||
:101AB400240400002C040000340400003C04000052
|
||||
:101AC400440400004C040000F9030000FF0300007C
|
||||
:101AD400050400000000000200000000F8020000FD
|
||||
:101AE400000000010201030303035B4B65796D6190
|
||||
:101AF400703A20636C61737369635D0A00BC012CE6
|
||||
:101B0400017401E4005B4B65796D61703A204170AA
|
||||
:101B1400706C6520322028752F6C206361736529F1
|
||||
:101B24005D005B4B65796D61703A204170706C6546
|
||||
:101B3400203220434150535D00313020474554202A
|
||||
:101B440041240D0032302041203D2041534328419F
|
||||
:101B540024290D0033302049462041203C203332D3
|
||||
:101B6400205448454E2041243D2243544C2B222BE3
|
||||
:101B7400434852242841202B203634290D00343088
|
||||
:101B8400203F2227223B41243B2227203D20223B89
|
||||
:101B9400413A0D0035302049462041203C3E203357
|
||||
:101BA40020474F544F2031300D00363020454E44ED
|
||||
:101BB4000D52554E0D0024034C02DC029402040223
|
||||
:101BC4005B4B657962643A20536F6C2D32305D0053
|
||||
:00000001FF
|
|
@ -0,0 +1,438 @@
|
|||
:1000000047C2000061C200005FC200005DC2000084
|
||||
:100010005BC2000059C2000057C2000055C2000078
|
||||
:1000200053C2000051C200004FC200004DC2000088
|
||||
:100030004BC2000049C200008BC3000045C2000053
|
||||
:1000400043C2000041C200003FC200003DC20000A8
|
||||
:100050003BC2000039C2000037C2000035C20000B8
|
||||
:1000600033C2000031C20000A0A1A1A01B09A51C41
|
||||
:10007000A010A0A0201A0111B12C0D0E0216031819
|
||||
:10008000A00B0A0807060413A00915191412051776
|
||||
:10009000A0A6A40D0A0F0CA0A01D1BA0A0C0BFBE4F
|
||||
:1000A00000BDBCBBBAB9B8B7A8A9AAAB0000ADAC3B
|
||||
:1000B000A0A1A1A01B09A55C7F503B2F205A415154
|
||||
:1000C000A02C4D4E42564358A04B4A4847464453F5
|
||||
:1000D000A049555954524557A0A6A40D0A4F4C2E7D
|
||||
:1000E0007E5D5B2D3A303938403736353433323126
|
||||
:1000F000A8A9AAAB0000ADACA0A1A1A01B09A57C3A
|
||||
:100100007F502B3F205A4151B23C4D4E42564358EE
|
||||
:10011000A04B4A4847464453A04955595452455765
|
||||
:10012000A0A6A40D0A4F4C3E7E7D7B3D2A30292897
|
||||
:100130006027262524232221A8A9AAAB0000ADAC64
|
||||
:10014000A0A1A1A01B09A55C7F703B2F207A617143
|
||||
:10015000A02C6D6E62766378A06B6A6867666473C4
|
||||
:10016000A069757974726577A0A6A40D0A6F6C2ECC
|
||||
:100170007E5D5B2D3A303938403736353433323195
|
||||
:10018000A8A9AAAB0000ADACA4A1A1A0A01BA51575
|
||||
:10019000A010A0A0201A0111A02C0D0E0216031809
|
||||
:1001A000A00B0A0807060413A00915191412051755
|
||||
:1001B000A0A0A00DA60F0CA0A0A0B1A0A0C0BFBE83
|
||||
:1001C00008BDBCBBBAB9B8B7A8A9AAAB0000ADAC12
|
||||
:1001D000A4A1A1A0A01BA515A0503B2F205A4151BE
|
||||
:1001E000A02C4D4E42564358A04B4A4847464453D4
|
||||
:1001F000A049555954524557A0A0A00DA64F4C2ECA
|
||||
:10020000A0A0A02D3A303938083736353433323192
|
||||
:10021000A8A9AAAB0000ADACA4A1A1A0A01BA515E4
|
||||
:10022000A0402B3F205A4151A03C4D5E42564358BE
|
||||
:10023000A04B4A4847464453A04955595452455744
|
||||
:10024000A0A0A00DA64F4C3EA0A0B23D2A30292868
|
||||
:100250000827262524232221A8A9AAAB0000ADAC9B
|
||||
:10026000A4A1A1A0A01BA515A0502B3F205A41512D
|
||||
:10027000A03C4D4E42564358A04B4A484746445333
|
||||
:10028000A049555954524557A0A0A00D404F4C3E8F
|
||||
:10029000A0A0B23D2A302928082726252423222180
|
||||
:1002A000A8A9AAAB0000ADACA4A1A1A0A01BA51554
|
||||
:1002B0007F703B2F207A6171A02C6D6E627663781F
|
||||
:1002C000A06B6A6867666473A069757974726577F4
|
||||
:1002D000A0A0A00D5E6F6C2EA0A0A02D3A303938E2
|
||||
:1002E0000837363534333231A8A9AAAB0000ADAC9B
|
||||
:1002F000A5A20113040607080A0B0C0B0A7FB1A57F
|
||||
:10030000A4A11A180316020E0D0C0E0FA180A0A0B6
|
||||
:100310001B010203040506070809000D1E1B1C1D16
|
||||
:10032000B20911170512141915090F10000D0A8CC6
|
||||
:10033000A8A9AAAB0000ADACB3978120939A8E8B8D
|
||||
:100340002D372A382F39A0A0343135323633A0A0CA
|
||||
:10035000302E2BA0A0A0A0A0A5A241534446474800
|
||||
:100360004A4B4C3B3A5FA6A5A4A15A584356424E6D
|
||||
:100370004D3C3E3FA180A0A01B21222324252627FF
|
||||
:100380002829203D7E5B5C5DB20951574552545986
|
||||
:1003900055494F50600D0A8CA8A9AAAB0000ADAC1E
|
||||
:1003A000B3978120939A8E8B2D372A382F39A0A0AE
|
||||
:1003B000343135323633A0A0302E2BA0A0A0A0A01F
|
||||
:1003C000A5A24153444647484A4B4C3B3A7FA6A519
|
||||
:1003D000A4A15A584356424E4D2C2E2FA180A0A0C6
|
||||
:1003E0001B313233343536373839302D5E5B5C5D46
|
||||
:1003F000B20951574552545955494F50400D0A8C36
|
||||
:10040000A8A9AAAB0000ADACB3978120939A8E8BBC
|
||||
:100410002D372A382F39A0A0343135323633A0A0F9
|
||||
:10042000302E2BA0A0A0A0A0A5A26173646667686F
|
||||
:100430006A6B6C3B3A7FA6A5A4A17A786376626E5C
|
||||
:100440006D2C2E2FA180A0A01B31323334353637CE
|
||||
:100450003839302D5E5B5C5DB209717765727479F5
|
||||
:1004600075696F70400D0A8CA8A9AAAB0000ADACED
|
||||
:10047000B3978120939A8E8B2D372A382F39A0A0DD
|
||||
:10048000343135323633A0A0302E2BA0A0A0A0A04E
|
||||
:1004900011241FBECFEFD8E0DEBFCDBF12E0A0E039
|
||||
:1004A000B1E0EAE1FAE102C005900D92A033B10794
|
||||
:1004B000D9F723E0A0E3B2E001C01D92A43CB2074B
|
||||
:1004C000E1F799D70C94DD0C9BCD805A813208F06E
|
||||
:1004D0000895E82FF0E0E152F34FAFC784E09BC2EC
|
||||
:1004E0008DE099C28CE097C28BE095C28AE093C2FE
|
||||
:1004F00089E091C288E08FC287E08DC286E08BC21E
|
||||
:1005000085E089C286E0E7C585E0E5C584E0E3C50E
|
||||
:1005100083E0E1C582E0DFC581E0DDC589E0DBC5C0
|
||||
:1005200088E0D9C587E0D7C56BC11FC5D7C396C3BF
|
||||
:1005300055C314C330C540C433C427C41EC417C434
|
||||
:10054000815A8D3008F00895E82FF0E0E050F34F25
|
||||
:1005500074C736C43AC437C5E1C220C35FC39EC363
|
||||
:10056000F0C451C1CF93C82F8A3041F06C2F8091D5
|
||||
:1005700032020CD28C2F90E0CF9108956DE08091E3
|
||||
:10058000320204D2F3CFCF938091320221D2C82F0E
|
||||
:10059000803A41F0809130029091310246D18C2F07
|
||||
:1005A000CF91089580913302CF9112C290E0909341
|
||||
:1005B00031028093300208955F926F927F928F9202
|
||||
:1005C0009F92AF92BF92CF92DF92EF92FF920F93E2
|
||||
:1005D0001F93CF93DF9381E02DD25C0183E01BD288
|
||||
:1005E00000E03AE0732E88248394912C50EA652E23
|
||||
:1005F00068D2081708F06BC0802FF5010995D82F35
|
||||
:10060000802F90E09C012B543D4F6901F90110812E
|
||||
:100610001D27C0E0880F991F880F991F880F991F09
|
||||
:100620009C012B5C3D4F790105C0811115C01695C9
|
||||
:10063000D695CF5F51D2C81708F044C08D2F817076
|
||||
:1006400010FFF3CFF701EC0FF11D90812FEF290F71
|
||||
:100650009130F9F02083EBCFBBD3482F6C2F802F44
|
||||
:100660005DD3909134029813E2CFBAD48823F9F283
|
||||
:1006700050903402F0EAF51510F1652D80913302A7
|
||||
:1006800085D180913402581691F25092340250D4A0
|
||||
:10069000CECF7082F601908194010C2E01C0220F02
|
||||
:1006A0000A94EAF7882319F1922B908391D3482F6B
|
||||
:1006B0006C2F802F33D3582EF0EAF817F0F6852DE3
|
||||
:1006C00004DFB5CF0F5FFDD1081708F495CFDF9198
|
||||
:1006D000CF911F910F91FF90EF90DF90CF90BF903F
|
||||
:1006E000AF909F908F907F906F905F90089520952E
|
||||
:1006F000292320836DD3482F6C2F802F0FD3813A6D
|
||||
:1007000038F490913402981392CF609234028FCFD4
|
||||
:1007100017DF8DCF80EA8093340204D1FAD3E7D17A
|
||||
:1007200080E190E006D18093330280E890E001D12F
|
||||
:1007300080933202E5EBF2E080E1DF011D928A95C1
|
||||
:10074000E9F740E850E06AE070E085E392E08FC6A8
|
||||
:100750008F9381E08093C6028F9118958091C60295
|
||||
:100760001092C6020895882311F044980895449A7F
|
||||
:100770000895882311F02D9A08952D9808958823BF
|
||||
:1007800011F02C9A08952C980895882319F0459A11
|
||||
:100790003D9A089545983D9A0895882319F03D980B
|
||||
:1007A000459A089545983D9A0895882319F0459AE9
|
||||
:1007B0003D9A08953D9845980895882319F02B98FF
|
||||
:1007C000239A08952B9A239A0895089508950895D9
|
||||
:1007D000882319F02F9A279A08952F98279A089519
|
||||
:1007E000882319F027982F9A08952F98279A08950B
|
||||
:1007F000882319F02F9A279A089527982F980895FB
|
||||
:100800002E98269A08952E9A269A08958AE18A9516
|
||||
:10081000F1F700C008952FE788E391E02150804070
|
||||
:100820009040E1F700C0000008959C01892B61F021
|
||||
:1008300090E080E0EFECF7E03197F1F700C00000C6
|
||||
:10084000019628173907B1F70895F8941092C60257
|
||||
:1008500087E0809361001092C6028CE787BD15BCCB
|
||||
:1008600082E084BD80936E0083E085BD8091C502E7
|
||||
:100870008BB98FEF8AB91092C5022E98269A3C9AAE
|
||||
:10088000259A249A3C9A259A249A88B1807F88B91F
|
||||
:1008900087B18F6087B92A98229A299A219A20983D
|
||||
:1008A00028987894089598B1907F8F70982B98B974
|
||||
:1008B00029982A9A2A98299A30E020E080E093B17A
|
||||
:1008C0009095492F417050E0BA01022E01C0660F89
|
||||
:1008D0000A94EAF7862B2A9A2A982F5F3F4F2830EE
|
||||
:1008E000310569F708959091C50289278BB91E9A41
|
||||
:1008F0008AE18A95F1F700C01E9A0895833049F085
|
||||
:1009000028F4813041F0823029F4A0C4843011F4FD
|
||||
:1009100034C5CFC42CC45DC4982F81E0953008F055
|
||||
:1009200080E008951092C9021092C8021092C70286
|
||||
:1009300008959C018091C702843034F54091C8022B
|
||||
:100940005091C90260E970E0641B750B6217730770
|
||||
:10095000DCF091E0980F9093C70297E08902F001D4
|
||||
:100960001124E653FD4F33832283BA016A517D4F30
|
||||
:1009700071836083148215821682420F531F509335
|
||||
:10098000C9024093C80208958FEF089587FD1EC0E5
|
||||
:100990009091C7028917DCF497E08902F0011124D5
|
||||
:1009A000E653FD4F2681428153812417150674F4C6
|
||||
:1009B000848190E0A081B181A80FB91F6C9301964A
|
||||
:1009C000BA0128D584832F5F26830895089508955A
|
||||
:1009D00087FD04C09091C70289171CF030EA832F6D
|
||||
:1009E000089597E08902F0011124E653FD4F268116
|
||||
:1009F0002223A1F3858190E0A081B181A80FB91FC6
|
||||
:100A00003C9101966281738105D5858321502683AF
|
||||
:100A1000832F089508959FEF980F9D3050F4E82F8D
|
||||
:100A2000F0E0EE0FFF1FEA58FC4F0190F081E02D3F
|
||||
:100A3000099408959FEF980F9D3048F4E82FF0E057
|
||||
:100A4000EE0FFF1FEA58FC4F8081918108958AE0E4
|
||||
:100A500095E008959FEF980F9D3040F4E82FF0E067
|
||||
:100A6000EE0FFF1FEA58FC4F608371830895E6E79D
|
||||
:100A7000F3E08AE095E08193919323E0E239F20775
|
||||
:100A8000D1F783E594E0909379038093780383E72B
|
||||
:100A900094E090937B0380937A030895643080F40C
|
||||
:100AA000413170F4293060F4E62FF0E0EE0FFF1FC3
|
||||
:100AB000EE0FFF1FED56FC4F80839183428323830B
|
||||
:100AC000089586D1E82FF0E0EE0FFF1FEE0FFF1F15
|
||||
:100AD000ED56FC4F828108957BD1E82FF0E0EE0FB8
|
||||
:100AE000FF1FEE0FFF1FED56FC4F8381089580E03E
|
||||
:100AF00013DF811101C0089510929203A6DEE3E98D
|
||||
:100B0000F3E01182108212821382349683E0E33A7A
|
||||
:100B1000F807B9F70AD3ABDF80E0F0CECF9380912E
|
||||
:100B20009203C82FCE7F80FD02C0CF9108958C2FF5
|
||||
:100B3000F3DE8823D1F3C093920387DEE3E9F3E089
|
||||
:100B40001182108212821382349683E0E33AF8070E
|
||||
:100B5000B9F7EBD28CDF8C2FCF91D0CECF93809191
|
||||
:100B60009203C82FC16080FF02C0CF9108958C2FDF
|
||||
:100B7000D3DE8823D1F3C093920367DEE3E9F3E089
|
||||
:100B80001182108212821382349683E0E33AF807CE
|
||||
:100B9000B9F7CBD26CDF8C2FCF91B0CECF938091B1
|
||||
:100BA0009203C82FCD7F81FD02C0CF9108958C2F75
|
||||
:100BB000B3DE8823D1F3C093920347DEE3E9F3E089
|
||||
:100BC0001182108212821382349683E0E33AF8078E
|
||||
:100BD000B9F7ABD24CDF8C2FCF9190CECF938091D1
|
||||
:100BE0009203C82FC26081FF02C0CF9108958C2F5D
|
||||
:100BF00093DE8823D1F3C093920327DEE3E9F3E089
|
||||
:100C00001182108212821382349683E0E33AF8074D
|
||||
:100C1000B9F78BD22CDF8C2FCF9170CECF938091F0
|
||||
:100C20009203C82FCB7F82FD02C0CF9108958C2FF5
|
||||
:100C300073DE8823D1F3C093920307DEE3E9F3E088
|
||||
:100C40001182108212821382349683E0E33AF8070D
|
||||
:100C5000B9F76BD20CDF8C2FCF9150CECF93809110
|
||||
:100C60009203C82FC46082FF02C0CF9108958C2FD9
|
||||
:100C700053DE8823D1F3C0939203E7DDE3E9F3E089
|
||||
:100C80001182108212821382349683E0E33AF807CD
|
||||
:100C9000B9F74BD2ECDE8C2FCF9130CECF93809131
|
||||
:100CA0009203C82FC77F83FD02C0CF9108958C2F78
|
||||
:100CB00033DE8823D1F3C0939203C7DDE3E9F3E089
|
||||
:100CC0001182108212821382349683E0E33AF8078D
|
||||
:100CD000B9F72BD2CCDE8C2FCF9110CECF93809151
|
||||
:100CE0009203C82FC86083FF02C0CF9108958C2F54
|
||||
:100CF00013DE8823D1F3C0939203A7DDE3E9F3E089
|
||||
:100D00001182108212821382349683E0E33AF8074C
|
||||
:100D1000B9F70BD2ACDE8C2FCF91F0CD982FA091EC
|
||||
:100D20009203B0E0AA0FBB1FAA0FBB1FAD56BC4F6A
|
||||
:100D300013968C9113978823C9F012962C91222335
|
||||
:100D4000A1F0E42FF0E0EE0FFF1FEE0FFF1FED56B6
|
||||
:100D5000FC4F70E0899F600D711D11240190F0819E
|
||||
:100D6000E02DE60FF71F8491089580E0089581E05B
|
||||
:100D70008093A50362E08BE049C18091A503826066
|
||||
:100D80008093A50361E08BE041C18091A50392E0CF
|
||||
:100D900089278093A50362E081FD61E08BE036C185
|
||||
:100DA0009091A40381E089278093A40362E09130AD
|
||||
:100DB00009F061E08AE02AC181E08093A3030895ED
|
||||
:100DC0001092A50362E08BE021C11092A303089565
|
||||
:100DD000E1E08091A503811101C0E0E08091A403CE
|
||||
:100DE0008111E2608091A3038111E460F0E0EE5B89
|
||||
:100DF000FE4F80810895CF93DF93C82FD0E0CC0FB2
|
||||
:100E0000DD1FCC0FDD1FC050DF4FE881F98181E08D
|
||||
:100E1000099581E08A83DF91CF910895CF93DF9385
|
||||
:100E2000C82FD0E0CC0FDD1FCC0FDD1FC050DF4F2F
|
||||
:100E3000E881F98180E009951A82DF91CF910895C8
|
||||
:100E40001F93CF93DF93C82FD0E0CC0FDD1FCC0FC3
|
||||
:100E5000DD1FFE01E050FF4F11E08281811110E0A3
|
||||
:100E6000C050DF4FE881F981812F09951A83DF9106
|
||||
:100E7000CF911F910895E82FF0E0EE0FFF1FEE0FC6
|
||||
:100E8000FF1FE050FF4F83810895582F8091030189
|
||||
:100E9000882391F0581303C027C0581771F0282FEA
|
||||
:100EA00030E0982F220F331F220F331FF901E0503B
|
||||
:100EB000FF4F83818111F1CF089581508C30B8F4B8
|
||||
:100EC0009D30A9F0E52FF0E0EE0FFF1FEE0FFF1FA2
|
||||
:100ED000E050FF4F838120503F4FD90113968C93F0
|
||||
:100EE0006383428381E0089581508C3010F080E06C
|
||||
:100EF000089530E020E0E6CFE2E0F1E080E091E02C
|
||||
:100F000090838F5F818334968D30D1F710923301B7
|
||||
:100F100008958DE092E09093A9038093A8039093A5
|
||||
:100F2000AB038093AA039093A7038093A60308952D
|
||||
:100F30008091AA039091AB039093A7038093A6039B
|
||||
:100F400008951092A9031092A8038091AA0390918A
|
||||
:100F5000AB038234910541F01092AB031092AA03C7
|
||||
:100F60001092A7031092A60308958DE092E090934B
|
||||
:100F7000A9038093A8032091AA033091AB032234E4
|
||||
:100F8000310541F09093AB038093AA039093A7039C
|
||||
:100F90008093A60308958091A6039091A7038334BC
|
||||
:100FA000910530F48091AA039091AB03892B51F401
|
||||
:100FB00082E490E09093AB038093AA039093A703FD
|
||||
:100FC0008093A60308958091A8039091A90390931C
|
||||
:100FD000AB038093AA039093A7038093A60308957D
|
||||
:100FE0008091A6039091A703009771F0019741F4B7
|
||||
:100FF00082E490E09093A7038093A60381E0089594
|
||||
:101000009093A7038093A60380E00895CF93DF9386
|
||||
:10101000E82FF0E0EE0FFF1FE455FC4FC081633076
|
||||
:1010200051F180F0643009F43BC0653031F007C005
|
||||
:101030008C2F06DF8C2F1FDFC82FC111F9CFDF9156
|
||||
:10104000CF910895613091F0623031F0F8CF8C2F5C
|
||||
:10105000E5DE8C2F10DFC82FC111F9CFDF91CF91C2
|
||||
:1010600008958C2FC8DE8C2F06DFC82FC111F9CF51
|
||||
:10107000DF91CF910895DC2FCC2339F18D2FE0DE65
|
||||
:101080008D2FF9DED82F8111F9CFC0DB8C2FD8DE60
|
||||
:101090008C2FF1DEC82F8111F9CFDF91CF91089508
|
||||
:1010A000DC2FCC23A9F08D2FCBDE8D2FE4DED82FC3
|
||||
:1010B0008111F9CFB0DB8C2FC3DE8C2FDCDEC82F83
|
||||
:1010C0008111F9CFDF91CF910895DF91CF919ECB20
|
||||
:1010D000DF91CF91A0CBE82FF0E0EE0FFF1FE4559A
|
||||
:1010E000FC4F618193CF0F931F93CF93DF93162F04
|
||||
:1010F000042F9FEF980F9B3028F0DF91CF911F9125
|
||||
:101100000F910895C82FD0E0CC0FDD1FC455DC4FE0
|
||||
:10111000422F6881812FB9DE882379F318830983F0
|
||||
:10112000DF91CF911F910F910895E6DEECEAF3E095
|
||||
:1011300011821082329683E0E43CF807C9F70895E3
|
||||
:10114000CF93DF93CDB7DEB7FE01359661917191F4
|
||||
:10115000AF0184E391E092D1DF91CF9108958AE4C9
|
||||
:1011600091E09F938F93ECDF0F900F90089588E2AA
|
||||
:101170001DDA60E080E057D062E081E054D061E0A9
|
||||
:1011800082E051D063E083E04ED06FEA78E08DE0FA
|
||||
:1011900061DC63E879E08CE05DDC21E040E06AE05E
|
||||
:1011A00087E0A1DF20E040E06CE08AE09CDF21E006
|
||||
:1011B00043E068E081E097DF20E044E063E082E024
|
||||
:1011C00092CF8AE491E09F938F93BADF0F900F90B4
|
||||
:1011D000089588E2EBD960E081E025D062E081E00B
|
||||
:1011E00022D061E082E01FD063E083E01CD061EE9A
|
||||
:1011F00078E08DE02FDC63E879E08CE02BDC21E007
|
||||
:1012000040E06AE087E06FDF20E040E06CE087E0EC
|
||||
:101210006ADF21E043E068E081E065DF20E044E050
|
||||
:1012200063E082E060CFE82FF0E0EE0FFF1FE35AAB
|
||||
:10123000FE4F28E049E08081918130CC85E691E045
|
||||
:101240009F938F937DDF0F900F90089588E2AED922
|
||||
:1012500060E080E07FD062E081E07CD061E082E00D
|
||||
:1012600079D063E084E076D063E879E08CE0F2DB6B
|
||||
:101270006EE179E08DE0EEDB20E040E06AE08AE0BC
|
||||
:1012800032DF20E040E06CE088E02DDF21E043E049
|
||||
:1012900068E081E028DF20E044E063E082E023DFD3
|
||||
:1012A0007FCD82E891E09F938F934ADF0F900F905C
|
||||
:1012B000089588E27BD960E081E04CD062E081E073
|
||||
:1012C00049D061E083E046D063E084E043D063E846
|
||||
:1012D00079E08CE0BFDB61E579E08DE0BBDB20E00D
|
||||
:1012E00040E06AE087E0FFDE20E040E06CE088E07C
|
||||
:1012F000FADE21E043E068E081E0F5DE20E044E052
|
||||
:1013000063E082E0F0CE89E991E09F938F9318DF4C
|
||||
:1013100084EA91E09F938F9313DF84EB91E09F9396
|
||||
:101320008F930EDF8EED91E09F938F9309DF84EF13
|
||||
:1013300091E09F938F9304DF8AE092E09F938F93D5
|
||||
:10134000FFDE8DB79EB70C960FB6F8949EBF0FBE0A
|
||||
:101350008DBF0895E82FF0E0EE0FFF1FEA5EFD4F0E
|
||||
:1013600028E049E08081918199CB80E292E09F93CF
|
||||
:101370008F93E6DE0F900F90089528E04DE060E037
|
||||
:1013800088E294E08BDB28E04DE062E080EC93E0C3
|
||||
:1013900085DB28E04DE061E088E593E07FDB28E035
|
||||
:1013A0004DE063E080EF92E079DB88E2FFD820E057
|
||||
:1013B00040E06AE08AE097DE20E040E06CE08BE00D
|
||||
:1013C00092DE21E045E061E083E08DDE20E045E053
|
||||
:1013D0006BE083E088DE21E043E068E081E083DECB
|
||||
:1013E00021E044E064E082E07EDEDADC0CDA65EBEA
|
||||
:1013F00079E08DE02FCB8ED9B1D98823E9F3C3D81A
|
||||
:10140000C82F803A29F082E015DBFC018C2F09956A
|
||||
:10141000D3D8F2CF97FB072E16F4009406D077FDB1
|
||||
:1014200008D011D007FC05D03EF4909581959F4FD0
|
||||
:101430000895709561957F4F0895EE0FFF1F0590F9
|
||||
:10144000F491E02D0994AA1BBB1B51E107C0AA1F10
|
||||
:10145000BB1FA617B70710F0A61BB70B881F991F55
|
||||
:101460005A95A9F780959095BC01CD010895DC01AE
|
||||
:1014700001C06D9341505040E0F70895AFE0B0E0F7
|
||||
:10148000E3E4FAE063C27C013B018A01DC011796C8
|
||||
:101490001C921E92169713968C9181FFB0C19AE010
|
||||
:1014A000292EFE0131964F01D70113969C91F3012D
|
||||
:1014B00093FD859193FF81913F01882309F43AC1FF
|
||||
:1014C000853239F493FD859193FF81913F018532F7
|
||||
:1014D00021F4B70190E0ACD1E7CFB12C412C512CD5
|
||||
:1014E000BFE1B51538F08B3209F188F4803201F193
|
||||
:1014F000833221F157FC3AC020ED280F2A3040F505
|
||||
:1015000056FE1FC0B29C200D1124B22E06C08D3293
|
||||
:1015100091F0803379F7689450F8F30193FD859149
|
||||
:1015200093FF81913F018111DBCF20C0689451F876
|
||||
:10153000689452F8F2CF689453F8EFCF689454F857
|
||||
:10154000ECCF429C200D1124422E689455F8E5CF33
|
||||
:101550008E3229F456FCEEC0689456F8DECF8C36F5
|
||||
:1015600019F4689457F8D9CF8836B9F2982F9F7D2F
|
||||
:1015700095549330B8F0833671F1833791F1833508
|
||||
:1015800009F056C0D801CD90DD908D016B2D70E033
|
||||
:1015900056FC02C06FEF7FEFC60134D15C01689446
|
||||
:1015A00057F80AC00C5F1F4FEFE3E983AA24A39406
|
||||
:1015B000B12C6401E89457F853FE26C0342CA114D2
|
||||
:1015C000B10439F5332009F46FCFB70180E290E020
|
||||
:1015D0002FD13A94F7CFD8018C9189830E5F1F4F9A
|
||||
:1015E000E5CFF801C190D1908F016B2D70E056FCD2
|
||||
:1015F00002C06FEF7FEFC60110D15C01DBCFB701F6
|
||||
:1016000080E290E015D14A944A141B0409F0B8F71F
|
||||
:10161000D5CFF60157FC859157FE81916F01B70137
|
||||
:1016200090E006D131103A94B1E0AB1AB108C7CFBF
|
||||
:10163000843619F0893609F06DC0F80157FE63C091
|
||||
:1016400061917191819191918F01E52DEF76DE2E5F
|
||||
:1016500097FF09C090958095709561957F4F8F4F4A
|
||||
:101660009F4F6894D7F82AE030E0A40111D1C82E2A
|
||||
:10167000C818AC2C5D2CD6FE0CC0E89450F8CB14E6
|
||||
:1016800040F4D4FE05C0D2FC03C05D2D5E7E552E15
|
||||
:10169000AB2C54FE8EC0FE01EC0DF11D8081803319
|
||||
:1016A00009F080C0652D697E562E752D7870372E15
|
||||
:1016B00053FC8DC050FE87C0BC2CA41410F4B40C95
|
||||
:1016C000BA1854FE8AC0B70180E390E0B1D052FE50
|
||||
:1016D00006C088E751FC88E590E0B701A9D0CB149B
|
||||
:1016E00008F487C0CA94D12C8FEFC81AD80AC80C46
|
||||
:1016F000D91CD6018E916D01B70190E099D08C1460
|
||||
:101700009D04B9F75FCF61917191072E000C880B92
|
||||
:10171000990B9ACFD52CE894D4F82AE0853721F19B
|
||||
:10172000F52DF97FDF2E803799F050F4883599F048
|
||||
:101730008F36C9F0F701868197812F96E2E122C1A9
|
||||
:101740008837C1F7D4FE02C06894D2F820E10CC0FB
|
||||
:101750006894D4F8F7CF54FE03C02F2F2660D22E02
|
||||
:1017600020E132E002C028E030E0F801D7FE14C0EA
|
||||
:1017700041915191619171914C875D876E877F870F
|
||||
:101780008F01A4016C857D858E859F8581D0C82EB3
|
||||
:10179000C818E894D7F86DCF81919191AC0170E0B1
|
||||
:1017A00060E0EACF52FC02C0A3947FCFA394A3943D
|
||||
:1017B0007CCF852D867809F478CFF6CFB70180E20B
|
||||
:1017C00090E036D0A394A414C8F3312C7ACF342CF3
|
||||
:1017D0003A18A41408F475CFF8CF852D867809F44B
|
||||
:1017E0007ECF8BE251FE80E257FC8DE2B70190E0A4
|
||||
:1017F00075CFB70180E390E01BD0BA9470CF8FEF24
|
||||
:101800009FEF9BCFFC010590615070400110D8F70D
|
||||
:10181000809590958E0F9F1F0895FC016150704038
|
||||
:1018200001900110D8F7809590958E0F9F1F089515
|
||||
:101830000F931F93CF93DF93182F092FEB018B8109
|
||||
:1018400081FD09C01FEF0FEF812F902FDF91CF9106
|
||||
:101850001F910F91089582FF14C02E813F818C81CA
|
||||
:101860009D81281739073CF4E881F981CF01019661
|
||||
:101870009983888310838E819F8101969F838E83B5
|
||||
:10188000E3CFE885F985812F0995892BA1F3DACF7C
|
||||
:10189000FA01AA27283051F1203181F1E8946F93A1
|
||||
:1018A0006E7F6E5F7F4F8F4F9F4FAF4FB1E03ED047
|
||||
:1018B000B4E03CD0670F781F891F9A1FA11D680FE5
|
||||
:1018C000791F8A1F911DA11D6A0F711D811D911D18
|
||||
:1018D000A11D20D009F468943F912AE0269F11248D
|
||||
:1018E0003019305D3193DEF6CF010895462F4770F1
|
||||
:1018F000405D4193B3E00FD0C9F7F6CF462F4F704C
|
||||
:10190000405D4A3318F0495D31FD4052419302D0A9
|
||||
:10191000A9F7EACFB4E0A69597958795779567954F
|
||||
:10192000BA95C9F700976105710508959B01AC014F
|
||||
:101930000A2E06945795479537952795BA95C9F776
|
||||
:10194000620F731F841F951FA01D08952F923F9251
|
||||
:101950004F925F926F927F928F929F92AF92BF92BF
|
||||
:10196000CF92DF92EF92FF920F931F93CF93DF936B
|
||||
:10197000CDB7DEB7CA1BDB0B0FB6F894DEBF0FBEC8
|
||||
:10198000CDBF09942A88398848885F846E847D8415
|
||||
:101990008C849B84AA84B984C884DF80EE80FD8017
|
||||
:1019A0000C811B81AA81B981CE0FD11D0FB6F8948D
|
||||
:1019B000DEBF0FBECDBFED010895F894FFCF6E02DC
|
||||
:1019C0009F029E029D029C029B029A026E02990255
|
||||
:1019D00098029702960295029402920290028E0259
|
||||
:1019E0008C028A0288028602840282026E028002CF
|
||||
:1019F0007E027C027A02780276027402720270021F
|
||||
:101A0000A902A302A302A302AA02AB02A302AC0290
|
||||
:0A1A1000AD02AE02AF02B002B10257
|
||||
:101A1A00E5030000C5030000CD030000D503000064
|
||||
:101A2A00DD030000E6030000E7030000E80300000E
|
||||
:101A3A00F0030000F8030000B3030000B90300003C
|
||||
:101A4A00BF0300000000000200000000B202000014
|
||||
:101A5A00000000010201030303035B4B65796D611A
|
||||
:101A6A00703A20636C61737369635D0A004001B068
|
||||
:101A7A0000F80068005B4B65796D61703A2041702F
|
||||
:101A8A00706C6520322028752F6C2063617365297C
|
||||
:101A9A005D005B4B65796D61703A204170706C65D1
|
||||
:101AAA00203220434150535D0031302047455420B5
|
||||
:101ABA0041240D0032302041203D2041534328412A
|
||||
:101ACA0024290D0033302049462041203C2033325E
|
||||
:101ADA00205448454E2041243D2243544C2B222B6E
|
||||
:101AEA00434852242841202B203634290D00343013
|
||||
:101AFA00203F2227223B41243B2227203D20223B14
|
||||
:101B0A00413A0D0035302049462041203C3E2033E1
|
||||
:101B1A0020474F544F2031300D00363020454E4477
|
||||
:101B2A000D52554E0D00A802D0016002180288011C
|
||||
:101B3A005B4B657962643A20536F6C2D32305D00DD
|
||||
:00000001FF
|
|
@ -1,4 +1,4 @@
|
|||
Unified Retro Keyboard firmware (ASDF) rev @CMAKE_PROJECT_VERSION@
|
||||
Unified Retro Keyboard firmware (ASDF) rev 1.6.3
|
||||
=======================================================================
|
||||
|
||||
.. toctree::
|
|
@ -0,0 +1,7 @@
|
|||
.. _atmega2560 Rev 1.6.3:
|
||||
|
||||
ASDF Rev 1.6.3 hex file (atmega2560)
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
:ASDF Firmware 1.6.3-atmega2560:
|
||||
:download:`asdf-v1.6.3-atmega2560.hex`
|
|
@ -0,0 +1,7 @@
|
|||
.. _atmega328p Rev 1.6.3:
|
||||
|
||||
ASDF Rev 1.6.3 hex file (atmega328p)
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
:ASDF Firmware 1.6.3-atmega328p:
|
||||
:download:`asdf-v1.6.3-atmega328p.hex`
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* _sphinx_javascript_frameworks_compat.js
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* Compatability shim for jQuery and underscores.js.
|
||||
*
|
||||
* WILL BE REMOVED IN Sphinx 6.0
|
||||
* xref RemovedInSphinx60Warning
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* select a different prefix for underscore
|
||||
*/
|
||||
$u = _.noConflict();
|
||||
|
||||
|
||||
/**
|
||||
* small helper function to urldecode strings
|
||||
*
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
|
||||
*/
|
||||
jQuery.urldecode = function(x) {
|
||||
if (!x) {
|
||||
return x
|
||||
}
|
||||
return decodeURIComponent(x.replace(/\+/g, ' '));
|
||||
};
|
||||
|
||||
/**
|
||||
* small helper function to urlencode strings
|
||||
*/
|
||||
jQuery.urlencode = encodeURIComponent;
|
||||
|
||||
/**
|
||||
* This function returns the parsed url parameters of the
|
||||
* current request. Multiple values per key are supported,
|
||||
* it will always return arrays of strings for the value parts.
|
||||
*/
|
||||
jQuery.getQueryParameters = function(s) {
|
||||
if (typeof s === 'undefined')
|
||||
s = document.location.search;
|
||||
var parts = s.substr(s.indexOf('?') + 1).split('&');
|
||||
var result = {};
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var tmp = parts[i].split('=', 2);
|
||||
var key = jQuery.urldecode(tmp[0]);
|
||||
var value = jQuery.urldecode(tmp[1]);
|
||||
if (key in result)
|
||||
result[key].push(value);
|
||||
else
|
||||
result[key] = [value];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a jquery object by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
jQuery.fn.highlightText = function(text, className) {
|
||||
function highlight(node, addItems) {
|
||||
if (node.nodeType === 3) {
|
||||
var val = node.nodeValue;
|
||||
var pos = val.toLowerCase().indexOf(text);
|
||||
if (pos >= 0 &&
|
||||
!jQuery(node.parentNode).hasClass(className) &&
|
||||
!jQuery(node.parentNode).hasClass("nohighlight")) {
|
||||
var span;
|
||||
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.className = className;
|
||||
}
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling));
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
if (isInSVG) {
|
||||
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
||||
var bbox = node.parentElement.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute('class', className);
|
||||
addItems.push({
|
||||
"parent": node.parentNode,
|
||||
"target": rect});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!jQuery(node).is("button, select, textarea")) {
|
||||
jQuery.each(node.childNodes, function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
}
|
||||
}
|
||||
var addItems = [];
|
||||
var result = this.each(function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
for (var i = 0; i < addItems.length; ++i) {
|
||||
jQuery(addItems[i].parent).before(addItems[i].target);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
* backward compatibility for jQuery.browser
|
||||
* This will be supported until firefox bug is fixed.
|
||||
*/
|
||||
if (!jQuery.browser) {
|
||||
jQuery.uaMatch = function(ua) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(msie) ([\w.]+)/.exec(ua) ||
|
||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
browser: match[ 1 ] || "",
|
||||
version: match[ 2 ] || "0"
|
||||
};
|
||||
};
|
||||
jQuery.browser = {};
|
||||
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
|
||||
}
|
|
@ -0,0 +1,899 @@
|
|||
/*
|
||||
* basic.css
|
||||
* ~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- basic theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.section::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap : break-word;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox form.search {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="text"] {
|
||||
float: left;
|
||||
width: 80%;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
||||
float: left;
|
||||
width: 20%;
|
||||
border-left: none;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li p.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
table.indextable > tbody > tr > td > ul {
|
||||
padding-left: 0em;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
div.genindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* -- domain module index --------------------------------------------------- */
|
||||
|
||||
table.modindextable td {
|
||||
padding: 2px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
div.body {
|
||||
min-width: 360px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
a.brackets:before,
|
||||
span.brackets > a:before{
|
||||
content: "[";
|
||||
}
|
||||
|
||||
a.brackets:after,
|
||||
span.brackets > a:after {
|
||||
content: "]";
|
||||
}
|
||||
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink,
|
||||
caption:hover > a.headerlink,
|
||||
p.caption:hover > a.headerlink,
|
||||
div.code-block-caption:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.body p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.body td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.align-left, figure.align-left, .figure.align-left, object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
img.align-right, figure.align-right, .figure.align-right, object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
img.align-center, figure.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
img.align-default, figure.align-default, .figure.align-default {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-default {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar,
|
||||
aside.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
clear: right;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
div.admonition, div.topic, blockquote {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.body p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- content of sidebars/topics/admonitions -------------------------------- */
|
||||
|
||||
div.sidebar > :last-child,
|
||||
aside.sidebar > :last-child,
|
||||
div.topic > :last-child,
|
||||
div.admonition > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sidebar::after,
|
||||
aside.sidebar::after,
|
||||
div.topic::after,
|
||||
div.admonition::after,
|
||||
blockquote::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-default {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table caption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table caption span.caption-text {
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
table.citation td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
th > :first-child,
|
||||
td > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
th > :last-child,
|
||||
td > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* -- figures --------------------------------------------------------------- */
|
||||
|
||||
div.figure, figure {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div.figure p.caption, figcaption {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-number,
|
||||
figcaption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-text,
|
||||
figcaption span.caption-text {
|
||||
}
|
||||
|
||||
/* -- field list styles ----------------------------------------------------- */
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
/* -- hlist styles ---------------------------------------------------------- */
|
||||
|
||||
table.hlist {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
table.hlist td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -- object description styles --------------------------------------------- */
|
||||
|
||||
.sig {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
}
|
||||
|
||||
.sig-name, code.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sig-name {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
code.descname {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.sig-prename, code.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.sig-paren {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.sig-param.n {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* C++ specific styling */
|
||||
|
||||
.sig-inline.c-texpr,
|
||||
.sig-inline.cpp-texpr {
|
||||
font-family: unset;
|
||||
}
|
||||
|
||||
.sig.c .k, .sig.c .kt,
|
||||
.sig.cpp .k, .sig.cpp .kt {
|
||||
color: #0033B3;
|
||||
}
|
||||
|
||||
.sig.c .m,
|
||||
.sig.cpp .m {
|
||||
color: #1750EB;
|
||||
}
|
||||
|
||||
.sig.c .s, .sig.c .sc,
|
||||
.sig.cpp .s, .sig.cpp .sc {
|
||||
color: #067D17;
|
||||
}
|
||||
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha;
|
||||
}
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha;
|
||||
}
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman;
|
||||
}
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:first-child > :first-child,
|
||||
:not(li) > ul > li:first-child > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:last-child > :last-child,
|
||||
:not(li) > ul > li:last-child > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ol.simple ol p,
|
||||
ol.simple ul p,
|
||||
ul.simple ol p,
|
||||
ul.simple ul p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple > li:not(:first-child) > p,
|
||||
ul.simple > li:not(:first-child) > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple p,
|
||||
ul.simple p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
dl.footnote > dt,
|
||||
dl.citation > dt {
|
||||
float: left;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
dl.footnote > dd,
|
||||
dl.citation > dd {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl.footnote > dd:after,
|
||||
dl.citation > dd:after {
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
dl.field-list {
|
||||
display: grid;
|
||||
grid-template-columns: fit-content(30%) auto;
|
||||
}
|
||||
|
||||
dl.field-list > dt {
|
||||
font-weight: bold;
|
||||
word-break: break-word;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 5px;
|
||||
}
|
||||
dl.field-list > dt:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
|
||||
dl.field-list > dd {
|
||||
padding-left: 0.5em;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dl > dd:last-child,
|
||||
dl > dd:last-child > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt:target, span.highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
rect.highlighted {
|
||||
fill: #fbe54e;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.guilabel, .menuselection {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.accelerator {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.classifier {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.classifier:before {
|
||||
font-style: normal;
|
||||
margin: 0 0.5em;
|
||||
content: ":";
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
abbr, acronym {
|
||||
border-bottom: dotted 1px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
||||
}
|
||||
|
||||
pre, div[class*="highlight-"] {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
span.pre {
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
hyphens: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div[class*="highlight-"] {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td.code {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.highlight pre,
|
||||
table.highlighttable pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption + div {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption {
|
||||
margin-top: 1em;
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.code-block-caption code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos,
|
||||
span.linenos,
|
||||
div.highlight span.gp { /* gp: Generic.Prompt */
|
||||
user-select: none;
|
||||
-webkit-user-select: text; /* Safari fallback only */
|
||||
-webkit-user-select: none; /* Chrome/Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE10+ */
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-number {
|
||||
padding: 0.1em 0.3em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-text {
|
||||
}
|
||||
|
||||
div.literal-block-wrapper {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
code.xref, a code {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.body div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.eqno a.headerlink {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
div.math:hover a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* -- printout stylesheet --------------------------------------------------- */
|
||||
|
||||
@media print {
|
||||
div.document,
|
||||
div.documentwrapper,
|
||||
div.bodywrapper {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar,
|
||||
div.related,
|
||||
div.footer,
|
||||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* doctools.js
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* Base JavaScript utilities for all Sphinx HTML documentation.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const _ready = (callback) => {
|
||||
if (document.readyState !== "loading") {
|
||||
callback();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a node by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
const _highlight = (node, addItems, text, className) => {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const val = node.nodeValue;
|
||||
const parent = node.parentNode;
|
||||
const pos = val.toLowerCase().indexOf(text);
|
||||
if (
|
||||
pos >= 0 &&
|
||||
!parent.classList.contains(className) &&
|
||||
!parent.classList.contains("nohighlight")
|
||||
) {
|
||||
let span;
|
||||
|
||||
const closestNode = parent.closest("body, svg, foreignObject");
|
||||
const isInSVG = closestNode && closestNode.matches("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.classList.add(className);
|
||||
}
|
||||
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
parent.insertBefore(
|
||||
span,
|
||||
parent.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling
|
||||
)
|
||||
);
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
|
||||
if (isInSVG) {
|
||||
const rect = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"rect"
|
||||
);
|
||||
const bbox = parent.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute("class", className);
|
||||
addItems.push({ parent: parent, target: rect });
|
||||
}
|
||||
}
|
||||
} else if (node.matches && !node.matches("button, select, textarea")) {
|
||||
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
|
||||
}
|
||||
};
|
||||
const _highlightText = (thisNode, text, className) => {
|
||||
let addItems = [];
|
||||
_highlight(thisNode, addItems, text, className);
|
||||
addItems.forEach((obj) =>
|
||||
obj.parent.insertAdjacentElement("beforebegin", obj.target)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Small JavaScript module for the documentation.
|
||||
*/
|
||||
const Documentation = {
|
||||
init: () => {
|
||||
Documentation.highlightSearchWords();
|
||||
Documentation.initDomainIndexTable();
|
||||
Documentation.initOnKeyListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
* i18n support
|
||||
*/
|
||||
TRANSLATIONS: {},
|
||||
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
|
||||
LOCALE: "unknown",
|
||||
|
||||
// gettext and ngettext don't access this so that the functions
|
||||
// can safely bound to a different name (_ = Documentation.gettext)
|
||||
gettext: (string) => {
|
||||
const translated = Documentation.TRANSLATIONS[string];
|
||||
switch (typeof translated) {
|
||||
case "undefined":
|
||||
return string; // no translation
|
||||
case "string":
|
||||
return translated; // translation exists
|
||||
default:
|
||||
return translated[0]; // (singular, plural) translation tuple exists
|
||||
}
|
||||
},
|
||||
|
||||
ngettext: (singular, plural, n) => {
|
||||
const translated = Documentation.TRANSLATIONS[singular];
|
||||
if (typeof translated !== "undefined")
|
||||
return translated[Documentation.PLURAL_EXPR(n)];
|
||||
return n === 1 ? singular : plural;
|
||||
},
|
||||
|
||||
addTranslations: (catalog) => {
|
||||
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
|
||||
Documentation.PLURAL_EXPR = new Function(
|
||||
"n",
|
||||
`return (${catalog.plural_expr})`
|
||||
);
|
||||
Documentation.LOCALE = catalog.locale;
|
||||
},
|
||||
|
||||
/**
|
||||
* highlight the search words provided in the url in the text
|
||||
*/
|
||||
highlightSearchWords: () => {
|
||||
const highlight =
|
||||
new URLSearchParams(window.location.search).get("highlight") || "";
|
||||
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
|
||||
if (terms.length === 0) return; // nothing to do
|
||||
|
||||
// There should never be more than one element matching "div.body"
|
||||
const divBody = document.querySelectorAll("div.body");
|
||||
const body = divBody.length ? divBody[0] : document.querySelector("body");
|
||||
window.setTimeout(() => {
|
||||
terms.forEach((term) => _highlightText(body, term, "highlighted"));
|
||||
}, 10);
|
||||
|
||||
const searchBox = document.getElementById("searchbox");
|
||||
if (searchBox === null) return;
|
||||
searchBox.appendChild(
|
||||
document
|
||||
.createRange()
|
||||
.createContextualFragment(
|
||||
'<p class="highlight-link">' +
|
||||
'<a href="javascript:Documentation.hideSearchWords()">' +
|
||||
Documentation.gettext("Hide Search Matches") +
|
||||
"</a></p>"
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to hide the search marks again
|
||||
*/
|
||||
hideSearchWords: () => {
|
||||
document
|
||||
.querySelectorAll("#searchbox .highlight-link")
|
||||
.forEach((el) => el.remove());
|
||||
document
|
||||
.querySelectorAll("span.highlighted")
|
||||
.forEach((el) => el.classList.remove("highlighted"));
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.delete("highlight");
|
||||
window.history.replaceState({}, "", url);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to focus on search bar
|
||||
*/
|
||||
focusSearchBar: () => {
|
||||
document.querySelectorAll("input[name=q]")[0]?.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialise the domain index toggle buttons
|
||||
*/
|
||||
initDomainIndexTable: () => {
|
||||
const toggler = (el) => {
|
||||
const idNumber = el.id.substr(7);
|
||||
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
|
||||
if (el.src.substr(-9) === "minus.png") {
|
||||
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = "none"));
|
||||
} else {
|
||||
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = ""));
|
||||
}
|
||||
};
|
||||
|
||||
const togglerElements = document.querySelectorAll("img.toggler");
|
||||
togglerElements.forEach((el) =>
|
||||
el.addEventListener("click", (event) => toggler(event.currentTarget))
|
||||
);
|
||||
togglerElements.forEach((el) => (el.style.display = ""));
|
||||
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
|
||||
},
|
||||
|
||||
initOnKeyListeners: () => {
|
||||
// only install a listener if it is really needed
|
||||
if (
|
||||
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
|
||||
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
|
||||
)
|
||||
return;
|
||||
|
||||
const blacklistedElements = new Set([
|
||||
"TEXTAREA",
|
||||
"INPUT",
|
||||
"SELECT",
|
||||
"BUTTON",
|
||||
]);
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
|
||||
|
||||
if (!event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case "ArrowLeft":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const prevLink = document.querySelector('link[rel="prev"]');
|
||||
if (prevLink && prevLink.href) {
|
||||
window.location.href = prevLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "ArrowRight":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const nextLink = document.querySelector('link[rel="next"]');
|
||||
if (nextLink && nextLink.href) {
|
||||
window.location.href = nextLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.hideSearchWords();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// some keyboard layouts may need Shift to get /
|
||||
switch (event.key) {
|
||||
case "/":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.focusSearchBar();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// quick alias for translations
|
||||
const _ = Documentation.gettext;
|
||||
|
||||
_ready(Documentation.init);
|
|
@ -0,0 +1,14 @@
|
|||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '',
|
||||
LANGUAGE: 'en',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
FILE_SUFFIX: '.html',
|
||||
LINK_SUFFIX: '.html',
|
||||
HAS_SOURCE: true,
|
||||
SOURCELINK_SUFFIX: '.txt',
|
||||
NAVIGATION_WITH_KEYS: false,
|
||||
SHOW_SEARCH_SUMMARY: true,
|
||||
ENABLE_SEARCH_SHORTCUTS: true,
|
||||
};
|
Binary file not shown.
After Width: | Height: | Size: 286 B |
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* language_data.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This script contains the language-specific data used by searchtools.js,
|
||||
* namely the list of stopwords, stemmer, scorer and splitter.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
|
||||
|
||||
|
||||
/* Non-minified version is copied as a separate JS file, is available */
|
||||
|
||||
/**
|
||||
* Porter Stemmer
|
||||
*/
|
||||
var Stemmer = function() {
|
||||
|
||||
var step2list = {
|
||||
ational: 'ate',
|
||||
tional: 'tion',
|
||||
enci: 'ence',
|
||||
anci: 'ance',
|
||||
izer: 'ize',
|
||||
bli: 'ble',
|
||||
alli: 'al',
|
||||
entli: 'ent',
|
||||
eli: 'e',
|
||||
ousli: 'ous',
|
||||
ization: 'ize',
|
||||
ation: 'ate',
|
||||
ator: 'ate',
|
||||
alism: 'al',
|
||||
iveness: 'ive',
|
||||
fulness: 'ful',
|
||||
ousness: 'ous',
|
||||
aliti: 'al',
|
||||
iviti: 'ive',
|
||||
biliti: 'ble',
|
||||
logi: 'log'
|
||||
};
|
||||
|
||||
var step3list = {
|
||||
icate: 'ic',
|
||||
ative: '',
|
||||
alize: 'al',
|
||||
iciti: 'ic',
|
||||
ical: 'ic',
|
||||
ful: '',
|
||||
ness: ''
|
||||
};
|
||||
|
||||
var c = "[^aeiou]"; // consonant
|
||||
var v = "[aeiouy]"; // vowel
|
||||
var C = c + "[^aeiouy]*"; // consonant sequence
|
||||
var V = v + "[aeiou]*"; // vowel sequence
|
||||
|
||||
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
|
||||
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
|
||||
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
|
||||
var s_v = "^(" + C + ")?" + v; // vowel in stem
|
||||
|
||||
this.stemWord = function (w) {
|
||||
var stem;
|
||||
var suffix;
|
||||
var firstch;
|
||||
var origword = w;
|
||||
|
||||
if (w.length < 3)
|
||||
return w;
|
||||
|
||||
var re;
|
||||
var re2;
|
||||
var re3;
|
||||
var re4;
|
||||
|
||||
firstch = w.substr(0,1);
|
||||
if (firstch == "y")
|
||||
w = firstch.toUpperCase() + w.substr(1);
|
||||
|
||||
// Step 1a
|
||||
re = /^(.+?)(ss|i)es$/;
|
||||
re2 = /^(.+?)([^s])s$/;
|
||||
|
||||
if (re.test(w))
|
||||
w = w.replace(re,"$1$2");
|
||||
else if (re2.test(w))
|
||||
w = w.replace(re2,"$1$2");
|
||||
|
||||
// Step 1b
|
||||
re = /^(.+?)eed$/;
|
||||
re2 = /^(.+?)(ed|ing)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(fp[1])) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1];
|
||||
re2 = new RegExp(s_v);
|
||||
if (re2.test(stem)) {
|
||||
w = stem;
|
||||
re2 = /(at|bl|iz)$/;
|
||||
re3 = new RegExp("([^aeiouylsz])\\1$");
|
||||
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re2.test(w))
|
||||
w = w + "e";
|
||||
else if (re3.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
else if (re4.test(w))
|
||||
w = w + "e";
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1c
|
||||
re = /^(.+?)y$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(s_v);
|
||||
if (re.test(stem))
|
||||
w = stem + "i";
|
||||
}
|
||||
|
||||
// Step 2
|
||||
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step2list[suffix];
|
||||
}
|
||||
|
||||
// Step 3
|
||||
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step3list[suffix];
|
||||
}
|
||||
|
||||
// Step 4
|
||||
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
|
||||
re2 = /^(.+?)(s|t)(ion)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
if (re.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1] + fp[2];
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re2.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
re = /^(.+?)e$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
re2 = new RegExp(meq1);
|
||||
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
|
||||
w = stem;
|
||||
}
|
||||
re = /ll$/;
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re.test(w) && re2.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
|
||||
// and turn initial Y back to y
|
||||
if (firstch == "y")
|
||||
w = firstch.toLowerCase() + w.substr(1);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 90 B |
Binary file not shown.
After Width: | Height: | Size: 90 B |
|
@ -0,0 +1,74 @@
|
|||
pre { line-height: 125%; }
|
||||
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
|
||||
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
|
||||
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #E40000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #008400 } /* Generic.Inserted */
|
||||
.highlight .go { color: #717171 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #687822 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #767600 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* searchtools.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx JavaScript utilities for the full-text search.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Simple result scoring code.
|
||||
*/
|
||||
if (typeof Scorer === "undefined") {
|
||||
var Scorer = {
|
||||
// Implement the following function to further tweak the score for each result
|
||||
// The function takes a result array [docname, title, anchor, descr, score, filename]
|
||||
// and returns the new score.
|
||||
/*
|
||||
score: result => {
|
||||
const [docname, title, anchor, descr, score, filename] = result
|
||||
return score
|
||||
},
|
||||
*/
|
||||
|
||||
// query matches the full name of an object
|
||||
objNameMatch: 11,
|
||||
// or matches in the last dotted part of the object name
|
||||
objPartialMatch: 6,
|
||||
// Additive scores depending on the priority of the object
|
||||
objPrio: {
|
||||
0: 15, // used to be importantResults
|
||||
1: 5, // used to be objectResults
|
||||
2: -5, // used to be unimportantResults
|
||||
},
|
||||
// Used when the priority is not in the mapping.
|
||||
objPrioDefault: 0,
|
||||
|
||||
// query found in title
|
||||
title: 15,
|
||||
partialTitle: 7,
|
||||
// query found in terms
|
||||
term: 5,
|
||||
partialTerm: 2,
|
||||
};
|
||||
}
|
||||
|
||||
const _removeChildren = (element) => {
|
||||
while (element && element.lastChild) element.removeChild(element.lastChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
||||
*/
|
||||
const _escapeRegExp = (string) =>
|
||||
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
|
||||
const _displayItem = (item, highlightTerms, searchTerms) => {
|
||||
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
|
||||
const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
|
||||
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
|
||||
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
|
||||
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
|
||||
|
||||
const [docName, title, anchor, descr] = item;
|
||||
|
||||
let listItem = document.createElement("li");
|
||||
let requestUrl;
|
||||
let linkUrl;
|
||||
if (docBuilder === "dirhtml") {
|
||||
// dirhtml builder
|
||||
let dirname = docName + "/";
|
||||
if (dirname.match(/\/index\/$/))
|
||||
dirname = dirname.substring(0, dirname.length - 6);
|
||||
else if (dirname === "index/") dirname = "";
|
||||
requestUrl = docUrlRoot + dirname;
|
||||
linkUrl = requestUrl;
|
||||
} else {
|
||||
// normal html builders
|
||||
requestUrl = docUrlRoot + docName + docFileSuffix;
|
||||
linkUrl = docName + docLinkSuffix;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.set("highlight", [...highlightTerms].join(" "));
|
||||
let linkEl = listItem.appendChild(document.createElement("a"));
|
||||
linkEl.href = linkUrl + "?" + params.toString() + anchor;
|
||||
linkEl.innerHTML = title;
|
||||
if (descr)
|
||||
listItem.appendChild(document.createElement("span")).innerHTML =
|
||||
" (" + descr + ")";
|
||||
else if (showSearchSummary)
|
||||
fetch(requestUrl)
|
||||
.then((responseData) => responseData.text())
|
||||
.then((data) => {
|
||||
if (data)
|
||||
listItem.appendChild(
|
||||
Search.makeSearchSummary(data, searchTerms, highlightTerms)
|
||||
);
|
||||
});
|
||||
Search.output.appendChild(listItem);
|
||||
};
|
||||
const _finishSearch = (resultCount) => {
|
||||
Search.stopPulse();
|
||||
Search.title.innerText = _("Search Results");
|
||||
if (!resultCount)
|
||||
Search.status.innerText = Documentation.gettext(
|
||||
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
|
||||
);
|
||||
else
|
||||
Search.status.innerText = _(
|
||||
`Search finished, found ${resultCount} page(s) matching the search query.`
|
||||
);
|
||||
};
|
||||
const _displayNextItem = (
|
||||
results,
|
||||
resultCount,
|
||||
highlightTerms,
|
||||
searchTerms
|
||||
) => {
|
||||
// results left, load the summary and display it
|
||||
// this is intended to be dynamic (don't sub resultsCount)
|
||||
if (results.length) {
|
||||
_displayItem(results.pop(), highlightTerms, searchTerms);
|
||||
setTimeout(
|
||||
() => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
|
||||
5
|
||||
);
|
||||
}
|
||||
// search finished, update title and status message
|
||||
else _finishSearch(resultCount);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
|
||||
* custom function per language.
|
||||
*
|
||||
* The regular expression works by splitting the string on consecutive characters
|
||||
* that are not Unicode letters, numbers, underscores, or emoji characters.
|
||||
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
|
||||
*/
|
||||
if (typeof splitQuery === "undefined") {
|
||||
var splitQuery = (query) => query
|
||||
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
|
||||
.filter(term => term) // remove remaining empty strings
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Module
|
||||
*/
|
||||
const Search = {
|
||||
_index: null,
|
||||
_queued_query: null,
|
||||
_pulse_status: -1,
|
||||
|
||||
htmlToText: (htmlString) => {
|
||||
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
|
||||
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
|
||||
const docContent = htmlElement.querySelector('[role="main"]');
|
||||
if (docContent !== undefined) return docContent.textContent;
|
||||
console.warn(
|
||||
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
|
||||
);
|
||||
return "";
|
||||
},
|
||||
|
||||
init: () => {
|
||||
const query = new URLSearchParams(window.location.search).get("q");
|
||||
document
|
||||
.querySelectorAll('input[name="q"]')
|
||||
.forEach((el) => (el.value = query));
|
||||
if (query) Search.performSearch(query);
|
||||
},
|
||||
|
||||
loadIndex: (url) =>
|
||||
(document.body.appendChild(document.createElement("script")).src = url),
|
||||
|
||||
setIndex: (index) => {
|
||||
Search._index = index;
|
||||
if (Search._queued_query !== null) {
|
||||
const query = Search._queued_query;
|
||||
Search._queued_query = null;
|
||||
Search.query(query);
|
||||
}
|
||||
},
|
||||
|
||||
hasIndex: () => Search._index !== null,
|
||||
|
||||
deferQuery: (query) => (Search._queued_query = query),
|
||||
|
||||
stopPulse: () => (Search._pulse_status = -1),
|
||||
|
||||
startPulse: () => {
|
||||
if (Search._pulse_status >= 0) return;
|
||||
|
||||
const pulse = () => {
|
||||
Search._pulse_status = (Search._pulse_status + 1) % 4;
|
||||
Search.dots.innerText = ".".repeat(Search._pulse_status);
|
||||
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
|
||||
};
|
||||
pulse();
|
||||
},
|
||||
|
||||
/**
|
||||
* perform a search for something (or wait until index is loaded)
|
||||
*/
|
||||
performSearch: (query) => {
|
||||
// create the required interface elements
|
||||
const searchText = document.createElement("h2");
|
||||
searchText.textContent = _("Searching");
|
||||
const searchSummary = document.createElement("p");
|
||||
searchSummary.classList.add("search-summary");
|
||||
searchSummary.innerText = "";
|
||||
const searchList = document.createElement("ul");
|
||||
searchList.classList.add("search");
|
||||
|
||||
const out = document.getElementById("search-results");
|
||||
Search.title = out.appendChild(searchText);
|
||||
Search.dots = Search.title.appendChild(document.createElement("span"));
|
||||
Search.status = out.appendChild(searchSummary);
|
||||
Search.output = out.appendChild(searchList);
|
||||
|
||||
const searchProgress = document.getElementById("search-progress");
|
||||
// Some themes don't use the search progress node
|
||||
if (searchProgress) {
|
||||
searchProgress.innerText = _("Preparing search...");
|
||||
}
|
||||
Search.startPulse();
|
||||
|
||||
// index already loaded, the browser was quick!
|
||||
if (Search.hasIndex()) Search.query(query);
|
||||
else Search.deferQuery(query);
|
||||
},
|
||||
|
||||
/**
|
||||
* execute search (requires search index to be loaded)
|
||||
*/
|
||||
query: (query) => {
|
||||
// stem the search terms and add them to the correct list
|
||||
const stemmer = new Stemmer();
|
||||
const searchTerms = new Set();
|
||||
const excludedTerms = new Set();
|
||||
const highlightTerms = new Set();
|
||||
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
|
||||
splitQuery(query.trim()).forEach((queryTerm) => {
|
||||
const queryTermLower = queryTerm.toLowerCase();
|
||||
|
||||
// maybe skip this "word"
|
||||
// stopwords array is from language_data.js
|
||||
if (
|
||||
stopwords.indexOf(queryTermLower) !== -1 ||
|
||||
queryTerm.match(/^\d+$/)
|
||||
)
|
||||
return;
|
||||
|
||||
// stem the word
|
||||
let word = stemmer.stemWord(queryTermLower);
|
||||
// select the correct list
|
||||
if (word[0] === "-") excludedTerms.add(word.substr(1));
|
||||
else {
|
||||
searchTerms.add(word);
|
||||
highlightTerms.add(queryTermLower);
|
||||
}
|
||||
});
|
||||
|
||||
// console.debug("SEARCH: searching for:");
|
||||
// console.info("required: ", [...searchTerms]);
|
||||
// console.info("excluded: ", [...excludedTerms]);
|
||||
|
||||
// array of [docname, title, anchor, descr, score, filename]
|
||||
let results = [];
|
||||
_removeChildren(document.getElementById("search-progress"));
|
||||
|
||||
// lookup as object
|
||||
objectTerms.forEach((term) =>
|
||||
results.push(...Search.performObjectSearch(term, objectTerms))
|
||||
);
|
||||
|
||||
// lookup as search terms in fulltext
|
||||
results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
|
||||
|
||||
// let the scorer override scores with a custom scoring function
|
||||
if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
|
||||
|
||||
// now sort the results by score (in opposite order of appearance, since the
|
||||
// display function below uses pop() to retrieve items) and then
|
||||
// alphabetically
|
||||
results.sort((a, b) => {
|
||||
const leftScore = a[4];
|
||||
const rightScore = b[4];
|
||||
if (leftScore === rightScore) {
|
||||
// same score: sort alphabetically
|
||||
const leftTitle = a[1].toLowerCase();
|
||||
const rightTitle = b[1].toLowerCase();
|
||||
if (leftTitle === rightTitle) return 0;
|
||||
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
|
||||
}
|
||||
return leftScore > rightScore ? 1 : -1;
|
||||
});
|
||||
|
||||
// remove duplicate search results
|
||||
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
|
||||
let seen = new Set();
|
||||
results = results.reverse().reduce((acc, result) => {
|
||||
let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
|
||||
if (!seen.has(resultStr)) {
|
||||
acc.push(result);
|
||||
seen.add(resultStr);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
results = results.reverse();
|
||||
|
||||
// for debugging
|
||||
//Search.lastresults = results.slice(); // a copy
|
||||
// console.info("search results:", Search.lastresults);
|
||||
|
||||
// print the results
|
||||
_displayNextItem(results, results.length, highlightTerms, searchTerms);
|
||||
},
|
||||
|
||||
/**
|
||||
* search for object names
|
||||
*/
|
||||
performObjectSearch: (object, objectTerms) => {
|
||||
const filenames = Search._index.filenames;
|
||||
const docNames = Search._index.docnames;
|
||||
const objects = Search._index.objects;
|
||||
const objNames = Search._index.objnames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const results = [];
|
||||
|
||||
const objectSearchCallback = (prefix, match) => {
|
||||
const name = match[4]
|
||||
const fullname = (prefix ? prefix + "." : "") + name;
|
||||
const fullnameLower = fullname.toLowerCase();
|
||||
if (fullnameLower.indexOf(object) < 0) return;
|
||||
|
||||
let score = 0;
|
||||
const parts = fullnameLower.split(".");
|
||||
|
||||
// check for different match types: exact matches of full name or
|
||||
// "last name" (i.e. last dotted part)
|
||||
if (fullnameLower === object || parts.slice(-1)[0] === object)
|
||||
score += Scorer.objNameMatch;
|
||||
else if (parts.slice(-1)[0].indexOf(object) > -1)
|
||||
score += Scorer.objPartialMatch; // matches in last name
|
||||
|
||||
const objName = objNames[match[1]][2];
|
||||
const title = titles[match[0]];
|
||||
|
||||
// If more than one term searched for, we require other words to be
|
||||
// found in the name/title/description
|
||||
const otherTerms = new Set(objectTerms);
|
||||
otherTerms.delete(object);
|
||||
if (otherTerms.size > 0) {
|
||||
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
|
||||
if (
|
||||
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
let anchor = match[3];
|
||||
if (anchor === "") anchor = fullname;
|
||||
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
|
||||
|
||||
const descr = objName + _(", in ") + title;
|
||||
|
||||
// add custom score for some objects according to scorer
|
||||
if (Scorer.objPrio.hasOwnProperty(match[2]))
|
||||
score += Scorer.objPrio[match[2]];
|
||||
else score += Scorer.objPrioDefault;
|
||||
|
||||
results.push([
|
||||
docNames[match[0]],
|
||||
fullname,
|
||||
"#" + anchor,
|
||||
descr,
|
||||
score,
|
||||
filenames[match[0]],
|
||||
]);
|
||||
};
|
||||
Object.keys(objects).forEach((prefix) =>
|
||||
objects[prefix].forEach((array) =>
|
||||
objectSearchCallback(prefix, array)
|
||||
)
|
||||
);
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* search for full-text terms in the index
|
||||
*/
|
||||
performTermsSearch: (searchTerms, excludedTerms) => {
|
||||
// prepare search
|
||||
const terms = Search._index.terms;
|
||||
const titleTerms = Search._index.titleterms;
|
||||
const docNames = Search._index.docnames;
|
||||
const filenames = Search._index.filenames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const scoreMap = new Map();
|
||||
const fileMap = new Map();
|
||||
|
||||
// perform the search on the required terms
|
||||
searchTerms.forEach((word) => {
|
||||
const files = [];
|
||||
const arr = [
|
||||
{ files: terms[word], score: Scorer.term },
|
||||
{ files: titleTerms[word], score: Scorer.title },
|
||||
];
|
||||
// add support for partial matches
|
||||
if (word.length > 2) {
|
||||
const escapedWord = _escapeRegExp(word);
|
||||
Object.keys(terms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !terms[word])
|
||||
arr.push({ files: terms[term], score: Scorer.partialTerm });
|
||||
});
|
||||
Object.keys(titleTerms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !titleTerms[word])
|
||||
arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
|
||||
});
|
||||
}
|
||||
|
||||
// no match but word was a required one
|
||||
if (arr.every((record) => record.files === undefined)) return;
|
||||
|
||||
// found search word in contents
|
||||
arr.forEach((record) => {
|
||||
if (record.files === undefined) return;
|
||||
|
||||
let recordFiles = record.files;
|
||||
if (recordFiles.length === undefined) recordFiles = [recordFiles];
|
||||
files.push(...recordFiles);
|
||||
|
||||
// set score for the word in each file
|
||||
recordFiles.forEach((file) => {
|
||||
if (!scoreMap.has(file)) scoreMap.set(file, {});
|
||||
scoreMap.get(file)[word] = record.score;
|
||||
});
|
||||
});
|
||||
|
||||
// create the mapping
|
||||
files.forEach((file) => {
|
||||
if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
|
||||
fileMap.get(file).push(word);
|
||||
else fileMap.set(file, [word]);
|
||||
});
|
||||
});
|
||||
|
||||
// now check if the files don't contain excluded terms
|
||||
const results = [];
|
||||
for (const [file, wordList] of fileMap) {
|
||||
// check if all requirements are matched
|
||||
|
||||
// as search terms with length < 3 are discarded
|
||||
const filteredTermCount = [...searchTerms].filter(
|
||||
(term) => term.length > 2
|
||||
).length;
|
||||
if (
|
||||
wordList.length !== searchTerms.size &&
|
||||
wordList.length !== filteredTermCount
|
||||
)
|
||||
continue;
|
||||
|
||||
// ensure that none of the excluded terms is in the search result
|
||||
if (
|
||||
[...excludedTerms].some(
|
||||
(term) =>
|
||||
terms[term] === file ||
|
||||
titleTerms[term] === file ||
|
||||
(terms[term] || []).includes(file) ||
|
||||
(titleTerms[term] || []).includes(file)
|
||||
)
|
||||
)
|
||||
break;
|
||||
|
||||
// select one (max) score for the file.
|
||||
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
|
||||
// add result to the result list
|
||||
results.push([
|
||||
docNames[file],
|
||||
titles[file],
|
||||
"",
|
||||
null,
|
||||
score,
|
||||
filenames[file],
|
||||
]);
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to return a node containing the
|
||||
* search summary for a given text. keywords is a list
|
||||
* of stemmed words, highlightWords is the list of normal, unstemmed
|
||||
* words. the first one is used to find the occurrence, the
|
||||
* latter for highlighting it.
|
||||
*/
|
||||
makeSearchSummary: (htmlText, keywords, highlightWords) => {
|
||||
const text = Search.htmlToText(htmlText);
|
||||
if (text === "") return null;
|
||||
|
||||
const textLower = text.toLowerCase();
|
||||
const actualStartPosition = [...keywords]
|
||||
.map((k) => textLower.indexOf(k.toLowerCase()))
|
||||
.filter((i) => i > -1)
|
||||
.slice(-1)[0];
|
||||
const startWithContext = Math.max(actualStartPosition - 120, 0);
|
||||
|
||||
const top = startWithContext === 0 ? "" : "...";
|
||||
const tail = startWithContext + 240 < text.length ? "..." : "";
|
||||
|
||||
let summary = document.createElement("p");
|
||||
summary.classList.add("context");
|
||||
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
|
||||
|
||||
highlightWords.forEach((highlightWord) =>
|
||||
_highlightText(summary, highlightWord, "highlighted")
|
||||
);
|
||||
|
||||
return summary;
|
||||
},
|
||||
};
|
||||
|
||||
_ready(Search.init);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -1,67 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
set(KEYMAPFILE keymaps.txt)
|
||||
|
||||
# Set up the toolchain and other architecture specific details
|
||||
|
||||
if(ARCH MATCHES atmega328p)
|
||||
message(STATUS "setting up for atmega328p")
|
||||
set(AVF_H_FUSE 0xd9)
|
||||
set(AVR_L_FUSE 0xd2)
|
||||
set(AVR_MCU ${ARCH})
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generic-gcc-avr.cmake)
|
||||
set (PROJECT_OUT_TARGET ${PROJECT_TARGET}.elf)
|
||||
|
||||
elseif(ARCH MATCHES atmega2560)
|
||||
message(STATUS "setting up for atmega2560")
|
||||
set(AVF_H_FUSE 0x99)
|
||||
set(AVR_L_FUSE 0xe7)
|
||||
set(AVR_MCU ${ARCH})
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generic-gcc-avr.cmake)
|
||||
set (PROJECT_OUT_TARGET ${PROJECT_TARGET}.elf)
|
||||
|
||||
endif()
|
||||
|
||||
project("asdf"
|
||||
VERSION 1.6.3
|
||||
DESCRIPTION "A customizable keyboard matrix controller for retrocomputers"
|
||||
LANGUAGES C)
|
||||
|
||||
set_property(GLOBAL PROPERTY C_STANDARD 99)
|
||||
|
||||
set(PROJECT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
message("SRC Dir is ${PROJECT_SRC_DIR}")
|
||||
|
||||
#set(PYTHON_SCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
|
||||
#message("Python scripts Dir is ${PYTHON_SCRIPTS_DIR}")
|
||||
|
||||
set(DOC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
|
||||
message("Documentation and web page directory is ${DOC_DIR}")
|
||||
|
||||
set (PROJECT_TARGET_NAME asdf-v${PROJECT_VERSION}-${ARCH})
|
||||
set (PROJECT_EXECUTABLE_TARGET_NAME ${PROJECT_TARGET_NAME})
|
||||
|
||||
if(ARCH MATCHES test)
|
||||
add_subdirectory(test)
|
||||
else()
|
||||
if((ARCH MATCHES atmega328p) OR (ARCH MATCHES atmega2560))
|
||||
set (PROJECT_EXECUTABLE_TARGET_NAME ${PROJECT_TARGET_NAME}.elf)
|
||||
|
||||
function(custom_add_library EXECUTABLE_NAME)
|
||||
add_avr_library(${EXECUTABLE_NAME} ${ARGN})
|
||||
endfunction(custom_add_library)
|
||||
|
||||
function(custom_add_executable EXECUTABLE_NAME)
|
||||
add_avr_executable(${EXECUTABLE_NAME} ${ARGN})
|
||||
endfunction(custom_add_executable)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
endif()
|
||||
|
||||
# generate reStructuredText index file for project version: Note: this may be
|
||||
# rebuilt for each target, but as long as all have the same project version, the
|
||||
# build is idempotent, so no issues.
|
||||
configure_file(${DOC_DIR}/source/_templates/index.rst.in ${DOC_DIR}/source/index.rst)
|
|
@ -1,20 +0,0 @@
|
|||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
black = "*"
|
||||
flake8 = "*"
|
||||
pylint = "*"
|
||||
mypy = "*"
|
||||
|
||||
[packages]
|
||||
sphinx = "*"
|
||||
sphinx-autodoc-typehints = "*"
|
||||
sphinx-rtd-theme = "*"
|
||||
toml = "*"
|
||||
intelhex = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3"
|
|
@ -1,124 +0,0 @@
|
|||
ASDF Keyboard scanning firmware
|
||||
-
|
||||
This is a key matrix scanner that can detect and debounce keypress and release
|
||||
events on a key matrix and either send codes or perform actions on keypress or
|
||||
release. Keymaps are defined per application and may, for example, generate
|
||||
ASCII codes, special keyscan codes, etc. The code is modular and may be
|
||||
integrated into a larger system easily.
|
||||
|
||||
By default, the code supports any number of rows by 8 columns, which will give
|
||||
the bestperformance on an 8-bit microcontroller. For more than 8 columns per
|
||||
row, the row datatype would need to be changed to uint16_t to support 16
|
||||
columns, etc.
|
||||
|
||||
The first supported application is a parallel ASCII output keyboard. If you want
|
||||
serial or USB output, you can supply your own routines.
|
||||
|
||||
ASDF supports basic keyboard functionality and is configurable via a few
|
||||
boolean variables, and via the key maps. The key maps are organized in
|
||||
row,column format, with separate keymaps shift, capslock, and control-key modes.
|
||||
|
||||
Features:
|
||||
--
|
||||
* modifiers: A set of modifier keys may be specified. When only a few modifiers
|
||||
are used, this mechanism is a low-overhead alternative to a keymap overlay for
|
||||
keyboard states that only change the key codes produced by a keypress, such as
|
||||
SHIFT, CAPS LOCK, CONTROL, etc. The state of each modifier key is kept in a
|
||||
state variable. In most cases, pressing the key will set the value to a
|
||||
"pressed" state, and releasing will reset the value to an "unpressed" state.
|
||||
However some functions interact. For example, Shift Lock is sticky, so
|
||||
pressing Shift Lock toggles the Shift Lock state, and Releasing Shift Lock
|
||||
does nothing; but pressing "Shift" will reset the "Shift Lock" state.
|
||||
|
||||
All modifier state variables are kept in a modifier state variable array. On a
|
||||
regular keypress, all of the modifier state variables are OR'ed together to
|
||||
produce an index into a value array for the standard key, to determine the
|
||||
value sent by the standard keypress.
|
||||
|
||||
* DIP switches: DIP switches are implemented by adding them into the key
|
||||
matrix, and providing activate() and deactivate() functions for the on and off
|
||||
positions.
|
||||
|
||||
* Multiple keymaps. DIP switches 0-4 select the map. The current version
|
||||
includes:
|
||||
|
||||
* (0): ADM-style ASCII keyboard
|
||||
* (1): ADM-style ASCII keyboard (all caps)
|
||||
* (2): Apple 2 ASCII keyboard (upper/lower)
|
||||
* (3): Apple 2 ASCII keyboard (standard all caps)
|
||||
* (4): Sol-20 ASCII keyboard
|
||||
|
||||
* Debounce and Repeat functions: The main keyscan logic implements key
|
||||
debouncing. Multiple keys may be debounced simultaneously using a separate
|
||||
debounce counter for each key in the matrix.
|
||||
|
||||
* Repeat key and Autorepeat: This is provided by the repeat module. Autorepeat
|
||||
may be disabled or enabled either by configuration, by activate()/deactivate()
|
||||
functions, or other keyboard logic. Repeat and autorepeat only apply to the
|
||||
most recently pressed key.
|
||||
|
||||
* ASCII output - supported via output_value function.
|
||||
|
||||
* Virtual Output layer: Indicator LEDs and other direct logic-level hardware controls: supported via
|
||||
a virtual output layer. The keymaps (and certain functions such as shiftlock and capslock) may bind virtual outputs. The keymaps may then specify how the virtual outputs map to the available physical resources. This allows one keymap to place the capslock LED in one position, and another keymap may place the capslock LED elswhere. This simplifies support of multiple keyboards and keymaps.
|
||||
|
||||
Compiling and configuration
|
||||
--
|
||||
The source files are in the ./src directory. The final build files go in the ./build directory.
|
||||
|
||||
To build, enter the ./src directory. You should be able to build a binary and
|
||||
hex file suitable for programming a microcontroller by typing "Make". You may
|
||||
edit the Makefile to specify your target platform (default is Atmega328P ASCII
|
||||
controller). You may also wish to edit your preferences in "asdf_config.h" to
|
||||
specify repeat timings, optimize the debounce setting (if you have very bounce
|
||||
keys), and specify the character output buffer size (if you are implementing
|
||||
macros, etc.)
|
||||
|
||||
Porting
|
||||
--
|
||||
This firmware was written in modular, portable C99, to be compiled with GCC
|
||||
(avr-gcc for the Atmega). The hardware-sepecific files are in Arch/*.[ch]. To
|
||||
adapt the Atmega port for additional hardware, enter the ./src/Arch directory,
|
||||
and copy the files asdf_arch_atmega2560.c and asdf_arch_astmeg2560.h to new
|
||||
filenames, and edit them to suit the hardware changes.
|
||||
|
||||
The firmware is designed to run from ROM on a slow vintage processor, with a
|
||||
small RAM footprint, and is not re-entrant. It is designed to compile on small
|
||||
architectures, or to be hand-translated to assembly on small processors, or to
|
||||
an HDL for a CPLD or FPGA.
|
||||
|
||||
The code was written to favor readability over cleverness. While tempted to
|
||||
optimize bit testing via bithacks, I opted for code simplicity since the
|
||||
performance benefit was not there for 8-bit values.
|
||||
|
||||
To port to a new processor architecture, you may use the atmega2560 files as an
|
||||
example, and create a pair of architecture-specific .c and .h files for the new
|
||||
hardware, exporting the following functions:
|
||||
|
||||
- asdf_arch_init: initializes the CPU and hardware
|
||||
|
||||
- asdf_arch_read_row: given a row number, output the row to the matrix, and read
|
||||
all the columns on that row asdf_arch_send_code
|
||||
|
||||
- asdf_arch_send_code: given a key code, output the code to the computer, via
|
||||
serial, parallel, I2C, whatever is appropriate.
|
||||
|
||||
- asdf_arch_tick: true once every 1ms. This tests a flag set in an interrupt
|
||||
routine that is triggered every 1ms. The function return value is polled and a
|
||||
keyscan initiated when true. An alternative, if you have an RTOS, or even just
|
||||
a scheduler, would be to schedule the keyscan every 1 ms, rather than poll. In
|
||||
that case, this function is not needed, and the "superloop" in main.c would
|
||||
contain a call to the scheduler.
|
||||
|
||||
- asdf_arch_XXXX_set: The hardware provides a number of physical resources, such
|
||||
as TTL or tri-state outputs, which can be used to drive LEDs, TTL logic output
|
||||
lines, etc. These are driven by a virtual output layer. The virtual layer
|
||||
requires a function to set the state of the physical resources. One function
|
||||
is provided for each such resource. For example, if a TTL output is called
|
||||
OUT1, then the function asdf_arch_out1_set() must be defined. For now, the
|
||||
required devices are:
|
||||
- LED1, LED2, LED3 (LED outputs)
|
||||
- OUT1, OUT2, OUT3 (TTL outputs)
|
||||
- OUT1\_OPEN\_HI, OUT2\_OPEN\_HI, OUT3\_OPEN\_HI (Open collector outputs)
|
||||
- OUT1\_OPEN\_LO, OUT2\_OPEN\_LO, OUT3\_OPEN\_LO (Open emitter outputs)
|
||||
|
|
@ -1,474 +0,0 @@
|
|||
##########################################################################
|
||||
# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware
|
||||
# license):
|
||||
# <dev@layer128.net> wrote this file. As long as you retain this notice
|
||||
# you can do whatever you want with this stuff. If we meet some day, and
|
||||
# you think this stuff is worth it, you can buy me a be(ve)er(age) in
|
||||
# return. (I don't like beer much.)
|
||||
#
|
||||
# Matthias Kleemann
|
||||
##########################################################################
|
||||
|
||||
##########################################################################
|
||||
# The toolchain requires some variables set.
|
||||
#
|
||||
# AVR_MCU (default: atmega8)
|
||||
# the type of AVR the application is built for
|
||||
# AVR_L_FUSE (NO DEFAULT)
|
||||
# the LOW fuse value for the MCU used
|
||||
# AVR_H_FUSE (NO DEFAULT)
|
||||
# the HIGH fuse value for the MCU used
|
||||
# AVR_UPLOADTOOL (default: avrdude)
|
||||
# the application used to upload to the MCU
|
||||
# NOTE: The toolchain is currently quite specific about
|
||||
# the commands used, so it needs tweaking.
|
||||
# AVR_UPLOADTOOL_PORT (default: usb)
|
||||
# the port used for the upload tool, e.g. usb
|
||||
# AVR_PROGRAMMER (default: avrispmkII)
|
||||
# the programmer hardware used, e.g. avrispmkII
|
||||
##########################################################################
|
||||
|
||||
##########################################################################
|
||||
# options
|
||||
##########################################################################
|
||||
#option(WITH_MCU "Add the mCU type to the target file name." OFF)
|
||||
|
||||
##########################################################################
|
||||
# executables in use
|
||||
##########################################################################
|
||||
find_program(AVR_CC avr-gcc)
|
||||
find_program(AVR_CXX avr-g++)
|
||||
find_program(AVR_OBJCOPY avr-objcopy)
|
||||
find_program(AVR_SIZE_TOOL avr-size)
|
||||
find_program(AVR_OBJDUMP avr-objdump)
|
||||
|
||||
##########################################################################
|
||||
# toolchain starts with defining mandatory variables
|
||||
##########################################################################
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR avr)
|
||||
set(CMAKE_C_COMPILER ${AVR_CC})
|
||||
set(CMAKE_CXX_COMPILER ${AVR_CXX})
|
||||
|
||||
##########################################################################
|
||||
# c_toolchain_flags
|
||||
# - Adds a list of compiler-specific flags to the CFLAGS variable in the
|
||||
# parent scope.
|
||||
##########################################################################
|
||||
function(c_toolchain_flags)
|
||||
# fix array base indexing beginning in AVR-GCC 12:
|
||||
|
||||
list(APPEND TOOLCHAIN_FLAGS
|
||||
-std=c99
|
||||
# -Wa,-adhln
|
||||
-Wall
|
||||
-funsigned-char
|
||||
-funsigned-bitfields
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fpack-struct
|
||||
-fshort-enums
|
||||
-O2
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpointer-arith
|
||||
-Wcast-align
|
||||
-Wwrite-strings
|
||||
-Wswitch-default
|
||||
-Wunreachable-code
|
||||
-Winit-self
|
||||
-Wmissing-field-initializers
|
||||
-Wno-unknown-pragmas
|
||||
-Wstrict-prototypes
|
||||
-Wundef
|
||||
-Wold-style-definition
|
||||
)
|
||||
|
||||
if(CMAKE_C_COMPILER_VERSION GREATER_EQUAL "11.3")
|
||||
message(STATUS "Appending page size fix for GCC >= 11.3")
|
||||
list(APPEND TOOLCHAIN_FLAGS --param=min-pagesize=0)
|
||||
endif()
|
||||
|
||||
set(CFLAGS ${TOOLCHAIN_FLAGS} PARENT_SCOPE)
|
||||
endfunction(c_toolchain_flags)
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Macros for setting optimization flag:
|
||||
# - optimization_off: turn off optimization for RTOS
|
||||
# - optimization_full: set optimization to desired level for app.
|
||||
##########################################################################
|
||||
|
||||
macro(optimization_off)
|
||||
set(CMAKE_CFLAGS_RELEASE "-O0" "-NDEBUG")
|
||||
set(CMAKE_CFLAGS "-O0" "-NDEBUG")
|
||||
endmacro(optimization_off)
|
||||
|
||||
|
||||
macro(optimization_full)
|
||||
set(CMAKE_CFLAGS_RELEASE "-O3" "-NDEBUG")
|
||||
set(CMAKE_CFLAGS "-O3" "-NDEBUG")
|
||||
endmacro(optimization_full)
|
||||
|
||||
##########################################################################
|
||||
# Identification
|
||||
##########################################################################
|
||||
set(AVR 1)
|
||||
|
||||
##########################################################################
|
||||
# some necessary tools and variables for AVR builds, which may not
|
||||
# defined yet
|
||||
# - AVR_UPLOADTOOL
|
||||
# - AVR_UPLOADTOOL_PORT
|
||||
# - AVR_PROGRAMMER
|
||||
# - AVR_MCU
|
||||
# - AVR_SIZE_ARGS
|
||||
##########################################################################
|
||||
|
||||
# default upload tool
|
||||
if(NOT AVR_UPLOADTOOL)
|
||||
set(
|
||||
AVR_UPLOADTOOL avrdude
|
||||
CACHE STRING "Set default upload tool: avrdude"
|
||||
)
|
||||
find_program(AVR_UPLOADTOOL avrdude)
|
||||
endif(NOT AVR_UPLOADTOOL)
|
||||
|
||||
# default upload tool port
|
||||
if(NOT AVR_UPLOADTOOL_PORT)
|
||||
set(
|
||||
AVR_UPLOADTOOL_PORT usb
|
||||
CACHE STRING "Set default upload tool port: usb"
|
||||
)
|
||||
endif(NOT AVR_UPLOADTOOL_PORT)
|
||||
|
||||
# default programmer (hardware)
|
||||
if(NOT AVR_PROGRAMMER)
|
||||
set(
|
||||
AVR_PROGRAMMER avrispmkII
|
||||
CACHE STRING "Set default programmer hardware model: avrispmkII"
|
||||
)
|
||||
endif(NOT AVR_PROGRAMMER)
|
||||
|
||||
# default MCU (chip)
|
||||
if(NOT AVR_MCU)
|
||||
set(
|
||||
AVR_MCU atmega8
|
||||
CACHE STRING "Set default MCU: atmega8 (see 'avr-gcc --target-help' for valid values)"
|
||||
)
|
||||
endif(NOT AVR_MCU)
|
||||
|
||||
#default avr-size args
|
||||
if(NOT AVR_SIZE_ARGS)
|
||||
set(AVR_SIZE_ARGS -B)
|
||||
endif(NOT AVR_SIZE_ARGS)
|
||||
|
||||
# prepare base flags for upload tool
|
||||
set(AVR_UPLOADTOOL_BASE_OPTIONS -p ${AVR_MCU} -c ${AVR_PROGRAMMER})
|
||||
|
||||
# use AVR_UPLOADTOOL_BAUDRATE as baudrate for upload tool (if defined)
|
||||
if(AVR_UPLOADTOOL_BAUDRATE)
|
||||
set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -b ${AVR_UPLOADTOOL_BAUDRATE})
|
||||
endif()
|
||||
|
||||
##########################################################################
|
||||
# check build types:
|
||||
# - Debug
|
||||
# - Release
|
||||
# - RelWithDebInfo
|
||||
#
|
||||
# Release is chosen, because of some optimized functions in the
|
||||
# AVR toolchain, e.g. _delay_ms().
|
||||
##########################################################################
|
||||
if(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES Debug) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES MinSizeRel)))
|
||||
set(
|
||||
CMAKE_BUILD_TYPE Release
|
||||
CACHE STRING "Choose cmake build type: Debug Release RelWithDebInfo MinSizeRel"
|
||||
FORCE
|
||||
)
|
||||
endif(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES Debug) OR
|
||||
(CMAKE_BUILD_TYPE MATCHES MinSizeRel)))
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
|
||||
##########################################################################
|
||||
# target file name add-on
|
||||
##########################################################################
|
||||
if(WITH_MCU)
|
||||
set(MCU_TYPE_FOR_FILENAME "-${AVR_MCU}")
|
||||
else(WITH_MCU)
|
||||
set(MCU_TYPE_FOR_FILENAME "")
|
||||
endif(WITH_MCU)
|
||||
|
||||
|
||||
##########################################################################
|
||||
# add_avr_executable
|
||||
# - IN_VAR: EXECUTABLE_NAME
|
||||
#
|
||||
# Creates targets and dependencies for AVR toolchain, building an
|
||||
# executable. Calls add_executable with ELF file as target name, so
|
||||
# any link dependencies need to be using that target, e.g. for
|
||||
# target_link_libraries(<EXECUTABLE_NAME>-${AVR_MCU}.elf ...).
|
||||
#
|
||||
##########################################################################
|
||||
function(add_avr_executable EXECUTABLE_NAME)
|
||||
message(STATUS "target name: ${EXECUTABLE_NAME}")
|
||||
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}.")
|
||||
endif(NOT ARGN)
|
||||
|
||||
# set file names
|
||||
set(basename ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME})
|
||||
set(elf_file ${basename}.elf)
|
||||
set(hex_file ${basename}.hex)
|
||||
set(lst_file ${basename}.lst)
|
||||
set(map_file ${basename}.map)
|
||||
set(eeprom_image ${basename}-eeprom.hex)
|
||||
message(STATUS "elf name: ${elf_file}")
|
||||
message(STATUS "project target name: ${PROJECT_TARGET_NAME}")
|
||||
|
||||
set(sphinx_file ${CMAKE_CURRENT_BINARY_DIR}/toc_${PROJECT_TARGET_NAME}.rst)
|
||||
configure_file(${DOC_DIR}/source/_templates/hexfile_link.in ${sphinx_file})
|
||||
|
||||
message(STATUS "sphinx file: ${sphinx_file}")
|
||||
|
||||
install(FILES ${sphinx_file} DESTINATION docs/source)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${basename}.hex DESTINATION dist)
|
||||
|
||||
# elf file
|
||||
add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN})
|
||||
|
||||
set_target_properties(
|
||||
${elf_file}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-mmcu=${AVR_MCU}"
|
||||
LINK_FLAGS "-mmcu=${AVR_MCU} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${hex_file}
|
||||
COMMAND
|
||||
${AVR_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file}
|
||||
COMMAND
|
||||
${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${lst_file}
|
||||
COMMAND
|
||||
${AVR_OBJDUMP} -d ${elf_file} > ${lst_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
# eeprom
|
||||
add_custom_command(
|
||||
OUTPUT ${eeprom_image}
|
||||
COMMAND
|
||||
${AVR_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load
|
||||
--change-section-lma .eeprom=0 --no-change-warnings
|
||||
-O ihex ${elf_file} ${eeprom_image}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
${EXECUTABLE_NAME}
|
||||
ALL
|
||||
DEPENDS ${hex_file} ${lst_file} ${eeprom_image}
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
${EXECUTABLE_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${elf_file}"
|
||||
)
|
||||
|
||||
# clean
|
||||
get_directory_property(clean_files ADDITIONAL_MAKE_CLEAN_FILES)
|
||||
set_directory_properties(
|
||||
PROPERTIES
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${map_file}"
|
||||
)
|
||||
|
||||
# upload - with avrdude
|
||||
add_custom_target(
|
||||
upload_${EXECUTABLE_NAME}
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS}
|
||||
-U flash:w:${hex_file}
|
||||
-P ${AVR_UPLOADTOOL_PORT}
|
||||
DEPENDS ${hex_file}
|
||||
COMMENT "Uploading ${hex_file} to ${AVR_MCU} using ${AVR_PROGRAMMER}"
|
||||
)
|
||||
|
||||
# upload eeprom only - with avrdude
|
||||
# see also bug http://savannah.nongnu.org/bugs/?40142
|
||||
add_custom_target(
|
||||
upload_${EXECUTABLE_NAME}_eeprom
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS}
|
||||
-U eeprom:w:${eeprom_image}
|
||||
-P ${AVR_UPLOADTOOL_PORT}
|
||||
DEPENDS ${eeprom_image}
|
||||
COMMENT "Uploading ${eeprom_image} to ${AVR_MCU} using ${AVR_PROGRAMMER}"
|
||||
)
|
||||
|
||||
# disassemble
|
||||
add_custom_target(
|
||||
disassemble_${EXECUTABLE_NAME}
|
||||
${AVR_OBJDUMP} -h -S ${elf_file} > ${EXECUTABLE_NAME}.lst
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
endfunction(add_avr_executable)
|
||||
|
||||
|
||||
##########################################################################
|
||||
# add_avr_library
|
||||
# - IN_VAR: LIBRARY_NAME
|
||||
#
|
||||
# Calls add_library with an optionally concatenated name
|
||||
# <LIBRARY_NAME>${MCU_TYPE_FOR_FILENAME}.
|
||||
# This needs to be used for linking against the library, e.g. calling
|
||||
# target_link_libraries(...).
|
||||
##########################################################################
|
||||
function(add_avr_library LIBRARY_NAME)
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "No source files given for ${LIBRARY_NAME}.")
|
||||
endif(NOT ARGN)
|
||||
|
||||
set(lib_file ${LIBRARY_NAME}${MCU_TYPE_FOR_FILENAME})
|
||||
|
||||
add_library(${lib_file} STATIC ${ARGN})
|
||||
|
||||
set_target_properties(
|
||||
${lib_file}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-mmcu=${AVR_MCU}"
|
||||
OUTPUT_NAME "${lib_file}"
|
||||
)
|
||||
|
||||
if(NOT TARGET ${LIBRARY_NAME})
|
||||
add_custom_target(
|
||||
${LIBRARY_NAME}
|
||||
ALL
|
||||
DEPENDS ${lib_file}
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
${LIBRARY_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${lib_file}"
|
||||
)
|
||||
endif(NOT TARGET ${LIBRARY_NAME})
|
||||
|
||||
endfunction(add_avr_library)
|
||||
|
||||
##########################################################################
|
||||
# avr_target_link_libraries
|
||||
# - IN_VAR: EXECUTABLE_TARGET
|
||||
# - ARGN : targets and files to link to
|
||||
#
|
||||
# Calls target_link_libraries with AVR target names (concatenation,
|
||||
# extensions and so on.
|
||||
##########################################################################
|
||||
function(avr_target_link_libraries EXECUTABLE_TARGET)
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "Nothing to link to ${EXECUTABLE_TARGET}.")
|
||||
endif(NOT ARGN)
|
||||
|
||||
get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
|
||||
|
||||
foreach(TGT ${ARGN})
|
||||
if(TARGET ${TGT})
|
||||
get_target_property(ARG_NAME ${TGT} OUTPUT_NAME)
|
||||
list(APPEND NON_TARGET_LIST ${ARG_NAME})
|
||||
else(TARGET ${TGT})
|
||||
list(APPEND NON_TARGET_LIST ${TGT})
|
||||
endif(TARGET ${TGT})
|
||||
endforeach(TGT ${ARGN})
|
||||
|
||||
target_link_libraries(${TARGET_LIST} ${NON_TARGET_LIST})
|
||||
endfunction(avr_target_link_libraries EXECUTABLE_TARGET)
|
||||
|
||||
##########################################################################
|
||||
# avr_target_include_directories
|
||||
#
|
||||
# Calls target_include_directories with AVR target names
|
||||
##########################################################################
|
||||
|
||||
function(avr_target_include_directories EXECUTABLE_TARGET)
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "No include directories to add to ${EXECUTABLE_TARGET}.")
|
||||
endif()
|
||||
|
||||
get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
|
||||
set(extra_args ${ARGN})
|
||||
|
||||
target_include_directories(${TARGET_LIST} ${extra_args})
|
||||
endfunction()
|
||||
|
||||
##########################################################################
|
||||
# avr_target_compile_definitions
|
||||
#
|
||||
# Calls target_compile_definitions with AVR target names
|
||||
##########################################################################
|
||||
|
||||
function(avr_target_compile_definitions EXECUTABLE_TARGET)
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "No compile definitions to add to ${EXECUTABLE_TARGET}.")
|
||||
endif()
|
||||
|
||||
get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME)
|
||||
set(extra_args ${ARGN})
|
||||
|
||||
target_compile_definitions(${TARGET_LIST} ${extra_args})
|
||||
endfunction()
|
||||
|
||||
function(avr_generate_fixed_targets)
|
||||
# get status
|
||||
add_custom_target(
|
||||
get_status
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n -v
|
||||
COMMENT "Get status from ${AVR_MCU}"
|
||||
)
|
||||
|
||||
# get fuses
|
||||
add_custom_target(
|
||||
get_fuses
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n
|
||||
-U lfuse:r:-:b
|
||||
-U hfuse:r:-:b
|
||||
COMMENT "Get fuses from ${AVR_MCU}"
|
||||
)
|
||||
|
||||
# set fuses
|
||||
add_custom_target(
|
||||
set_fuses
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
|
||||
-U lfuse:w:${AVR_L_FUSE}:m
|
||||
-U hfuse:w:${AVR_H_FUSE}:m
|
||||
COMMENT "Setup: High Fuse: ${AVR_H_FUSE} Low Fuse: ${AVR_L_FUSE}"
|
||||
)
|
||||
|
||||
# get oscillator calibration
|
||||
add_custom_target(
|
||||
get_calibration
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
|
||||
-U calibration:r:${AVR_MCU}_calib.tmp:r
|
||||
COMMENT "Write calibration status of internal oscillator to ${AVR_MCU}_calib.tmp."
|
||||
)
|
||||
|
||||
# set oscillator calibration
|
||||
add_custom_target(
|
||||
set_calibration
|
||||
${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT}
|
||||
-U calibration:w:${AVR_MCU}_calib.hex
|
||||
COMMENT "Program calibration status of internal oscillator from ${AVR_MCU}_calib.hex."
|
||||
)
|
||||
endfunction()
|
|
@ -1,20 +0,0 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = source
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@ -1,35 +0,0 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
|
@ -1,7 +0,0 @@
|
|||
.. _@ARCH@ Rev @CMAKE_PROJECT_VERSION@:
|
||||
|
||||
ASDF Rev @CMAKE_PROJECT_VERSION@ hex file (@ARCH@)
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
:ASDF Firmware @CMAKE_PROJECT_VERSION@-@ARCH@:
|
||||
:download:`@hex_file@`
|
|
@ -1,63 +0,0 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import toml
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "ASDF - Unified Retro Keyboard Firmware"
|
||||
copyright = "2022 Osiweb.org"
|
||||
author = "David F"
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.autodoc", # Core library for html generation from docstrings
|
||||
"sphinx_autodoc_typehints",
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinx.ext.autosectionlabel",
|
||||
"sphinx.ext.autosummary", # Create neat summary tables
|
||||
]
|
||||
autosummary_generate = True # Turn on sphinx.ext.autosummary
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = []
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = [
|
||||
"_static"
|
||||
] # Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
@ -1,25 +0,0 @@
|
|||
* EEPROM management
|
||||
** Uses
|
||||
*** Store current keyboard ID
|
||||
*** Store status of various options
|
||||
**** key repeat rates and delays
|
||||
**** communications delays
|
||||
**** serial baud rates
|
||||
**** keyboard macros
|
||||
**** keyboard specific options
|
||||
***** all caps / upper+lower
|
||||
***** handling of special keys
|
||||
** Allocate on demand
|
||||
** System block does not change as keyboards are changed
|
||||
*** Items include:
|
||||
**** current keyboard
|
||||
*** All system block allocation must occur before any keyboard allocation may occur.
|
||||
*** Once system EEPROM is allocated, system EEPROM is "locked"
|
||||
*** If system EEPROM is locked, then EEPROM cannot be reallocated, although the parameters may be re-written.
|
||||
*** provision to unlock EEPROM, for example, when firmware is updated, or during development
|
||||
|
||||
** Keyboard block is reset whenever the keyboard changes
|
||||
*** Any parameters specific to a keyboard, such as macros, keymap-specific settings, etc. are stored here.
|
||||
*** This section is erased when keymap changes, but not when a keymap is loaded from EEPROM at powerup.
|
||||
|
||||
*
|
|
@ -1,9 +0,0 @@
|
|||
list(APPEND keymap_list
|
||||
"<classic:0>"
|
||||
"<classic_caps:1>"
|
||||
"<apple2:2>"
|
||||
"<apple2_caps:3>"
|
||||
"<sol:4>"
|
||||
)
|
||||
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
GENERATOR="Unix Makefiles"
|
||||
NUM_VALID_TARGETS=0
|
||||
BUILD_TYPE=RELEASE
|
||||
INSTALL_DIR="dist"
|
||||
MAKE_TARGETS="all"
|
||||
DOC_DIR=docs
|
||||
LINKS_DIR="$DOC_DIR/source"
|
||||
|
||||
add_valid_target() {
|
||||
VALID_TARGETS[$NUM_VALID_TARGETS]=$1
|
||||
HW_SIGS[$NUM_VALID_TARGETS]=$2
|
||||
((NUM_VALID_TARGETS++))
|
||||
}
|
||||
|
||||
add_valid_target test
|
||||
add_valid_target atmega328p
|
||||
add_valid_target atmega2560
|
||||
|
||||
|
||||
check_valid_target() {
|
||||
result="false"
|
||||
|
||||
for (( i = 0; i < NUM_VALID_TARGETS; i++ ))
|
||||
do
|
||||
if [[ ${VALID_TARGETS[$i]} == $1 ]]
|
||||
then
|
||||
result=$i
|
||||
fi
|
||||
done
|
||||
echo $result
|
||||
}
|
||||
|
||||
|
||||
do_pipenv_clean() {
|
||||
echo removing old python virtual environment...
|
||||
pipenv --rm
|
||||
}
|
||||
|
||||
|
||||
do_pipenv_install() {
|
||||
echo installing python virtual environment...
|
||||
pipenv install
|
||||
}
|
||||
|
||||
clean_arch() {
|
||||
target_arch="$1"
|
||||
echo "Removing pre-existing build directory: $target_arch..."
|
||||
rm -rf "build-$target_arch"
|
||||
echo "Removing any build artifacts"
|
||||
rm -f $INSTALL_DIR/*"$1"*
|
||||
echo "Removing any download links"
|
||||
rm -f $LINKS_DIR/*$1*
|
||||
}
|
||||
|
||||
build_arch() {
|
||||
local target_arch="$1"
|
||||
local hardware_sig="$2"
|
||||
|
||||
if [[ ! -d "build-$target_arch" ]]
|
||||
then
|
||||
mkdir "build-$target_arch"
|
||||
fi
|
||||
|
||||
if [[ -d "build-$target_arch" ]]
|
||||
then
|
||||
(cd "build-$target_arch" \
|
||||
&& cmake -G "$GENERATOR" -DCMAKE_INSTALL_PREFIX=".." -DARCH="$target_arch" \
|
||||
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" ..)
|
||||
fi
|
||||
}
|
||||
|
||||
deploy_arch() {
|
||||
local target_arch="$1"
|
||||
|
||||
if [[ -d "build-$target_arch" ]]
|
||||
then
|
||||
(cd "build-$target_arch" \
|
||||
&& make install)
|
||||
fi
|
||||
}
|
||||
|
||||
clean_all() {
|
||||
echo "- Removing install dir \"$INSTALL_DIR\"..."
|
||||
rm -rvf "$INSTALL_DIR"
|
||||
echo "- Removing download links..."
|
||||
rm -vf $DOC_DIR/source/toc_*
|
||||
echo "- Removing versioned index file"
|
||||
rm -vf "$DOC_DIR/source/index.rst"
|
||||
}
|
||||
|
||||
syntax() {
|
||||
echo "Usage:"
|
||||
echo " $0 -t target [-t target] ..."
|
||||
echo " $0 -a"
|
||||
echo " $0 -h"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h. Display this help message"
|
||||
echo " -x Before creating a build directgory or virtual env, remove"
|
||||
echo " any pre-existing version"
|
||||
echo " -t add an architecture directory"
|
||||
echo " -a Add all valid architecture directories"
|
||||
echo " -i Build each specified target and install to dist directory"
|
||||
echo " -p Install pipenv virtual environment for python scripts"
|
||||
echo " -c Clean all artifacts"
|
||||
echo " -s Copy dist files to sphinx directory"
|
||||
echo "Valid targets: ${VALID_TARGETS[*]}"
|
||||
}
|
||||
|
||||
parse() {
|
||||
local SYNTAX=""
|
||||
local ALL=""
|
||||
local i
|
||||
local valid_index
|
||||
|
||||
NUM_CMAKE_TARGETS=0
|
||||
CLEAN_BEFORE_BUILD=""
|
||||
DO_PIPENV_INSTALL=""
|
||||
DEPLOY=""
|
||||
CLEAN_ALL=""
|
||||
COPY_DIST_TO_DOCS=""
|
||||
|
||||
while getopts "t:ahipxcs" optname
|
||||
do
|
||||
case "$optname" in
|
||||
h)
|
||||
SYNTAX="yes"
|
||||
;;
|
||||
a)
|
||||
ALL="yes"
|
||||
;;
|
||||
t)
|
||||
# Test that target is valid
|
||||
valid_index=$(check_valid_target $OPTARG)
|
||||
if [[ $valid_index != "false" ]]
|
||||
then
|
||||
CMAKE_TARGETS[$NUM_CMAKE_TARGETS]=$valid_index
|
||||
((NUM_CMAKE_TARGETS++))
|
||||
else
|
||||
echo Unknown target \"$OPTARG\"
|
||||
SYNTAX="yes"
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
DO_PIPENV_INSTALL="yes"
|
||||
;;
|
||||
x)
|
||||
CLEAN_BEFORE_BUILD="yes"
|
||||
;;
|
||||
i) DEPLOY="yes"
|
||||
;;
|
||||
s) COPY_DIST_TO_DOCS="yes"
|
||||
;;
|
||||
c) CLEAN_ALL="yes"
|
||||
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$SYNTAX" == "yes" ]]; then
|
||||
syntax && die
|
||||
fi
|
||||
|
||||
if [[ "$ALL" == "yes" ]]
|
||||
then
|
||||
for (( i=0; i<NUM_VALID_TARGETS; i++ ))
|
||||
do
|
||||
CMAKE_TARGETS[i]=$i
|
||||
done
|
||||
NUM_CMAKE_TARGETS=$NUM_VALID_TARGETS
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
die() {
|
||||
builtin echo $@
|
||||
exit 1
|
||||
}
|
||||
|
||||
main() {
|
||||
local TARGET
|
||||
local i
|
||||
parse $@
|
||||
|
||||
if [[ "$DO_PIPENV_INSTALL" == "yes" ]]
|
||||
then
|
||||
if [[ "$CLEAN_BEFORE_BUILD" == "yes" ]]
|
||||
then
|
||||
do_pipenv_clean
|
||||
fi
|
||||
|
||||
do_pipenv_install
|
||||
fi
|
||||
|
||||
if [[ "$CLEAN_ALL" == "yes" ]]
|
||||
then
|
||||
clean_all
|
||||
fi
|
||||
|
||||
echo Valid Targets: "${VALID_TARGETS[*]}"
|
||||
|
||||
for (( i=0; $i<$NUM_CMAKE_TARGETS; i++ ))
|
||||
do
|
||||
TARGET=${CMAKE_TARGETS[$i]}
|
||||
if [[ "$CLEAN_BEFORE_BUILD" == "yes" ]]
|
||||
then
|
||||
clean_arch ${VALID_TARGETS[$TARGET]}
|
||||
fi
|
||||
build_arch ${VALID_TARGETS[$TARGET]} ${HW_SIGS[$TARGET]}
|
||||
if [[ "$DEPLOY" == "yes" ]]
|
||||
then
|
||||
deploy_arch ${VALID_TARGETS[$TARGET]}
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $COPY_DIST_TO_DOCS == "yes" && -d "$INSTALL_DIR" ]]
|
||||
then
|
||||
cp -av "$INSTALL_DIR"/* docs/source
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
main $@
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
* Keymap architecture
|
||||
** Keymap definition modules are in src/Keymaps
|
||||
** Each keymap has its own keymap setup routine
|
||||
*** void setup_mapname_keymap(void) - keymap setup function
|
||||
**** register a keycode map for each modifier combination
|
||||
***** The keycode maps are in flash (ROM)
|
||||
**** set up virtual devices for the keymap
|
||||
***** virtual device to physical device mapping
|
||||
***** associated virtual device function on activate/deactivate
|
||||
***** initial state
|
||||
**** set up function hooks used by keymap
|
||||
|
||||
** Keymap definition API
|
||||
*** mapping keys
|
||||
#include "asdf_keymaps.h"
|
||||
**** asdf_keymaps_add_map() - called from
|
||||
Assigns a specified keymap matrix (ptr to FLASH) to a given keymap and modifier type.
|
||||
*** adding virtual devices - called from keymap setup routine
|
||||
**** asdf_virtual_init()
|
||||
***** Clears the virtual device table for the keymap
|
||||
***** initialize first entry in virtual device table to NULL
|
||||
**** asdf_virtual_add_device()
|
||||
***** Accept a virtual device code, a physical device code, a default function, and a default initial value, and create a new entry in the virtual device table.
|
||||
***** increment the virtual device table pointer and set next (last) entry to NULL
|
||||
|
||||
|
||||
* DIP SWITCHES
|
||||
Note that the DIP switches are keys in the key matrix, which is initialized to
|
||||
the all unpressed state at startup. Since the keymap is initialized to 0, the
|
||||
keymap is consistent with the presumed initial state of the DIP switches. If
|
||||
the DIP switches are not set to Keymap 0, then their position will be detected
|
||||
as keypresses, and the correct keymap will be set.
|
||||
|
|
@ -1,869 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch.c
|
||||
//
|
||||
// This file contains all the architecture dependent code, including register
|
||||
// setup, I/O, timers, etc.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// Wiring Information:
|
||||
// Chip: {Microcontroller type and version}
|
||||
//
|
||||
// Example:
|
||||
// PIN NAME FUNCTION
|
||||
// 14-19,9,10 PORTB COLUMN inputs (1 bit per column)
|
||||
// 23-25 PORTC0-2 ROW outputs (row number)
|
||||
// 27 PORTC4
|
||||
|
||||
#include "asdf_arch.h"
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "asdf_config.h"
|
||||
|
||||
// Tick is true every 1 ms.
|
||||
static volatile uint8_t tick = 0;
|
||||
|
||||
// data polarity may be changed with a DIP switch, so we use a static instead of a constant
|
||||
static uint8_t data_polarity = ASDF_DEFAULT_DATA_POLARITY;
|
||||
|
||||
// PROCEDURE: ISR for Timer 0 overflow
|
||||
// INPUTS: none
|
||||
// OUTPUTS:none
|
||||
//
|
||||
// DESCRIPTION: Occurs every 1 ms. Set tick flag, kick watchdog.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
ISR(TIMER0_COMPA_vect)
|
||||
{
|
||||
tick = 1;
|
||||
}
|
||||
|
||||
// PROCEDURE: set_bit
|
||||
// INPUTS: port: pointer to a (uint8) port
|
||||
// bit: bit position to be set
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Give a port address and bit position, set the bit position.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES: Declared inline. Will only be inlined for functions in this module, so
|
||||
// also declared static.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static inline void set_bit(volatile uint8_t *port, uint8_t bit)
|
||||
{
|
||||
*port |= (1 << bit);
|
||||
}
|
||||
|
||||
// PROCEDURE: clear_bit
|
||||
// INPUTS: port: pointer to a (uint8) port
|
||||
// bit: bit position to be cleared
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Give a port address and bit position, clear the bit position.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES: Declared inline. Will only be inlined for functions in this module, so
|
||||
// also declared static.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static inline void clear_bit(volatile uint8_t *port, uint8_t bit)
|
||||
{
|
||||
*port &= ~(1 << bit);
|
||||
}
|
||||
|
||||
// PROCEDURE: arch_timer0_config
|
||||
//
|
||||
// INPUTS: bits: a 4 byte field containing the configuration values for the
|
||||
// 8-bit timer0 A and B control registers, and the interrupt mask register.
|
||||
//
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a 4 byte value with settings for all the control
|
||||
// registers for the 8-bit counter/timer (timer 0), and writes them all
|
||||
// to the respective registers.
|
||||
//
|
||||
// SIDE EFFECTS: see above
|
||||
//
|
||||
// NOTES: Setting all the bits together, and writing all the registers from a
|
||||
// single word permits more clear initialization of control fields that are
|
||||
// spread across more than one word.
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
static void arch_timer0_config(uint32_t bits)
|
||||
{
|
||||
TCCR0B = 0; // first turn off timer.
|
||||
TCCR0A = (bits >> TMR0A_POS) & 0xff;
|
||||
TIMSK0 = (bits >> TMR0IMSK_POS) & 0xff;
|
||||
TCCR0B = (bits >> TMR0B_POS) & 0xff; // Set the mode (and turn on timer) last
|
||||
}
|
||||
|
||||
// PROCEDURE: arch_tick_timer_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up 1ms tick timer.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES: Set up Timer 0 in CTC mode for 1 ms overflow.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_tick_timer_init(void)
|
||||
{
|
||||
tick = 0;
|
||||
|
||||
// set compare register first, so timer can operate correctly as soon as it is
|
||||
// enabled.
|
||||
OCR0A = TICK_COUNT;
|
||||
|
||||
// operate in CTC mode to overflow at exactly 1 ms
|
||||
// prescaler = 64 and output compare value is 250
|
||||
arch_timer0_config(TIMER0_WFM_CTC | TIMER0_DIV64 | TIMER0_INT_ON_COMA);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_tick
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns a 1 if the 1ms timer timed out, 0 otherwise
|
||||
//
|
||||
// DESCRIPTION: See Outputs.
|
||||
//
|
||||
// SIDE EFFECTS: Zeroes out the 1 ms timer flag.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t asdf_arch_tick(void)
|
||||
{
|
||||
uint8_t retval = tick;
|
||||
tick = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_timers
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up timer for 1 ms intervals
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_clock(void)
|
||||
{
|
||||
CLKPR = (CLKPCE | SYSCLK_DIV1);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_outputs
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize all LED ports as outputs. Values are not set here.
|
||||
// They are set by the keymap code
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_leds(void)
|
||||
{
|
||||
set_bit(&ASDF_LED1_DDR, ASDF_LED1_BIT);
|
||||
set_bit(&ASDF_LED2_DDR, ASDF_LED2_BIT);
|
||||
set_bit(&ASDF_LED3_DDR, ASDF_LED3_BIT);
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED1 port drives the LED directly by pulling the cathode low, so
|
||||
// clearing the bit turns the LED on.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led1_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
|
||||
}
|
||||
else {
|
||||
set_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED2 output drives the LED via an inverter buffer, so a high
|
||||
// output pulls the LED cathode low, lighting the LED.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led2_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
|
||||
}
|
||||
else {
|
||||
set_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED3 output drives the LED via an inverter buffer, so a high
|
||||
// output pulls the LED cathode low, lighting the LED.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led3_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
|
||||
}
|
||||
else {
|
||||
set_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Does nothing.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_null_output(uint8_t value)
|
||||
{
|
||||
(void) value;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
set_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
set_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
set_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
clear_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_set_pos_strobe(void)
|
||||
{
|
||||
clear_bit(&ASDF_STROBE_PORT, ASDF_STROBE_BIT);
|
||||
set_bit(&ASDF_STROBE_DDR, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_set_neg_strobe(void)
|
||||
{
|
||||
set_bit(&ASDF_STROBE_PORT, ASDF_STROBE_BIT);
|
||||
set_bit(&ASDF_STROBE_DDR, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_ascii_output
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up output port for ASCII output
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_ascii_output(void)
|
||||
{
|
||||
// set all outputs
|
||||
ASDF_ASCII_PORT = data_polarity;
|
||||
ASDF_ASCII_DDR = ALL_OUTPUTS;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_columns
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up columns port as input and enable weak pullups.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_columns(void)
|
||||
{
|
||||
ASDF_COLUMNS_DDR = ALL_INPUTS;
|
||||
ASDF_COLUMNS_PORT = ALL_PULLUPS;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_row_outputs
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up output port to latch keyboard matrix row for scanning.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_row_outputs(void)
|
||||
{
|
||||
ASDF_HIROW_DDR = ALL_OUTPUTS;
|
||||
ASDF_LOROW_DDR = ALL_OUTPUTS;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by
|
||||
// ASDF_PULSE_DELAY_SHORT_US
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_short(void)
|
||||
{
|
||||
_delay_us(ASDF_PULSE_DELAY_SHORT_US);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by
|
||||
// ASDF_PULSE_DELAY_LONG_MS
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_long(void)
|
||||
{
|
||||
_delay_ms(ASDF_PULSE_DELAY_LONG_MS);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms)
|
||||
{
|
||||
for (uint16_t i=0; i < delay_ms; i++) {
|
||||
_delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
//
|
||||
// SIDE EFFECTS: see DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_init(void)
|
||||
{
|
||||
// disable interrupts:
|
||||
cli();
|
||||
|
||||
// clear the 1ms timer flag;
|
||||
tick = 0;
|
||||
|
||||
// set up timers for 1 msec intervals
|
||||
asdf_arch_init_clock();
|
||||
asdf_arch_tick_timer_init();
|
||||
|
||||
// set up ASCII output port
|
||||
asdf_arch_init_ascii_output();
|
||||
|
||||
// initialize keyboard data polarity and strobe polarity
|
||||
data_polarity = ASDF_DEFAULT_DATA_POLARITY;
|
||||
|
||||
if (ASDF_DEFAULT_STROBE_POLARITY == ASDF_POSITIVE_POLARITY) {
|
||||
asdf_arch_set_pos_strobe();
|
||||
} else {
|
||||
asdf_arch_set_neg_strobe();
|
||||
}
|
||||
|
||||
asdf_arch_init_leds();
|
||||
|
||||
// set up row and column ports
|
||||
asdf_arch_init_row_outputs();
|
||||
asdf_arch_init_columns();
|
||||
|
||||
// enable interrupts:
|
||||
sei();
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the active (pressed) columns
|
||||
//
|
||||
// DESCRIPTION: Outputs the argument to the ROW ports, then reads the column
|
||||
// port and returns the value. The value is a binary representation of the keys
|
||||
// pressed within the row, with 1=pressed, 0=released.
|
||||
//
|
||||
// SIDE EFFECTS: Sets ROW output port.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// 1) The keymap represents an unpressed key as a "0" and a pressed key as a
|
||||
// "1". So, if a keypress pulls the column line low, then the reading of the
|
||||
// physical bits must be inverted.
|
||||
//
|
||||
// 2) A small delay (2usec) is required between setting the keyboard row outputs
|
||||
// and reading the columns, which I think is due to capacitance across the
|
||||
// reverse-biased diodes.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
asdf_cols_t asdf_arch_read_row(uint8_t row)
|
||||
{
|
||||
uint32_t rows = ~(1L << row);
|
||||
|
||||
ASDF_LOROW_PORT = (uint8_t)(rows & 0xff);
|
||||
_delay_us(ASDF_KEYBOARD_ROW_SETTLING_TIME_US);
|
||||
ASDF_HIROW_PORT = (uint8_t)((rows >> 8) & 0xff);
|
||||
_delay_us(ASDF_KEYBOARD_ROW_SETTLING_TIME_US);
|
||||
|
||||
return ~(asdf_cols_t) ASDF_COLUMNS_PIN;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_osi_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the active (pressed) columns
|
||||
//
|
||||
// DESCRIPTION: Outputs the argument to the ROW ports, then reads the column
|
||||
// port and returns the value. The value is a binary representation of the keys
|
||||
// pressed within the row, with 1=pressed, 0=released.
|
||||
//
|
||||
// SIDE EFFECTS: Sets ROW output port.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// 1) The keymap represents an unpressed key as a "0" and a pressed key as a
|
||||
// "1". So, if a keypress pulls the column line low, then the reading of the
|
||||
// physical bits must be inverted.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
asdf_cols_t asdf_arch_osi_read_row(uint8_t row)
|
||||
{
|
||||
asdf_cols_t cols;
|
||||
|
||||
if (row > 7) {
|
||||
cols = asdf_arch_read_row(row);
|
||||
}
|
||||
else {
|
||||
// enable the OSI keyboard
|
||||
clear_bit(&ASDF_OSI_KBE_PORT, ASDF_OSI_KBE_BIT);
|
||||
|
||||
// register the row to be read
|
||||
ASDF_COLUMNS_DDR = ALL_OUTPUTS;
|
||||
|
||||
ASDF_COLUMNS_PORT = (1 << row);
|
||||
clear_bit(&ASDF_OSI_RW_PORT, ASDF_OSI_RW_BIT);
|
||||
set_bit(&ASDF_OSI_RW_PORT, ASDF_OSI_RW_BIT);
|
||||
|
||||
// Read in the columns
|
||||
ASDF_COLUMNS_DDR = ALL_INPUTS;
|
||||
return ASDF_COLUMNS_PIN;
|
||||
|
||||
ASDF_LOROW_PORT = row & 0xff;
|
||||
|
||||
cols = (asdf_cols_t) ASDF_COLUMNS_PORT;
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: (keycode_t) code - the 7-bit ASCII code to be output by the keyboard
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a character code and outputs the code on a parallel ASCII
|
||||
// port, with a strobe. This routine could be replaced with UART, I2C, USB, or
|
||||
// other output mechanism, of course.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The strobe is set by the ASDF_STROBE_LENGTH definition. The data
|
||||
// output and strobe polarity are set by the static data_polarity and static
|
||||
// strobe_polarity variables.
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
void asdf_arch_send_code(asdf_keycode_t code)
|
||||
{
|
||||
ASDF_ASCII_PORT = (code ^ data_polarity);
|
||||
|
||||
|
||||
// toggle strobe. Must test before setting to avoid spurious strobe
|
||||
set_bit(&ASDF_STROBE_PIN, ASDF_STROBE_BIT);
|
||||
|
||||
_delay_us(ASDF_STROBE_LENGTH_US);
|
||||
|
||||
set_bit(&ASDF_STROBE_PIN, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
//
|
|
@ -1,506 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch_atmega2560.h
|
||||
//
|
||||
// Contains architecture-specific definitions for the atmega 2560
|
||||
//
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#if !defined(ASDF_ARCH_H)
|
||||
#define ASDF_ARCH_H
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include "asdf.h"
|
||||
|
||||
// ASDF keyboard definitions:
|
||||
|
||||
#define F_CPU 16000000L
|
||||
|
||||
#define ASDF_STROBE_LENGTH_US 10 // strobe length in microseconds
|
||||
#define ASDF_KEYBOARD_ROW_SETTLING_TIME_US 4 // time for keyboard capacitance to
|
||||
// settle before sampling
|
||||
|
||||
// Clock definitions:
|
||||
#define SYSCLK_DIV1 0
|
||||
#define SYSCLK_DIV2 (CLKPS0)
|
||||
#define SYCCLK_DIV4 (CLKPS1)
|
||||
#define SYSCLK_DIV8 (CLKPS1 | CLKPS0)
|
||||
#define SYSCLK_DIV16 (CLKPS2)
|
||||
#define SYSCLK_DIV32 (CLKPS2 | CLKPS0)
|
||||
#define SYSCLK_DIV64 (CLKPS2 | CLKPS1)
|
||||
#define SYSCLK_DIV128 (CLKPS2 | CLKPS1 | CLKPS0)
|
||||
#define SYSCLK_DIV256 (CLKPS3)
|
||||
|
||||
// Timer 0 definitions
|
||||
// Define fields for register A, B, interrupt mask as 8-bit masks, and
|
||||
// as masks offset into a combined config word
|
||||
#define TMR0A_POS 0
|
||||
#define TMR0B_POS 8
|
||||
#define TMR0IMSK_POS 16
|
||||
#define TMR0A (1L << TMR0A_POS)
|
||||
#define TMR0B (1L << TMR0B_POS)
|
||||
#define TMR0IMSK (1L << TMR0IMSK_POS)
|
||||
|
||||
#define TIMER0_COM_A_DISCONNECTED 0
|
||||
#define TIMER0_COM_B_DISCONNECTED 0
|
||||
#define TIMER0_WFM_CTC (TMR0A << WGM01)
|
||||
#define TIMER0_DIV64 ((TMR0B << CS01) | (TMR0B << CS00))
|
||||
#define TIMER0_INT_ON_COMA (TMR0IMSK << OCIE0A)
|
||||
#define TIMER0_INT_ON_COMB (TMR0IMSK << OCIE0B)
|
||||
#define TIMER0_INT_OV_ENABLE (TMR0IMSK << TOIE0)
|
||||
|
||||
// Macros for 16-bit timers 1, 3, 4, 5. Datasheet section 17, p. 133
|
||||
//
|
||||
// Define fields for Registers A, B, C, INT Mask registers as 8-bit
|
||||
// masks, and as masks offset into a 32-bit combined config word.
|
||||
//
|
||||
// Macro definitions for individual registers are named TMRXA_*,
|
||||
// TMRXB_*, and TMRXC_*.
|
||||
//
|
||||
// Macros for the one-step combined timer config functions are named
|
||||
// TMRX_*.
|
||||
//
|
||||
//
|
||||
// Examples:
|
||||
// // Use TMRXB_* definition to set TCCR4B register
|
||||
// TCCR4B |= TMRXB_DIV1;
|
||||
//
|
||||
// // Use TMRX_* definitions to configure timer with config function
|
||||
// processor_timer4_config(TMRX_WFM_CTC | TMRX_INT_ON_CMPA);
|
||||
//
|
||||
#define TMRXA_POS 0
|
||||
#define TMRXB_POS 8
|
||||
#define TMRXC_POS 16
|
||||
#define TMRXIMSK_POS 24
|
||||
#define TMRXA (1L << TMRXA_POS)
|
||||
#define TMRXB (1L << TMRXB_POS)
|
||||
#define TMRXC (1L << TMRXC_POS)
|
||||
#define TMRXIMSK (1L << TMRXIMSK_POS)
|
||||
|
||||
// 16-bit timer reg A - Datasheet 17.11.1, p. 154
|
||||
#define TMRXA_CMPA_CLR_MATCH_SET_BOTTOM (1 << COM1A1)
|
||||
#define TMRXA_CMPB_CLR_MATCH_SET_BOTTOM (1 << COM1B1)
|
||||
#define TMRXA_CMPC_CLR_MATCH_SET_BOTTOM (1 << COM1C1)
|
||||
#define TMRX_CMPA_CLR_MATCH_SET_BOTTOM (TMRXA << COM1A1)
|
||||
#define TMRX_CMPB_CLR_MATCH_SET_BOTTOM (TMRXA << COM1B1)
|
||||
#define TMRX_CMPC_CLR_MATCH_SET_BOTTOM (TMRXA << COM1C1)
|
||||
|
||||
// 16-bit timer reg B - Datasheet 17.11.6, p. 156
|
||||
|
||||
#define TMRXB_IN_CAP_POS 0x40L
|
||||
#define TMRXB_IN_CAP_NEG 0L
|
||||
#define TMRXB_IN_CAP_NOISE_CANCEL 0x80L
|
||||
|
||||
// 16-bit timer reg C -- see datasheet, 17.11.9, p. 157
|
||||
#define TMRXC_FOCA 0x80L
|
||||
#define TMRXC_FOCB 0x40L
|
||||
#define TMRXC_FOCC 0x20L
|
||||
|
||||
// 16-bit timer int mask -- see datasheet 17.11.33, p. 161.
|
||||
#define TMRXIM_INT_CMP_MATCH_A (1L << OCIE1A)
|
||||
#define TMRXIM_INT_CMP_MATCH_B (1L << OCIE1B)
|
||||
#define TMRXIM_INT_CMP_MATCH_C (1L << OCIE1C)
|
||||
|
||||
// 16-bit timer all registers:
|
||||
#define TMRX_CMPA_DISCONNECTED 0L
|
||||
#define TMRX_CMPB_DISCONNECTED 0L
|
||||
#define TMRX_CMPC_DISCONNECTED 0L
|
||||
#define TMRX_INT_ON_CMPA (TMRXIM_INT_CMP_MATCH_A << TMRXIMSK_POS)
|
||||
|
||||
// 16-bit timer clock modes - see Datasheet table 17-6, p. 157
|
||||
#define TMRXB_OFF 0
|
||||
#define TMRX_OFF 0
|
||||
#define TMRXB_DIV1 (0x01L << CS10)
|
||||
#define TMRXB_DIV8 (0x02L << CS10)
|
||||
#define TMRXB_DIV64 (0x03L << CS10)
|
||||
#define TMRXB_DIV256 (0x04L << CS10)
|
||||
#define TMRXB_DIV1024 (0x05L << CS10)
|
||||
#define TMRXB_EXT_FALLING_EDGE (0x06L << CS10)
|
||||
#define TMRXB_EXT_RISING_EDGE (0x07L << CS10)
|
||||
#define TMRXB_CLK_MASK 0x07L
|
||||
#define TMRX_DIV1 (TMRXB_DIV1 << TMRXB_POS)
|
||||
#define TMRX_DIV8 (TMRXB_DIV8 << TMRXB_POS)
|
||||
#define TMRX_DIV64 (TMRXB_DIV64 << TMRXB_POS)
|
||||
#define TMRX_DIV256 (TMRXB_DIV256 << TMRXB_POS)
|
||||
#define TMRX_DIV1024 (TMRXB_DIV1024 << TMRXB_POS)
|
||||
#define TMRX_EXT_FALLING_EDGE (TMRXB_EXT_FALLING_EDGE << TMRXB_POS)
|
||||
#define TMRX_EXT_RISING_EDGE (TMRXB_EXT_RISING_EDGE << TMRXB_POS)
|
||||
|
||||
#define TMRXB_EDGE_SEL_POSITIVE (1 << ICES1)
|
||||
#define TMRXB_EDGE_SEL_NEGATIVE 0L
|
||||
#define TMRX_EDGE_SEL_POSITIVE (TMRXB << ICES1)
|
||||
#define TMRX_EDGE_SEL_NEGATIVE 0L
|
||||
|
||||
// 16-bit waveform modes (across reg A and B) Datasheet Table 17.2, p 145
|
||||
#define TMRX_WFM_NORMAL 0L
|
||||
#define TMRX_WFM_PWM_PC8 (TMRXA << WGM10) // PWM Phase Correct 8-bit
|
||||
#define TMRX_WFM_PWM_PC9 (TMRXA << WGM11) // PWM Phase COrrect 9-bit
|
||||
#define TMRX_WFM_PWM_PC10 ((TMRXA << WGM11) | (TMRXA << WGM10)) // PWM Phase Correct 10-bit
|
||||
#define TMRX_WFM_CTC (TMRXB << WGM12) // CTC
|
||||
#define TMRX_WFM_PWM_FAST8 ((TMRXB << WGM12) | (TMRXA << WGM10)) // PWM Fast 8-bit
|
||||
#define TMRX_WFM_PWM_FAST9 ((TMRXB << WGM12) | (TMRXA << WGM11)) // PWM Fast 9-bit
|
||||
#define TMRX_WFM_PWM_FAST10 \
|
||||
((TMRXB << WGM12) | (TMRXA << WGM11) | (TMRXA << WGM10)) // PWM Fast 10-bit
|
||||
#define TMRX_WFM_PWM_PFC_ICR (TMRXB << WGM13) // PWM Phase and Freq Correct, TpOP=ICR
|
||||
#define TMRX_WFM_PWM_PFC_OCRA \
|
||||
((TMRXB << WGM13) | (TMRXA << WGM10)) // PWM Phase and Freq Correct, TOP = OCRA
|
||||
#define TMRX_WFM_PWM_PC_ICR ((TMRXB << WGM13) | (TMRXA << WGM11)) // PWM PhaseCorrect, TOP = ICR
|
||||
#define TMRX_WFM_PWM_PC_OCRA \
|
||||
((TMRXB << WGM13) | (TMRXA << WGM11) | (TMRXA << WGM12)) // PWM PhaseCorrect, TOP=OCRA
|
||||
#define TMRX_WFM_CTC_ICR ((TMRXB << WGM13) | (TMRXB << WGM12)) // CTC, TOP = ICR
|
||||
#define TMRX_WFM_PWM_FAST_ICR \
|
||||
((TMRXB << WGM13) | (TMRXB << WGM12) | (TMRXA << WGM11)) // PWM Fast, TOP = ICR
|
||||
#define TMRX_WFM_PWM_FAST_OCRA \
|
||||
((TMRXB << WGM13) | (TMRXB << WGM12) | (TMRXA << WGM11) \
|
||||
| (TMRXA << WGM10)) // PWM Fast, TOP = OCRA
|
||||
|
||||
// USART configuration (Datasheet section 22, p. 200)
|
||||
//
|
||||
// Macro definitions for individual registers are named USARTA_*,
|
||||
// USARTB_*, and USARTC_*.
|
||||
//
|
||||
// Macros for the one-step combined timer config functions are named
|
||||
// USART_*.
|
||||
//
|
||||
//
|
||||
// Examples:
|
||||
// // Use USARTB_* definition to set UCSR1B register
|
||||
// UCSR1B |= USARTB_DATA_REG_EMPTY_INT_EN; // enable interrupt on tx reg empty
|
||||
//
|
||||
// // Use USART_* definitions to configure usart with config function
|
||||
// processor_usart3_config(USART_SIZE_8 | USART_PARITY_NONE | USART_STOP_1 | USART_DATA_TXEN |
|
||||
// USART_DATA_RXEN | USART_RX_COMPLETE_INT_EN);
|
||||
//
|
||||
#define USARTA_POS 0
|
||||
#define USARTB_POS 8
|
||||
#define USARTC_POS 16
|
||||
#define USARTA (1L << USARTA_POS)
|
||||
#define USARTB (1L << USARTB_POS)
|
||||
#define USARTC (1L << USARTC_POS)
|
||||
|
||||
// USART Register A, Datasheet 22.10.2, p. 219
|
||||
|
||||
#define USARTA_DATA_REG_EMPTY (1 << UDR0)
|
||||
#define USARTA_FRAME_ERROR (1 << FE0)
|
||||
#define USARTA_DATA_OVERRUN (1 << DOR0)
|
||||
#define USARTA_PARITY_ERROR (1 << UPE0)
|
||||
#define USARTA_DOUBLE_SPEED (1 << U2X0)
|
||||
#define USARTA_MULTI_PROCESSOR (1 << MPCM0)
|
||||
#define USART_DATA_REG_EMPTY (USARTA << UDR0)
|
||||
#define USART_FRAME_ERROR (USARTA << FE0)
|
||||
#define USART_DATA_OVERRUN (USARTA << DOR0)
|
||||
#define USART_PARITY_ERROR (USARTA << UPE0)
|
||||
#define USART_DOUBLE_SPEED (USARTA << U2X0)
|
||||
#define USART_MULTI_PROCESSOR (USARTA << MPCM0)
|
||||
|
||||
// USART Register B, Datasheet 22.10.3, p. 220
|
||||
|
||||
#define USARTB_RX_COMPLETE_INT_EN (1 << RXCIE0)
|
||||
#define USARTB_TX_COMPLETE_INT_EN (1 << TXCIE0)
|
||||
#define USARTB_DATA_REG_EMPTY_INT_EN (1 << UDRIE0)
|
||||
#define USARTB_DATA_RXEN (1 << RXEN0)
|
||||
#define USARTB_DATA_TXEN (1 << TXEN0)
|
||||
#define USARTB_SIZE_9 (1 << UCSZ02)
|
||||
#define USARTB_RX_BIT_8 (1 << RXB80)
|
||||
#define USARTB_TX_BIT_8 (1 << TXB80)
|
||||
#define USART_RX_COMPLETE_INT_EN (USARTB << RXCIE0)
|
||||
#define USART_TX_COMPLETE_INT_EN (USARTB << TXCIE0)
|
||||
#define USART_DATA_REG_EMPTY_INT_EN (USARTB << UDRIE0)
|
||||
#define USART_DATA_RXEN (USARTB << RXEN0)
|
||||
#define USART_DATA_TXEN (USARTB << TXEN0)
|
||||
#define USART_RX_BIT_8 (USARTB << RXB80)
|
||||
#define USART_TX_BIT_8 (USARTB << TXB80)
|
||||
|
||||
// USART Register C, Datasheet 22.10.4, p.221
|
||||
#define USARTC_MODE_ASYNC_USART (0x00L << UMSEL00)
|
||||
#define USARTC_MODE_SYNC_USART (0x01L << UMSEL00)
|
||||
#define USARTC_MODE_MSPIM (0x03L << UMSEL00)
|
||||
#define USART_MODE_ASYNC_USART (USARTC_MODE_ASYNC_USART << USARTC_POS)
|
||||
#define USART_MODE_SYNC_USART (USARTC_MODE_SYNC_USART << USARTC_POS)
|
||||
#define USART_MODE_MSPIM (USARTC_MODE_MSPIM << USARTC_POS)
|
||||
|
||||
#define USARTC_PARITY_NONE 0
|
||||
#define USARTC_PARITY_EVEN (0x01L << UPM00)
|
||||
#define USARTC_PARITY_ODD (0x03 << UPM00)
|
||||
#define USART_PARITY_NONE 0
|
||||
#define USART_PARITY_EVEN (USARTC_PARITY_EVEN << USARTC_POS)
|
||||
#define USART_PARITY_ODD (USARTC_PARITY_ODD << USARTC_POS)
|
||||
|
||||
#define USARTC_STOP_1 0
|
||||
#define USARTC_STOP_2 (1 << USBS0)
|
||||
#define USART_STOP_1 0
|
||||
#define USART_STOP_2 (USARTC << USBS0)
|
||||
|
||||
#define USARTC_SIZE_5 0
|
||||
#define USARTC_SIZE_6 (0x01L << UCSZ00)
|
||||
#define USARTC_SIZE_7 (0x02L << UCSZ00)
|
||||
#define USARTC_SIZE_8 (0x03L << UCSZ00)
|
||||
#define USARTC_SIZE_9 USARTC_SIZE_8
|
||||
#define USART_SIZE_5 0
|
||||
#define USART_SIZE_6 (USARTC_SIZE_6 << USARTC_POS)
|
||||
#define USART_SIZE_7 (USARTC_SIZE_7 << USARTC_POS)
|
||||
#define USART_SIZE_8 (USARTC_SIZE_8 << USARTC_POS)
|
||||
#define USART_SIZE_9 ((USARTB_SIZE_9 << USARTB_POS) | (USARTC_SIZE_9 << USARTC_POS))
|
||||
|
||||
#define USARTC_CLK_TX_RISING 0
|
||||
#define USART_CLK_TX_RISING 0
|
||||
#define USARTC_CLK_TX_FALLING (1 << UCPOL0)
|
||||
#define USART_CLK_TX_FALLING (USARTC << UCPOL0)
|
||||
|
||||
|
||||
|
||||
// I/O port definitions:
|
||||
|
||||
#define PIN_INPUT 0
|
||||
#define PIN_OUTPUT 1
|
||||
#define ALL_INPUTS 0
|
||||
#define ALL_OUTPUTS 0xff
|
||||
#define ALL_PULLUPS 0xff
|
||||
|
||||
#define ASDF_HIROW_PORT PORTA
|
||||
#define ASDF_HIROW_DDR DDRA
|
||||
#define ASDF_HIROW_PIN PINA
|
||||
|
||||
#define ASDF_LOROW_PORT PORTJ
|
||||
#define ASDF_LOROW_DDR DDRJ
|
||||
#define ASDF_LOROW_PIN PINJ
|
||||
|
||||
#define ASDF_COLUMNS_PORT PORTC
|
||||
#define ASDF_COLUMNS_PIN PINC
|
||||
#define ASDF_COLUMNS_DDR DDRC
|
||||
|
||||
#define ASDF_ASCII_PORT PORTH
|
||||
#define ASDF_ASCII_DDR DDRH
|
||||
|
||||
#define ASDF_LED1_PORT PORTD
|
||||
#define ASDF_LED1_DDR DDRD
|
||||
#define ASDF_LED1_BIT 5
|
||||
|
||||
#define ASDF_LED2_PORT PORTD
|
||||
#define ASDF_LED2_DDR DDRD
|
||||
#define ASDF_LED2_BIT 6
|
||||
|
||||
#define ASDF_LED3_PORT PORTD
|
||||
#define ASDF_LED3_DDR DDRD
|
||||
#define ASDF_LED3_BIT 7
|
||||
|
||||
#define ASDF_OUT1_PORT PORTB
|
||||
#define ASDF_OUT1_PIN PINB
|
||||
#define ASDF_OUT1_DDR DDRB
|
||||
#define ASDF_OUT1_BIT 5
|
||||
|
||||
#define ASDF_OUT2_PORT PORTB
|
||||
#define ASDF_OUT2_PIN PINB
|
||||
#define ASDF_OUT2_DDR DDRB
|
||||
#define ASDF_OUT2_BIT 6
|
||||
|
||||
#define ASDF_OUT3_PORT PORTB
|
||||
#define ASDF_OUT3_PIN PINB
|
||||
#define ASDF_OUT3_DDR DDRB
|
||||
#define ASDF_OUT3_BIT 7
|
||||
|
||||
#define ASDF_STROBE_PORT PORTB
|
||||
#define ASDF_STROBE_PIN PINB
|
||||
#define ASDF_STROBE_DDR DDRB
|
||||
#define ASDF_STROBE_BIT 4
|
||||
|
||||
#define ASDF_OSI_KBE_PORT ASDF_HIROW_PORT
|
||||
#define ASDF_OSI_KBE_DDR ASDF_HIROW_DDR
|
||||
#define ASDF_OSI_KBE_BIT 1
|
||||
|
||||
#define ASDF_OSI_RW_PORT ASDF_HIROW_PORT
|
||||
#define ASDF_OSI_RW_DDR ASDF_HIROW_DDR
|
||||
#define ASDF_OSI_RW_BIT 2
|
||||
|
||||
#define ASDF_ARCH_DIP_SWITCH_ROW 8
|
||||
|
||||
#define FUSE_INTERNAL_8MHZ_OSC_4MS (FUSE_CKSEL1 | FUSE_SUT0)
|
||||
#define FUSE_INTERNAL_8MHZ_OSC_65MS (FUSE_CKSEL1 | FUSE_SUT1)
|
||||
#define FUSE_XTAL_16MHZ_4MS (FUSE_CKSEL2 | FUSE_CKSEL1 | CKSEL0 | FUSE_SUT1)
|
||||
#define FUSE_XTAL_16MHZ_65MS (FUSE_CKSEL2 | FUSE_CKSEL1 | CKSEL0 | FUSE_SUT1 | FUSE_SUT0)
|
||||
#define FLASH PROGMEM
|
||||
|
||||
// not implemented with do-while(0) because this is a function call that returns
|
||||
// a value, and parameters are expanded inside the parameter list, so this will
|
||||
// be valid when substituting for function-like syntax.
|
||||
#define FLASH_READ (a) pgm_read_byte((a))
|
||||
#define FLASH_READ_MATRIX_ELEMENT(matrix, row, col) pgm_read_byte(&((matrix)[(row)][(col)]))
|
||||
|
||||
// For 1 ms tick, (16000000 / 64(prescale)) / 1000(usec) - 1 = 249
|
||||
#define TICK_COUNT 249
|
||||
|
||||
// Default key matrix row scanner
|
||||
#define ASDF_ARCH_DEFAULT_SCANNER &asdf_arch_read_row
|
||||
|
||||
// Default keyboard output
|
||||
#define ASDF_ARCH_DEFAULT_OUTPUT &asdf_arch_send_code
|
||||
|
||||
// DIP switch is on row 8
|
||||
#define ASDF_ARCH_DIPSWITCH_ROW 8
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
void asdf_arch_set_pos_strobe(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
void asdf_arch_set_neg_strobe(void);
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: null/dummy output function
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
void asdf_arch_null_output(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
void asdf_arch_led1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
void asdf_arch_led2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
void asdf_arch_led3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
void asdf_arch_out1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
void asdf_arch_out2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit to high if value is true, and hi-z if value is false.
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
void asdf_arch_out3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the active (pressed) columns
|
||||
// DESCRIPTION: Outputs the argument to the ROW port, then reads the column port
|
||||
// and returns the value. The value is a binary representation of the keys
|
||||
// pressed within the row, with 1=pressed, 0=released.
|
||||
asdf_cols_t asdf_arch_read_row(uint8_t row);
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by
|
||||
// ASDF_PULSE_DELAY_SHORT_US
|
||||
void asdf_arch_pulse_delay_short(void);
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by
|
||||
// ASDF_PULSE_DELAY_LONG_MS
|
||||
void asdf_arch_pulse_delay_long(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms);
|
||||
|
||||
// PROCEDURE: asdf_arch_tick
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns a 1 if the 1ms timer timed out, 0 otherwise
|
||||
uint8_t asdf_arch_tick(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: (keycode_t) code - the code to be output by the keyboard
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Takes a character code and outputs the code on a parallel ASCII
|
||||
// port, with a strobe. This routine could be replaced with UART, I2C, USB, or
|
||||
// other output mechanism, of course.
|
||||
void asdf_arch_send_code(asdf_keycode_t code);
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
void asdf_arch_init(void);
|
||||
|
||||
#endif /* !defined (ASDF_ARCH_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,838 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch.c
|
||||
//
|
||||
// This file contains all the architecture dependent code, including register
|
||||
// setup, I/O, timers, etc.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// Wiring Information:
|
||||
// Chip: {Microcontroller type and version}
|
||||
//
|
||||
// Example:
|
||||
// PIN NAME FUNCTION
|
||||
// 14-19,9,10 PORTB COLUMN inputs (1 bit per column)
|
||||
// 23-25 PORTC0-2 ROW outputs (row number)
|
||||
// 27 PORTC4
|
||||
|
||||
#include "asdf_arch.h"
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdint.h>
|
||||
#include "asdf.h"
|
||||
#include "asdf_config.h"
|
||||
|
||||
static volatile uint8_t tick = 0;
|
||||
|
||||
static uint8_t data_polarity = ASDF_DEFAULT_DATA_POLARITY;
|
||||
|
||||
|
||||
// PROCEDURE: ISR for Timer 0 overflow
|
||||
// INPUTS: none
|
||||
// OUTPUTS:none
|
||||
//
|
||||
// DESCRIPTION: Occurs every 1 ms. Set tick flag, kick watchdog.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
ISR(TIMER0_COMPA_vect)
|
||||
{
|
||||
tick = 1;
|
||||
}
|
||||
|
||||
// PROCEDURE: set_bit
|
||||
// INPUTS: port: pointer to a (uint8) port
|
||||
// bit: bit position to be set
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Give a port address and bit position, set the bit position.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES: Declared inline. Will only be inlined for functions in this module, so
|
||||
// also declared static.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static inline void set_bit(volatile uint8_t *port, uint8_t bit)
|
||||
{
|
||||
*port |= (1 << bit);
|
||||
}
|
||||
|
||||
// PROCEDURE: clear_bit
|
||||
// INPUTS: port: pointer to a (uint8) port
|
||||
// bit: bit position to be cleared
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Give a port address and bit position, clear the bit position.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES: Declared inline. Will only be inlined for functions in this module, so
|
||||
// also declared static.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static inline void clear_bit(volatile uint8_t *port, uint8_t bit)
|
||||
{
|
||||
*port &= ~(1 << bit);
|
||||
}
|
||||
|
||||
// PROCEDURE: arch_timer0_config
|
||||
//
|
||||
// INPUTS: bits: a 4 byte field containing the configuration values for the
|
||||
// 8-bit timer0 A and B control registers, and the interrupt mask register.
|
||||
//
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a 4 byte value with settings for all the control
|
||||
// registers for the 8-bit counter/timer (timer 0), and writes them all
|
||||
// to the respective registers.
|
||||
//
|
||||
// SIDE EFFECTS: see above
|
||||
//
|
||||
// NOTES: Setting all the bits together, and writing all the registers from a
|
||||
// single word permits more clear initialization of control fields that are
|
||||
// spread across more than one word.
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
static void arch_timer0_config(uint32_t bits)
|
||||
{
|
||||
TCCR0B = 0; // first turn off timer.
|
||||
TCCR0A = (bits >> TMR0A_POS) & 0xff;
|
||||
TIMSK0 = (bits >> TMR0IMSK_POS) & 0xff;
|
||||
TCCR0B = (bits >> TMR0B_POS) & 0xff; // Set the mode (and turn on timer) last
|
||||
}
|
||||
|
||||
// PROCEDURE: arch_tick_timer_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up 1ms tick timer.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES: Set up Timer 0 in CTC mode for 1 ms overflow.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_tick_timer_init(void)
|
||||
{
|
||||
tick = 0;
|
||||
|
||||
// set compare register first, so timer can operate correctly as soon as it is
|
||||
// enabled.
|
||||
OCR0A = TICK_COUNT;
|
||||
|
||||
// operate in CTC mode to overflow at exactly 1 ms
|
||||
// prescaler = 64 and output compare value is 250
|
||||
arch_timer0_config(TIMER0_WFM_CTC | TIMER0_DIV64 | TIMER0_INT_ON_COMA);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_tick
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns a 1 if the 1ms timer timed out, 0 otherwise
|
||||
//
|
||||
// DESCRIPTION: See Outputs.
|
||||
//
|
||||
// SIDE EFFECTS: Zeroes out the 1 ms timer flag.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t asdf_arch_tick(void)
|
||||
{
|
||||
uint8_t retval = tick;
|
||||
tick = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_timers
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up timer for 1 ms intervals
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_clock(void)
|
||||
{
|
||||
CLKPR = (CLKPCE | SYSCLK_DIV1);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_outputs
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize all LED ports as outputs. Values are not set here.
|
||||
// They are set by the keymap code
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_leds(void)
|
||||
{
|
||||
set_bit(&ASDF_LED1_DDR, ASDF_LED1_BIT);
|
||||
set_bit(&ASDF_LED2_DDR, ASDF_LED2_BIT);
|
||||
set_bit(&ASDF_LED3_DDR, ASDF_LED3_BIT);
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED1 port drives the LED directly by pulling the cathode low, so
|
||||
// clearing the bit turns the LED on.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led1_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
|
||||
}
|
||||
else {
|
||||
set_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED2 output drives the LED via an inverter buffer, so a high
|
||||
// output pulls the LED cathode low, lighting the LED.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led2_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The LED3 output drives the LED via an inverter buffer, so a high
|
||||
// output pulls the LED cathode low, lighting the LED.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_led3_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
|
||||
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: OUT2 is inverted by the 7404 buffer, so clearing the bit sets the output high. OUT2
|
||||
// cannot be high impedance.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
else {
|
||||
set_bit(&ASDF_OUT2_PORT, ASDF_OUT2_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Does nothing.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_null_output(uint8_t value)
|
||||
{
|
||||
(void) value;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value)
|
||||
{
|
||||
asdf_arch_null_output(value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value)
|
||||
{
|
||||
asdf_arch_null_output(value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
clear_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit to high if value is true, and hi-z if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value)
|
||||
{
|
||||
if (value) {
|
||||
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
}
|
||||
else {
|
||||
clear_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
|
||||
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_set_pos_strobe(void)
|
||||
{
|
||||
clear_bit(&ASDF_STROBE_PORT, ASDF_STROBE_BIT);
|
||||
set_bit(&ASDF_STROBE_DDR, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_set_neg_strobe(void)
|
||||
{
|
||||
set_bit(&ASDF_STROBE_PORT, ASDF_STROBE_BIT);
|
||||
set_bit(&ASDF_STROBE_DDR, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_ascii_output
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up output port for ASCII output
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_ascii_output(void)
|
||||
{
|
||||
|
||||
// set all outputs
|
||||
ASDF_ASCII_PORT = data_polarity;
|
||||
ASDF_ASCII_DDR = ALL_OUTPUTS;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_column_inputs
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: configure the shift register control lines. The MODE control is
|
||||
// LOW for shift and HIGH for load. Shift or Load occurs when CLK goes high.
|
||||
//
|
||||
// SIDE EFFECTS: Cont
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_column_control(void)
|
||||
{
|
||||
|
||||
// COLCLK is output and initialized LOW
|
||||
clear_bit(&ASDF_COLCLK_PORT, ASDF_COLCLK_BIT);
|
||||
set_bit(&ASDF_COLCLK_DDR, ASDF_COLCLK_BIT);
|
||||
|
||||
// COLMODE is output and initialized HIGH
|
||||
set_bit(&ASDF_COLMODE_PORT, ASDF_COLMODE_BIT);
|
||||
set_bit(&ASDF_COLMODE_DDR, ASDF_COLMODE_BIT);
|
||||
|
||||
// COL is input, no weak pullup.
|
||||
clear_bit(&ASDF_COL_DDR, ASDF_COL_BIT);
|
||||
clear_bit(&ASDF_COL_PORT, ASDF_COL_BIT);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init_row_outputs
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets up output port to latch keyboard matrix row for scanning.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void asdf_arch_init_row_outputs(void)
|
||||
{
|
||||
ASDF_ROW_PORT &= ~ASDF_ROW_MASK;
|
||||
ASDF_ROW_DDR |= ASDF_ROW_MASK;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by ASDF_PULSE_DELAY_SHORT_US
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_short(void)
|
||||
{
|
||||
_delay_us(ASDF_PULSE_DELAY_SHORT_US);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by ASDF_PULSE_DELAY_LONG_MS
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_long(void)
|
||||
{
|
||||
_delay_ms(ASDF_PULSE_DELAY_LONG_MS);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms)
|
||||
{
|
||||
for (uint16_t i=0; i < delay_ms; i++) {
|
||||
_delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
//
|
||||
// SIDE EFFECTS: see DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_init(void)
|
||||
{
|
||||
// disable interrupts:
|
||||
cli();
|
||||
|
||||
// clear the 1ms timer flag;
|
||||
tick = 0;
|
||||
|
||||
// set up timers for 1 msec intervals
|
||||
asdf_arch_init_clock();
|
||||
asdf_arch_tick_timer_init();
|
||||
|
||||
// set up ASCII output port
|
||||
asdf_arch_init_ascii_output();
|
||||
|
||||
// initialize keyboard data polarity and strobe polarity
|
||||
data_polarity = ASDF_DEFAULT_DATA_POLARITY;
|
||||
|
||||
if (ASDF_DEFAULT_STROBE_POLARITY == ASDF_POSITIVE_POLARITY) {
|
||||
asdf_arch_set_pos_strobe();
|
||||
} else {
|
||||
asdf_arch_set_neg_strobe();
|
||||
}
|
||||
|
||||
asdf_arch_init_leds();
|
||||
|
||||
asdf_arch_init_leds();
|
||||
|
||||
// set up row output port
|
||||
asdf_arch_init_row_outputs();
|
||||
|
||||
// set up column control lines
|
||||
asdf_arch_init_column_control();
|
||||
|
||||
// enable interrupts:
|
||||
sei();
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the active (pressed) columns
|
||||
//
|
||||
// DESCRIPTION: Outputs the argument to the ROW port, then reads the column port
|
||||
// and returns the value. The value is a binary representation of the keys
|
||||
// pressed within the row, with 1=pressed, 0=released.
|
||||
//
|
||||
// SIDE EFFECTS: Sets ROW output port.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// 1) The keymap represents an unpressed key as a "0" and a pressed key as a
|
||||
// "1". So, if a keypress pulls the column line low, then the reading of the
|
||||
// physical bits must be inverted.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
asdf_cols_t asdf_arch_read_row(uint8_t row)
|
||||
{
|
||||
asdf_cols_t cols = 0;
|
||||
|
||||
// first, output the new row value:
|
||||
ASDF_ROW_PORT = (ASDF_ROW_PORT & ~ASDF_ROW_MASK)
|
||||
| ((row & ASDF_ROW_MASK) << ASDF_ROW_OFFSET);
|
||||
|
||||
|
||||
// read in the columns. Set LOAD mode and pulse clock.
|
||||
clear_bit(&ASDF_COLMODE_PORT, ASDF_COLMODE_BIT);
|
||||
|
||||
set_bit(&ASDF_COLCLK_PORT, ASDF_COLCLK_BIT);
|
||||
clear_bit(&ASDF_COLCLK_PORT, ASDF_COLCLK_BIT);
|
||||
|
||||
// set back to SHIFT mode
|
||||
set_bit(&ASDF_COLMODE_PORT, ASDF_COLMODE_BIT);
|
||||
|
||||
// After the load operation, the LSB is already at the output pin, so there
|
||||
// will be one fewer read than clock pulse. Continue reading the bits until
|
||||
// the leader bit is in the boundary position.
|
||||
for (uint8_t i = 0; i < ASDF_MAX_COLS; i++) {
|
||||
|
||||
// invert the bits as they are read (see note 1)
|
||||
cols |= (((~(ASDF_COL_PIN) >> ASDF_COL_BIT) & 1) << i);
|
||||
|
||||
set_bit(&ASDF_COLCLK_PORT, ASDF_COLCLK_BIT);
|
||||
clear_bit(&ASDF_COLCLK_PORT, ASDF_COLCLK_BIT);
|
||||
}
|
||||
|
||||
return cols;
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: (keycode_t) code - the 7-bit ASCII code to be output by the keyboard
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a character code and outputs the code on a parallel ASCII
|
||||
// port, with a strobe. This routine could be replaced with UART, I2C, USB, or
|
||||
// other output mechanism, of course.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES: The strobe is set by the ASDF_STROBE_LENGTH definition. The data
|
||||
// output and strobe polarity are set by the static data_polarity and static
|
||||
// strobe_polarity variables.
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
void asdf_arch_send_code(asdf_keycode_t code)
|
||||
{
|
||||
ASDF_ASCII_PORT = (code ^ data_polarity);
|
||||
|
||||
|
||||
// toggle strobe. Must test before setting to avoid spurious strobe
|
||||
set_bit(&ASDF_STROBE_PIN, ASDF_STROBE_BIT);
|
||||
|
||||
_delay_us(ASDF_STROBE_LENGTH_US);
|
||||
|
||||
set_bit(&ASDF_STROBE_PIN, ASDF_STROBE_BIT);
|
||||
}
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
//
|
|
@ -1,407 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch_atmega328p.h
|
||||
//
|
||||
// Contains architecture-specific definitions for the atmega 328p.
|
||||
//
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#if !defined(ASDF_ARCH_H)
|
||||
#define ASDF_ARCH_H
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include "asdf.h"
|
||||
|
||||
// ASDF keyboard definitions:
|
||||
|
||||
#define F_CPU 8000000L
|
||||
|
||||
#define ASDF_STROBE_LENGTH_US 10 // strobe length in microseconds
|
||||
|
||||
|
||||
// Clock definitions:
|
||||
#define SYSCLK_DIV1 0
|
||||
#define SYSCLK_DIV2 (CLKPS0)
|
||||
#define SYCCLK_DIV4 (CLKPS1)
|
||||
#define SYSCLK_DIV8 (CLKPS1 | CLKPS0)
|
||||
#define SYSCLK_DIV16 (CLKPS2)
|
||||
#define SYSCLK_DIV32 (CLKPS2 | CLKPS0)
|
||||
#define SYSCLK_DIV64 (CLKPS2 | CLKPS1)
|
||||
#define SYSCLK_DIV128 (CLKPS2 | CLKPS1 | CLKPS0)
|
||||
#define SYSCLK_DIV256 (CLKPS3)
|
||||
|
||||
// Define fields for register A, B, interrupt mask as 8-bit masks, and
|
||||
// as masks offset into a combined config word
|
||||
#define TMR0A_POS 0
|
||||
#define TMR0B_POS 8
|
||||
#define TMR0IMSK_POS 16
|
||||
#define TMR0A (1L << TMR0A_POS)
|
||||
#define TMR0B (1L << TMR0B_POS)
|
||||
#define TMR0IMSK (1L << TMR0IMSK_POS)
|
||||
|
||||
#define TIMER0_COM_A_DISCONNECTED 0
|
||||
#define TIMER0_COM_B_DISCONNECTED 0
|
||||
#define TIMER0_WFM_CTC (TMR0A << WGM01)
|
||||
#define TIMER0_DIV64 ((TMR0B << CS01) | (TMR0B << CS00))
|
||||
#define TIMER0_INT_ON_COMA (TMR0IMSK << OCIE0A)
|
||||
#define TIMER0_INT_ON_COMB (TMR0IMSK << OCIE0B)
|
||||
#define TIMER0_INT_OV_ENABLE (TMR0IMSK << TOIE0)
|
||||
|
||||
// Macros for 16-bit timer 1. ATmega328P datasheet section 15, p. 108
|
||||
//
|
||||
// Define fields for Registers A, B, C, INT Mask registers as 8-bit
|
||||
// masks, and as masks offset into a 32-bit combined config word.
|
||||
//
|
||||
// Macro definitions for individual registers are named TMR1A_*,
|
||||
// TMR1B_*, and TMR1C_*.
|
||||
//
|
||||
// Macros for the one-step combined timer config functions are named
|
||||
// TMR1_*.
|
||||
//
|
||||
//
|
||||
// Examples:
|
||||
// // Use TMR1B_* definition to set TCCR1B register
|
||||
// TCCR1B |= TMR1B_DIV1;
|
||||
//
|
||||
// // Use TMR1_* definitions to configure timer with config function
|
||||
// timer1_config(TMR1_WFM_CTC | TMR1_INT_ON_CMPA);
|
||||
//
|
||||
#define TMR1A_POS 0
|
||||
#define TMR1B_POS 8
|
||||
#define TMR1C_POS 16
|
||||
#define TMR1IMSK_POS 24
|
||||
#define TMR1A (1L << TMR1A_POS)
|
||||
#define TMR1B (1L << TMR1B_POS)
|
||||
#define TMR1C (1L << TMR1C_POS)
|
||||
#define TMR1IMSK (1L << TMR1IMSK_POS)
|
||||
|
||||
// 16-bit timer reg A - Datasheet 17.11.1, p. 154
|
||||
#define TMR1A_CMPA_CLR_MATCH_SET_BOTTOM (1 << COM1A1)
|
||||
#define TMR1A_CMPB_CLR_MATCH_SET_BOTTOM (1 << COM1B1)
|
||||
#define TMR1A_CMPC_CLR_MATCH_SET_BOTTOM (1 << COM1C1)
|
||||
#define TMR1_CMPA_CLR_MATCH_SET_BOTTOM (TMR1A << COM1A1)
|
||||
#define TMR1_CMPB_CLR_MATCH_SET_BOTTOM (TMR1A << COM1B1)
|
||||
#define TMR1_CMPC_CLR_MATCH_SET_BOTTOM (TMR1A << COM1C1)
|
||||
|
||||
// 16-bit timer reg B - Datasheet 17.11.6, p. 156
|
||||
|
||||
#define TMR1B_IN_CAP_POS 0x40L
|
||||
#define TMR1B_IN_CAP_NEG 0L
|
||||
#define TMR1B_IN_CAP_NOISE_CANCEL 0x80L
|
||||
|
||||
// 16-bit timer reg C -- see datasheet, 17.11.9, p. 157
|
||||
#define TMR1C_FOCA 0x80L
|
||||
#define TMR1C_FOCB 0x40L
|
||||
#define TMR1C_FOCC 0x20L
|
||||
|
||||
// 16-bit timer int mask -- see datasheet 17.11.33, p. 161.
|
||||
#define TMR1IM_INT_CMP_MATCH_A (1L << OCIE1A)
|
||||
#define TMR1IM_INT_CMP_MATCH_B (1L << OCIE1B)
|
||||
#define TMR1IM_INT_CMP_MATCH_C (1L << OCIE1C)
|
||||
|
||||
// 16-bit timer all registers:
|
||||
#define TMR1_CMPA_DISCONNECTED 0L
|
||||
#define TMR1_CMPB_DISCONNECTED 0L
|
||||
#define TMR1_CMPC_DISCONNECTED 0L
|
||||
#define TMR1_INT_ON_CMPA (TMR1IM_INT_CMP_MATCH_A << TMR1IMSK_POS)
|
||||
|
||||
// 16-bit timer clock modes - see Datasheet table 17-6, p. 157
|
||||
#define TMR1B_OFF 0
|
||||
#define TMR1_OFF 0
|
||||
#define TMR1B_DIV1 (0x01L << CS10)
|
||||
#define TMR1B_DIV8 (0x02L << CS10)
|
||||
#define TMR1B_DIV64 (0x03L << CS10)
|
||||
#define TMR1B_DIV256 (0x04L << CS10)
|
||||
#define TMR1B_DIV1024 (0x05L << CS10)
|
||||
#define TMR1B_EXT_FALLING_EDGE (0x06L << CS10)
|
||||
#define TMR1B_EXT_RISING_EDGE (0x07L << CS10)
|
||||
#define TMR1B_CLK_MASK 0x07L
|
||||
#define TMR1_DIV1 (TMR1B_DIV1 << TMR1B_POS)
|
||||
#define TMR1_DIV8 (TMR1B_DIV8 << TMR1B_POS)
|
||||
#define TMR1_DIV64 (TMR1B_DIV64 << TMR1B_POS)
|
||||
#define TMR1_DIV256 (TMR1B_DIV256 << TMR1B_POS)
|
||||
#define TMR1_DIV1024 (TMR1B_DIV1024 << TMR1B_POS)
|
||||
#define TMR1_EXT_FALLING_EDGE (TMR1B_EXT_FALLING_EDGE << TMR1B_POS)
|
||||
#define TMR1_EXT_RISING_EDGE (TMR1B_EXT_RISING_EDGE << TMR1B_POS)
|
||||
|
||||
#define TMR1B_EDGE_SEL_POSITIVE (1 << ICES1)
|
||||
#define TMR1B_EDGE_SEL_NEGATIVE 0L
|
||||
#define TMR1_EDGE_SEL_POSITIVE (TMR1B << ICES1)
|
||||
#define TMR1_EDGE_SEL_NEGATIVE 0L
|
||||
|
||||
// 16-bit waveform modes (across reg A and B) Datasheet Table 17.2, p 145
|
||||
#define TMR1_WFM_NORMAL 0L
|
||||
#define TMR1_WFM_PWM_PC8 (TMR1A << WGM10) // PWM Phase Correct 8-bit
|
||||
#define TMR1_WFM_PWM_PC9 (TMR1A << WGM11) // PWM Phase COrrect 9-bit
|
||||
#define TMR1_WFM_PWM_PC10 ((TMR1A << WGM11) | (TMR1A << WGM10)) // PWM Phase Correct 10-bit
|
||||
#define TMR1_WFM_CTC (TMR1B << WGM12) // CTC
|
||||
#define TMR1_WFM_PWM_FAST8 ((TMR1B << WGM12) | (TMR1A << WGM10)) // PWM Fast 8-bit
|
||||
#define TMR1_WFM_PWM_FAST9 ((TMR1B << WGM12) | (TMR1A << WGM11)) // PWM Fast 9-bit
|
||||
#define TMR1_WFM_PWM_FAST10 \
|
||||
((TMR1B << WGM12) | (TMR1A << WGM11) | (TMR1A << WGM10)) // PWM Fast 10-bit
|
||||
#define TMR1_WFM_PWM_PFC_ICR (TMR1B << WGM13) // PWM Phase and Freq Correct, TpOP=ICR
|
||||
#define TMR1_WFM_PWM_PFC_OCRA \
|
||||
((TMR1B << WGM13) | (TMR1A << WGM10)) // PWM Phase and Freq Correct, TOP = OCRA
|
||||
#define TMR1_WFM_PWM_PC_ICR ((TMR1B << WGM13) | (TMR1A << WGM11)) // PWM PhaseCorrect, TOP = ICR
|
||||
#define TMR1_WFM_PWM_PC_OCRA \
|
||||
((TMR1B << WGM13) | (TMR1A << WGM11) | (TMR1A << WGM12)) // PWM PhaseCorrect, TOP=OCRA
|
||||
#define TMR1_WFM_CTC_ICR ((TMR1B << WGM13) | (TMR1B << WGM12)) // CTC, TOP = ICR
|
||||
#define TMR1_WFM_PWM_FAST_ICR \
|
||||
((TMR1B << WGM13) | (TMR1B << WGM12) | (TMR1A << WGM11)) // PWM Fast, TOP = ICR
|
||||
#define TMR1_WFM_PWM_FAST_OCRA \
|
||||
((TMR1B << WGM13) | (TMR1B << WGM12) | (TMR1A << WGM11) \
|
||||
| (TMR1A << WGM10)) // PWM Fast, TOP = OCRA
|
||||
|
||||
|
||||
// I/O port definitions:
|
||||
|
||||
#define PIN_INPUT 0
|
||||
#define PIN_OUTPUT 1
|
||||
#define ALL_INPUTS 0
|
||||
#define ALL_OUTPUTS 0xff
|
||||
|
||||
#define ASDF_ROW_PORT PORTC
|
||||
#define ASDF_ROW_DDR DDRC
|
||||
#define ASDF_ROW_MASK 0x0f
|
||||
#define ASDF_ROW_OFFSET 0
|
||||
|
||||
#define ASDF_COL_PORT PORTB
|
||||
#define ASDF_COL_PIN PINB
|
||||
#define ASDF_COL_DDR DDRB
|
||||
#define ASDF_COL_BIT 0
|
||||
#define ASDF_COL_PULLUPS 0 // disable weak pullup
|
||||
|
||||
#define ASDF_COLCLK_PORT PORTB
|
||||
#define ASDF_COLCLK_PINS PINB
|
||||
#define ASDF_COLCLK_DDR DDRB
|
||||
#define ASDF_COLCLK_BIT 2
|
||||
|
||||
#define ASDF_COLMODE_PORT PORTB
|
||||
#define ASDF_COLMODE_PINS PINB
|
||||
#define ASDF_COLMODE_DDR DDRB
|
||||
#define ASDF_COLMODE_BIT 1
|
||||
|
||||
#define ASDF_ASCII_PORT PORTD
|
||||
#define ASDF_ASCII_DDR DDRD
|
||||
|
||||
#define ASDF_LED1_PORT PORTC
|
||||
#define ASDF_LED1_DDR DDRC
|
||||
#define ASDF_LED1_BIT 4
|
||||
|
||||
#define ASDF_LED2_PORT PORTB
|
||||
#define ASDF_LED2_DDR DDRB
|
||||
#define ASDF_LED2_BIT 5
|
||||
|
||||
#define ASDF_LED3_PORT PORTB
|
||||
#define ASDF_LED3_DDR DDRB
|
||||
#define ASDF_LED3_BIT 4
|
||||
|
||||
#define ASDF_OUT1_PORT PORTC
|
||||
#define ASDF_OUT1_PIN PINC
|
||||
#define ASDF_OUT1_DDR DDRC
|
||||
#define ASDF_OUT1_BIT 5
|
||||
|
||||
#define ASDF_OUT2_PORT PORTB
|
||||
#define ASDF_OUT2_PIN PINB
|
||||
#define ASDF_OUT2_DDR DDRB
|
||||
#define ASDF_OUT2_BIT 3
|
||||
|
||||
#define ASDF_OUT3_PORT PORTB
|
||||
#define ASDF_OUT3_PIN PINB
|
||||
#define ASDF_OUT3_DDR DDRB
|
||||
#define ASDF_OUT3_BIT 7
|
||||
|
||||
#define ASDF_STROBE_PORT PORTB
|
||||
#define ASDF_STROBE_PIN PINB
|
||||
#define ASDF_STROBE_DDR DDRB
|
||||
#define ASDF_STROBE_BIT 6
|
||||
|
||||
#define ASDF_ARCH_DIP_SWITCH_ROW 8
|
||||
|
||||
#define FUSE_INTERNAL_8MHZ_OSC_0MS (FUSE_CKSEL0 | FUSE_CKSEL2 | FUSE_CKSEL3 | FUSE_SUT0 | FUSE_SUT1)
|
||||
#define FUSE_INTERNAL_8MHZ_OSC_4MS (FUSE_CKSEL0 | FUSE_CKSEL2 | FUSE_CKSEL3 | FUSE_SUT1)
|
||||
#define FUSE_INTERNAL_8MHZ_OSC_65MS (FUSE_CKSEL0 | FUSE_CKSEL2 | FUSE_CKSEL3 | FUSE_SUT0)
|
||||
|
||||
#define FLASH PROGMEM
|
||||
|
||||
// not implemented with do-while(0) because this is a function call that returns
|
||||
// a value, and parameters are expanded inside the parameter list, so this will
|
||||
// be valid when substituting for function-like syntax.
|
||||
#define FLASH_READ (a) pgm_read_byte((a))
|
||||
#define FLASH_READ_MATRIX_ELEMENT(matrix, row, col) pgm_read_byte(&((matrix)[(row)][(col)]))
|
||||
|
||||
// For 1 ms tick, (8000000 / 64(prescale)) / 1000(usec) - 1 = 124
|
||||
#define TICK_COUNT 124
|
||||
|
||||
|
||||
// Default key matrix row scanner
|
||||
#define ASDF_ARCH_DEFAULT_SCANNER asdf_arch_read_row
|
||||
|
||||
// Default keyboard output
|
||||
#define ASDF_ARCH_DEFAULT_OUTPUT asdf_arch_send_code
|
||||
|
||||
// DIP switch is on row 8
|
||||
#define ASDF_ARCH_DIPSWITCH_ROW 8
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
void asdf_arch_set_pos_strobe(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
void asdf_arch_set_neg_strobe(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: null/dummy output function
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
void asdf_arch_null_output(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
void asdf_arch_led1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
void asdf_arch_led2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
void asdf_arch_led3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
void asdf_arch_out1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
void asdf_arch_out2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
|
||||
// NOTES: Not supported for the ATMega-328 ASCII interface.
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit to high if value is true, and hi-z if value is false.
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
void asdf_arch_out3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the active (pressed) columns
|
||||
// DESCRIPTION: Outputs the argument to the ROW port, then reads the column port
|
||||
// and returns the value. The value is a binary representation of the keys
|
||||
// pressed within the row, with 1=pressed, 0=released.
|
||||
asdf_cols_t asdf_arch_read_row(uint8_t row);
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by ASDF_PULSE_DELAY_SHORT_US
|
||||
void asdf_arch_pulse_delay_short(void);
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses specified by ASDF_PULSE_DELAY_LONG_MS
|
||||
void asdf_arch_pulse_delay_long(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms);
|
||||
|
||||
// PROCEDURE: asdf_arch_tick
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns a 1 if the 1ms timer timed out, 0 otherwise
|
||||
uint8_t asdf_arch_tick(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: (keycode_t) code - the code to be output by the keyboard
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Takes a character code and outputs the code on a parallel ASCII
|
||||
// port, with a strobe. This routine could be replaced with UART, I2C, USB, or
|
||||
// other output mechanism, of course.
|
||||
void asdf_arch_send_code(asdf_keycode_t code);
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
void asdf_arch_init(void);
|
||||
|
||||
#endif /* !defined (ASDF_ARCH_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,623 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch.c
|
||||
//
|
||||
// This file contains all the architecture dependent code, including register
|
||||
// setup, I/O, timers, etc.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// Wiring Information:
|
||||
// Chip: {Microcontroller type and version}
|
||||
//
|
||||
// Example:
|
||||
// PIN NAME FUNCTION
|
||||
// 14-19,9,10 PORTB COLUMN inputs (1 bit per column)
|
||||
// 23-25 PORTC0-2 ROW outputs (row number)
|
||||
// 27 PORTC4
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "asdf_config.h"
|
||||
#include "asdf_physical.h"
|
||||
#include "asdf_arch.h"
|
||||
|
||||
typedef enum {
|
||||
PULSE_EVENT_SET_HIGH,
|
||||
PULSE_EVENT_SET_LOW,
|
||||
PULSE_EVENT_DELAY,
|
||||
NUM_PULSE_EVENTS
|
||||
} pulse_event_t;
|
||||
|
||||
static pulse_state_t pulse_transition_table[PD_ST_NUM_VALID_PULSE_STATES][NUM_PULSE_EVENTS] =
|
||||
{
|
||||
[PD_ST_INITIAL_STATE] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_STABLE_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_STABLE_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_PULSE_FROM_INITIAL_STATE,
|
||||
},
|
||||
[PD_ST_STABLE_LOW] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_TRANSITION_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_STABLE_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_NO_TRANSITION_BEFORE_DELAY,
|
||||
},
|
||||
[PD_ST_STABLE_HIGH] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_STABLE_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_TRANSITION_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_NO_TRANSITION_BEFORE_DELAY,
|
||||
},
|
||||
[PD_ST_TRANSITION_LOW] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_TRANSITION_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_STABLE_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_PULSE_DELAY_LOW,
|
||||
},
|
||||
[PD_ST_TRANSITION_HIGH] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_STABLE_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_TRANSITION_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_PULSE_DELAY_HIGH,
|
||||
},
|
||||
[PD_ST_PULSE_DELAY_LOW] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_PULSE_LOW_DETECTED,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_ERROR_NO_TRANSITION_AFTER_DELAY,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_DOUBLE_DELAY,
|
||||
},
|
||||
[PD_ST_PULSE_DELAY_HIGH] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_ERROR_NO_TRANSITION_AFTER_DELAY,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_PULSE_HIGH_DETECTED,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_DOUBLE_DELAY,
|
||||
},
|
||||
[PD_ST_PULSE_HIGH_DETECTED] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_TRANSITION_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_STABLE_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_NO_TRANSITION_BEFORE_DELAY
|
||||
},
|
||||
[PD_ST_PULSE_LOW_DETECTED] =
|
||||
{
|
||||
[PULSE_EVENT_SET_HIGH] = PD_ST_STABLE_HIGH,
|
||||
[PULSE_EVENT_SET_LOW] = PD_ST_TRANSITION_LOW,
|
||||
[PULSE_EVENT_DELAY] = PD_ST_ERROR_NO_TRANSITION_BEFORE_DELAY
|
||||
},
|
||||
};
|
||||
|
||||
static uint8_t outputs[ASDF_PHYSICAL_NUM_RESOURCES];
|
||||
static pulse_state_t pulses[ASDF_PHYSICAL_NUM_RESOURCES];
|
||||
|
||||
|
||||
|
||||
static asdf_keycode_t code_register;
|
||||
static uint8_t code_sent;
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: asdf_keycode_t code
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: emulates sending a code, by copying code to a register that can
|
||||
// be tested.
|
||||
//
|
||||
// SIDE_EFFECTS: sets code_sent variable and alters code_register
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_send_code(asdf_keycode_t code)
|
||||
{
|
||||
code_register = code;
|
||||
code_sent = 1;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_get_sent_code
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns type (asdf_keycode_t) in register and zeros the register.
|
||||
// DESCRIPTION: faciliates test of sending a code, by reporting contents of the
|
||||
// "sent register". Resets code_sent variable.
|
||||
//
|
||||
// SIDE_EFFECTS: alters code_sent variable
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
asdf_keycode_t asdf_arch_get_sent_code(void)
|
||||
{
|
||||
code_sent = 0;
|
||||
return code_register;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_was_code_sent
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns TRUE if a code was sent, FALSE otherwise.
|
||||
// DESCRIPTION: returns status of code_sent variable.
|
||||
//
|
||||
// SIDE_EFFECTS: sets code_sent variable and alters code_register
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t asdf_arch_was_code_sent(void){
|
||||
return code_sent;
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: pulse_detect
|
||||
// INPUTS: (pulse_state_t) current_state
|
||||
// (pulse_event_t) event - current input to the state machine
|
||||
// OUTPUTS: returns new pulse detector state for the output.
|
||||
//
|
||||
// DESCRIPTION: Given an output and a new value for the output, calculate the
|
||||
// next state of the pulse detector for the output.
|
||||
//
|
||||
// SIDE EFFECTS: none.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
static pulse_state_t pulse_detect(pulse_state_t current_state, pulse_event_t event)
|
||||
{
|
||||
pulse_state_t next_state = current_state;
|
||||
|
||||
// advance state if current state is valid (not an error state)
|
||||
if (current_state < PD_ST_NUM_VALID_PULSE_STATES) {
|
||||
next_state = pulse_transition_table[current_state][event];
|
||||
}
|
||||
return next_state;
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: set_output
|
||||
// INPUTS: (asdf_physical_dev_t) output_dev - the output to set
|
||||
// (uint8_t) value - value to assert on the output
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Given an output and a new value for the output, set the output
|
||||
// and advance the pulse detector state for the output.
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void set_output(asdf_physical_dev_t output_dev, uint8_t value)
|
||||
{
|
||||
pulse_event_t pulse_event = value ? PULSE_EVENT_SET_HIGH : PULSE_EVENT_SET_LOW;
|
||||
|
||||
outputs[output_dev] = value;
|
||||
pulses[output_dev] = pulse_detect(pulses[output_dev], pulse_event);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Does nothing.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_null_output(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_NO_OUT, value);
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_led1_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_LED1, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_led2_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_LED2, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_led3_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_LED3, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out1_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_OUT1, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT1 bit to hi-z if value is true, and low
|
||||
// if value is false. For testing, set PHYSICAL_OUT1_OPEN_HI to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT1 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT1_OPEN_LO to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_out2_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_OUT2, value);
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT2 bit to hi-z if value is true, and low
|
||||
// if value is false. For testing, set PHYSICAL_OUT2_OPEN_HI to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT2 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT2_OPEN_LO to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out3_set(uint8_t value)
|
||||
{
|
||||
set_output(PHYSICAL_OUT3, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT3 bit to hi-z if value is true, and low
|
||||
// if value is false. For testing, set PHYSICAL_OUT3_OPEN_HI to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates setting the OUT3 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT3_OPEN_LO to the value.
|
||||
//
|
||||
// SIDE EFFECTS: See above.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value)
|
||||
{set_output(PHYSICAL_OUT1_OPEN_HI, value);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_check_output
|
||||
// INPUTS:(asdf_physical_dev_t) device - which device to check
|
||||
// OUTPUTS: the value of the device setting.
|
||||
//
|
||||
// DESCRIPTION: For a given physical device, return the current setting (true or false)
|
||||
//
|
||||
// SIDE EFFECTS: none
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t asdf_arch_check_output(asdf_physical_dev_t device)
|
||||
{
|
||||
return outputs[device];
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_check_pulse
|
||||
// INPUTS:(asdf_physical_dev_t) device - which device to check
|
||||
// OUTPUTS: the value of the device pulse detector
|
||||
//
|
||||
// DESCRIPTION: For a given physical device, return the state of the pulse detector
|
||||
//
|
||||
// SIDE EFFECTS: none
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t asdf_arch_check_pulse(asdf_physical_dev_t device)
|
||||
{
|
||||
return pulses[device];
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates a delay by advancing the pulse detector state machine
|
||||
// for each output.
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
void asdf_arch_pulse_delay(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < ASDF_PHYSICAL_NUM_RESOURCES; i++) {
|
||||
pulses[i] = pulse_detect(pulses[i], PULSE_EVENT_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates a long delay by advancing the pulse detector state machine
|
||||
// for each output.
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_long(void)
|
||||
{
|
||||
asdf_arch_pulse_delay();
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms)
|
||||
{
|
||||
asdf_arch_pulse_delay();
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Emulates a short delay by advancing the pulse detector state machine
|
||||
// for each output.
|
||||
//
|
||||
// SIDE EFFECTS: see above.
|
||||
//
|
||||
// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_pulse_delay_short(void)
|
||||
{
|
||||
asdf_arch_pulse_delay();
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
void asdf_arch_set_pos_strobe(void) {}
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
void asdf_arch_set_neg_strobe(void) {}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
//
|
||||
// SIDE EFFECTS: see DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_arch_init(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < ASDF_PHYSICAL_NUM_RESOURCES; i++) {
|
||||
outputs[i] = 0;
|
||||
pulses[i] = PD_ST_INITIAL_STATE;
|
||||
}
|
||||
|
||||
// initially, no keycodes have been sent via asdf_arch_send_code:
|
||||
code_sent = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
//
|
|
@ -1,236 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_arch_test.h
|
||||
//
|
||||
// Architecture-dependent definitions for the unit-testing ASDF software.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#if !defined (ASDF_ARCH_H)
|
||||
#define ASDF_ARCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "asdf.h"
|
||||
#include "asdf_config.h"
|
||||
#include "asdf_physical.h"
|
||||
#include "asdf_virtual.h"
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
PD_ST_INITIAL_STATE = 0,
|
||||
PD_ST_STABLE_LOW = 1,
|
||||
PD_ST_STABLE_HIGH = 2,
|
||||
PD_ST_TRANSITION_LOW = 3,
|
||||
PD_ST_TRANSITION_HIGH = 4,
|
||||
PD_ST_PULSE_DELAY_LOW = 5,
|
||||
PD_ST_PULSE_DELAY_HIGH = 6,
|
||||
PD_ST_PULSE_HIGH_DETECTED = 7,
|
||||
PD_ST_PULSE_LOW_DETECTED = 8,
|
||||
PD_ST_NUM_VALID_PULSE_STATES = 9, // error states below this
|
||||
PD_ST_ERROR_DOUBLE_DELAY = 10,
|
||||
PD_ST_ERROR_DOUBLE_SET = 11,
|
||||
PD_ST_ERROR_NO_TRANSITION_BEFORE_DELAY = 12,
|
||||
PD_ST_ERROR_NO_TRANSITION_AFTER_DELAY = 13,
|
||||
PD_ST_ERROR_DOUBLE_TRANSITION = 14, // fast pulse without delay
|
||||
PD_ST_ERROR_PULSE_FROM_INITIAL_STATE = 15,
|
||||
} pulse_state_t;
|
||||
|
||||
#define FLASH
|
||||
#define FLASH_READ (a) (*(a))
|
||||
#define FLASH_READ_MATRIX_ELEMENT(mat,row,col) (mat)[(row)][(col)]
|
||||
#define ASDF_ARCH_DEFAULT_SCANNER asdf_arch_read_row
|
||||
#define ASDF_ARCH_DEFAULT_OUTPUT asdf_arch_send_code
|
||||
|
||||
// PROCEDURE: asdf_arch_pos_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output to positive polarity. Initial state is
|
||||
// LOW
|
||||
void asdf_arch_set_pos_strobe(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_neg_strobe
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize strobe output
|
||||
void asdf_arch_set_neg_strobe(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_null_output
|
||||
// INPUTS: (uint8_t) value - ignored
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Does nothing.
|
||||
void asdf_arch_null_output(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
|
||||
void asdf_arch_led1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
|
||||
void asdf_arch_led2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_led3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
|
||||
void asdf_arch_led3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
|
||||
void asdf_arch_out1_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT1 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT1_OPEN_LO to the value.
|
||||
void asdf_arch_out1_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out1_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT1 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT1_OPEN_LO to the value.
|
||||
void asdf_arch_out1_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
|
||||
void asdf_arch_out2_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT2 bit to hi-z if value is true, and low
|
||||
// if value is false. For testing, set PHYSICAL_OUT2_OPEN_HI to the value.
|
||||
void asdf_arch_out2_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out2_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT2 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT2_OPEN_LO to the value.
|
||||
void asdf_arch_out2_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
|
||||
void asdf_arch_out3_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_hi_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT3 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT3_OPEN_LO to the value.
|
||||
void asdf_arch_out3_open_hi_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_out3_open_lo_set
|
||||
// INPUTS: (uint8_t) value
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates setting the OUT3 bit to high if value is true, and hi-z
|
||||
// if value is false. For testing, set PHYSICAL_OUT3_OPEN_LO to the value.
|
||||
void asdf_arch_out3_open_lo_set(uint8_t value);
|
||||
|
||||
// PROCEDURE: asdf_arch_check_output
|
||||
// INPUTS:(asdf_physical_dev_t) device - which device to check
|
||||
// OUTPUTS: the value of the device setting.
|
||||
// DESCRIPTION: For a given real device, return the current setting (true or false)
|
||||
uint8_t asdf_arch_check_output(asdf_physical_dev_t device);
|
||||
|
||||
// PROCEDURE: asdf_arch_check_pulse
|
||||
// INPUTS:(asdf_physical_dev_t) device - which device to check
|
||||
// OUTPUTS: the value of the device pulse detector
|
||||
// DESCRIPTION: For a given real device, return the state of the pulse detector
|
||||
uint8_t asdf_arch_check_pulse(asdf_physical_dev_t device);
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_short
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates a short delay by advancing the pulse detector state machine
|
||||
// for each output.
|
||||
void asdf_arch_pulse_delay_short(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_pulse_delay_long
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Emulates a long delay by advancing the pulse detector state machine
|
||||
// for each output.
|
||||
void asdf_arch_pulse_delay_long(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_read_row
|
||||
// INPUTS: (uint8_t) row: the row number to be scanned
|
||||
// OUTPUTS: returns a word containing the emulated active (pressed) columns
|
||||
// DESCRIPTION: reads the word from the key state emulation array and returns
|
||||
// the value. The value is a binary representation of the keys pressed within
|
||||
// the row, with 1=pressed, 0=released.
|
||||
asdf_cols_t asdf_arch_read_row(uint8_t row);
|
||||
|
||||
// PROCEDURE: asdf_arch_send_code
|
||||
// INPUTS: asdf_keycode_t code
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: emulates sending a code, by copying code to a register that can
|
||||
// be tested.
|
||||
void asdf_arch_send_code(asdf_keycode_t);
|
||||
|
||||
// PROCEDURE: asdf_arch_delay_ms
|
||||
// INPUTS: (uint16) delay_ms - the delay in msec.
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Delays a specified number of milliseconds
|
||||
void asdf_arch_delay_ms(uint16_t delay_ms);
|
||||
|
||||
// PROCEDURE: asdf_arch_get_sent_code
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns type (asdf_keycode_t) in register and zeros the register.
|
||||
// DESCRIPTION: faciliates test of sending a code, by reporting contents of the
|
||||
// "sent register"
|
||||
asdf_keycode_t asdf_arch_get_sent_code(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_was_code_sent
|
||||
// INPUTS: none
|
||||
// OUTPUTS: returns TRUE if a code was sent, FALSE otherwise.
|
||||
uint8_t asdf_arch_was_code_sent(void);
|
||||
|
||||
// PROCEDURE: asdf_arch_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: sets up all the hardware for the keyboard
|
||||
void asdf_arch_init(void);
|
||||
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
//
|
||||
|
||||
#endif // !defined (ASDF_ARCH_H)
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
|
||||
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
message("C compiler: ${CMAKE_C_COMPILER}")
|
||||
|
||||
function(create_keymap_setups keymaps keymap_table)
|
||||
list(TRANSFORM keymaps REPLACE "<\(.+\):\(.+\)>" "\n case \\2: setup_\\1_keymap();break" OUTPUT_VARIABLE temp_list)
|
||||
# we can keep the ';' cmake list separators as the C statement separators.
|
||||
# However, we need to append an extra ';' at the end.
|
||||
string(APPEND temp_list ";")
|
||||
set(${keymap_table} "${temp_list}" PARENT_SCOPE)
|
||||
endfunction(create_keymap_setups)
|
||||
|
||||
function(create_keymap_valid keymaps keymap_valid)
|
||||
list(TRANSFORM keymaps REPLACE "<\(.+\):\(.+\)>" "\n case \\2:" OUTPUT_VARIABLE temp_list)
|
||||
# we can keep the ';' cmake list separators as the C statement separators.
|
||||
# However, we need to append an extra ';' at the end.
|
||||
string(APPEND temp_list ";")
|
||||
set(${keymap_valid} "${temp_list}" PARENT_SCOPE)
|
||||
endfunction(create_keymap_valid)
|
||||
|
||||
function(create_keymap_declarations keymaps keymap_decl)
|
||||
list(TRANSFORM keymaps REPLACE "<\(.+\):\(.+\)>" "\n void setup_\\1_keymap(void)" OUTPUT_VARIABLE temp_list)
|
||||
# we can keep the ';' cmake list separators as the C statement separators.
|
||||
# However, we need to append an extra ';' at the end.
|
||||
string(APPEND temp_list ";")
|
||||
set(${keymap_decl} "${temp_list}" PARENT_SCOPE)
|
||||
endfunction(create_keymap_declarations)
|
||||
|
||||
function(create_keymap_report keymaps keymap_report)
|
||||
list(TRANSFORM keymaps REPLACE "<\(.+\):\(.+\)>" "\nkeymap [\\2]: \\1" OUTPUT_VARIABLE temp_list)
|
||||
string(REPLACE ";" "" temp_list2 "${temp_list}")
|
||||
set(${keymap_report} "${temp_list2}" PARENT_SCOPE)
|
||||
endfunction(create_keymap_report)
|
||||
|
||||
include(../keymap_list.cmake)
|
||||
|
||||
create_keymap_setups("${keymap_list}" keymap_table)
|
||||
create_keymap_valid("${keymap_list}" keymap_valid)
|
||||
create_keymap_report("${keymap_list}" keymap_report)
|
||||
create_keymap_declarations("${keymap_list}" keymap_declarations)
|
||||
|
||||
# get list length and decrement by one to account for trailing semicolon
|
||||
list (LENGTH keymap_list num_keymaps)
|
||||
|
||||
message("**********************")
|
||||
message("Keymap table: ${keymap_report}")
|
||||
message("**********************\n\n")
|
||||
|
||||
set (PROJECT_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
configure_file(${PROJECT_SRC_DIR}/Arch/asdf_arch_${ARCH}.h ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.h COPYONLY)
|
||||
configure_file(${PROJECT_SRC_DIR}/Arch/asdf_arch_${ARCH}.c ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.c COPYONLY)
|
||||
configure_file(${PROJECT_SRC_DIR}/asdf_keymap_setup.c.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.c)
|
||||
configure_file(${PROJECT_SRC_DIR}/asdf_keymap_setup.h.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.h)
|
||||
|
||||
|
||||
c_toolchain_flags()
|
||||
|
||||
list (APPEND SOURCES
|
||||
asdf.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.c
|
||||
asdf_buffer.c
|
||||
asdf_hook.c
|
||||
asdf_keymap_setup.c
|
||||
asdf_keymaps.c
|
||||
asdf_modifiers.c
|
||||
asdf_physical.c
|
||||
asdf_repeat.c
|
||||
asdf_virtual.c
|
||||
asdf_print.c
|
||||
Keymaps/asdf_keymap_classic.c
|
||||
Keymaps/asdf_keymap_classic_caps.c
|
||||
Keymaps/asdf_keymap_classic_add_map.c
|
||||
Keymaps/asdf_keymap_apple2.c
|
||||
Keymaps/asdf_keymap_apple2_caps.c
|
||||
Keymaps/asdf_keymap_apple2_add_map.c
|
||||
Keymaps/asdf_keymap_sol.c
|
||||
main.c
|
||||
)
|
||||
|
||||
# create a library for the keymap modules
|
||||
#add_subdirectory(Keymaps)
|
||||
|
||||
# add the executable
|
||||
if (COMMAND custom_add_executable)
|
||||
custom_add_executable(${PROJECT_TARGET_NAME}
|
||||
${SOURCES}
|
||||
)
|
||||
else()
|
||||
add_executable(${PROJECT_TARGET_NAME}
|
||||
${SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_EXECUTABLE_TARGET_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Keymaps
|
||||
|
||||
)
|
||||
|
||||
target_compile_options(${PROJECT_EXECUTABLE_TARGET_NAME}
|
||||
PRIVATE
|
||||
${CFLAGS}
|
||||
)
|
||||
|
||||
#target_link_libraries(${PROJECT_EXECUTABLE_TARGET_NAME}
|
||||
# keymaps
|
||||
# )
|
|
@ -1,674 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
@ -1,46 +0,0 @@
|
|||
---
|
||||
BasedOnStyle: Mozilla
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignOperands: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'true'
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: 'false'
|
||||
AllowShortLoopsOnASingleLine: 'true'
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: 'true'
|
||||
BinPackArguments: 'true'
|
||||
BinPackParameters: 'true'
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Stroustrup
|
||||
ColumnLimit: '100'
|
||||
ConstructorInitializerIndentWidth: '2'
|
||||
ContinuationIndentWidth: '2'
|
||||
DerivePointerAlignment: 'false'
|
||||
DisableFormat: 'false'
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseLabels: 'true'
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: '2'
|
||||
IndentWrappedFunctionNames: 'false'
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'true'
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: '2'
|
||||
PointerAlignment: Right
|
||||
ReflowComments: 'true'
|
||||
SortIncludes: 'false'
|
||||
SpaceAfterCStyleCast: 'true'
|
||||
SpaceBeforeAssignmentOperators: 'true'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesBeforeTrailingComments: '1'
|
||||
SpacesInCStyleCastParentheses: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
TabWidth: '8'
|
||||
UseTab: Never
|
||||
|
||||
...
|
|
@ -1,87 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple2.c
|
||||
//
|
||||
// set up keymaps for Apple II keyboards
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
#include "asdf_print.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_virtual.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_keymap_apple2_add_map.h"
|
||||
#include "asdf_keymap_apple2.h"
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
void apple2_id_message(void) {
|
||||
asdf_print("[Keymap: Apple 2 (u/l case)]");
|
||||
}
|
||||
|
||||
void setup_apple2_keymap(void)
|
||||
{
|
||||
asdf_set_print_delay(APPLE2_PRINT_DELAY);
|
||||
|
||||
|
||||
apple_add_map(APPLE_PLAIN_MAP, MOD_PLAIN_MAP);
|
||||
apple_add_map(APPLE_CAPS_MAP, MOD_CAPS_MAP);
|
||||
apple_add_map(APPLE_SHIFT_MAP, MOD_SHIFT_MAP);
|
||||
apple_add_map(APPLE_CTRL_MAP, MOD_CTRL_MAP);
|
||||
|
||||
asdf_hook_assign(APPLESOFT_KEYBOARD_TEST, applesoft_keyboard_test);
|
||||
asdf_hook_assign(APPLE2_ID_MESSAGE, apple2_id_message);
|
||||
|
||||
// Attach the physical POWER LED as the CAPS LED. Assign no triggered
|
||||
// function, and initialize to initial state of the CAPS logic. The CAPS LED
|
||||
// will be controlled by the state of the CAPSLOCK logic.
|
||||
|
||||
asdf_virtual_assign(VCAPS_LED, APPLE_POWER_LED, V_NOFUNC, APPLE_POWER_LED_INIT_VALUE);
|
||||
|
||||
// Assign CAPS LED to off (disabled)
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_DISABLED_LED, APPLE_DISABLED_LED, V_NOFUNC, APPLE_DISABLED_INIT_VALUE);
|
||||
|
||||
// assign RESET output to the virtual RESET output, configure to produce a short pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_RESET, APPLE_RESET_OUTPUT, V_PULSE_SHORT, !APPLE_RESET_ACTIVE_VALUE);
|
||||
|
||||
// assign the CLRSCR output to the virtual CLRSCR output, configure to produce a long pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_CLR_SCR, APPLE_CLR_SCR_OUTPUT, V_PULSE_LONG, !APPLE_CLR_SCR_ACTIVE_VALUE);
|
||||
|
||||
asdf_modifier_capslock_activate(); // For Apple 2, start with CAPS active
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple2.h
|
||||
//
|
||||
// Apple 2 keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// This file supplies the Apple 2 ASCII keyboard keymap. Two variants are provided:
|
||||
//
|
||||
// 1) An Upper/Lowercase variant. This variant moves the @ and ^ symbols from
|
||||
// the P and N keys to the REPEAT key, since the P and N keys need to reserve
|
||||
// the shifted value for the uppercase characters. Also, the "Power" key
|
||||
// doubles as a caps-lock key.
|
||||
//
|
||||
// 2) A CAPS only keyboard, following the standard Apple II conventions and
|
||||
// layout, with ^ above the N key and @ above the P key, and a functioning
|
||||
// REPEAT key.
|
||||
//
|
||||
// For both variants, CTRL+RESET is required for a system reset.
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_APPLE2_H)
|
||||
#define ASDF_KEYMAP_DEFS_APPLE2_H
|
||||
|
||||
#define APPLESOFT_KEYBOARD_TEST ASDF_HOOK_USER_9
|
||||
#define APPLE2_ID_MESSAGE ASDF_HOOK_USER_10
|
||||
|
||||
#define APPLE2_PRINT_DELAY 40 // msec
|
||||
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_APPLE2_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,178 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic.c
|
||||
//
|
||||
// defines the keymap matrices used by the "classic" ADM 3A style keymap variants
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "asdf_arch.h"
|
||||
#include "asdf.h"
|
||||
#include "asdf_print.h"
|
||||
#include "asdf_ascii.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_keymap_apple2_add_map.h"
|
||||
|
||||
// Key Matrix for combination of ASCII controller and Apple ASCII matrix
|
||||
//
|
||||
// Col-> 0 1 2 3 4 5 6 7
|
||||
// Row 0 POWER R-Shift L-Shift (no key) ESC TAB CTRL \(backslash)
|
||||
// Row 1 Rubout P ; / SPACEBAR Z A Q
|
||||
// Row 2 Break ,(comma) M N B V C X
|
||||
// Row 3 Spare K J H G F D A
|
||||
// Row 4 Rt arrow I U Y T R E W
|
||||
// Row 5 LT arrow Repeat CapsLock Return LineFeed O(alpha) L .(period)
|
||||
// Row 6 ~(tilde) ] [ -(dash) :(colon) 0(numeral) 9 8
|
||||
// Row 7 @(at) 7 6 5 4 3 2 1
|
||||
//
|
||||
// Row 15 DIP switches 0-7
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1) The keys above correspond to the silk screen on the PCB. For the OSI and
|
||||
// Apple layouts, the keys may not all match the silk screen. When creating a
|
||||
// layout different from the silk screen, look up the row and column for the
|
||||
// silk screen label at the desired position, and then place the desired
|
||||
// function in the keymap definition at the desired row and column. For
|
||||
// example, the Apple 2 keymap places the "RESET" key at the "[" silk-screen
|
||||
// position, Row 6, Col 2. The keymap places ACTION_RESET at Row 6, Col 2 in
|
||||
// the "ASDF_APPLE2_CTRL_MAP" to map the RESET function to the CTRL-RESET key
|
||||
// combination.
|
||||
//
|
||||
// 2) To ensure consistent DIP switch operation within the keymap, a
|
||||
// ASDF_ASCII_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
|
||||
// definitions in positions 0-3 ensures consistent map selection among all
|
||||
// keymaps.
|
||||
|
||||
#define ASDF_APPLE2_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
typedef asdf_keycode_t apple_keycode_matrix_t[ASDF_APPLE2_NUM_ROWS][ASDF_APPLE2_NUM_COLS];
|
||||
|
||||
|
||||
const FLASH apple_keycode_matrix_t apple_plain_matrix = {
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW },
|
||||
[1] = { ASCII_DEL, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' },
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' },
|
||||
[3] = { ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' },
|
||||
[4] = { ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' },
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, '^', 'o', 'l', ASCII_PERIOD },
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, '-', ':', ASCII_ZERO, '9', '8' },
|
||||
[7] = { APPLE_LEFT_ARROW, '7', '6', '5', '4', '3', '2', '1' },
|
||||
ASDF_APPLE2_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH apple_keycode_matrix_t apple_shift_matrix = {
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW },
|
||||
[1] = { ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' },
|
||||
[2] = { ACTION_NOTHING, '<', 'M', 'N', 'B', 'V', 'C', 'X' },
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' },
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' },
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ASCII_AT, 'O', 'L', '>' },
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_CLEAR, '=',
|
||||
'*', ASCII_ZERO, ASCII_RT_PAREN, ASCII_LT_PAREN },
|
||||
[7] = { APPLE_LEFT_ARROW, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' },
|
||||
ASDF_APPLE2_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH apple_keycode_matrix_t apple_caps_shift_matrix = {
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW },
|
||||
[1] = { ACTION_NOTHING, ASCII_AT, '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' },
|
||||
[2] = { ACTION_NOTHING, '<', 'M', '^', 'B', 'V', 'C', 'X' },
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' },
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' },
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ACTION_REPEAT, 'O', 'L', '>' },
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_CLEAR, '=',
|
||||
'*', ASCII_ZERO, ASCII_RT_PAREN, ASCII_LT_PAREN },
|
||||
[7] = { APPLE_LEFT_ARROW, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' },
|
||||
ASDF_APPLE2_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH apple_keycode_matrix_t apple_caps_matrix = {
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW },
|
||||
[1] = { ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' },
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' },
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' },
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' },
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ACTION_REPEAT, 'O', 'L', ASCII_PERIOD },
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, '-', ':', ASCII_ZERO, '9', '8' },
|
||||
[7] = { APPLE_LEFT_ARROW, '7', '6', '5', '4', '3', '2', '1' },
|
||||
ASDF_APPLE2_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH apple_keycode_matrix_t apple_ctrl_matrix = {
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW },
|
||||
[1] = { ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING,
|
||||
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q },
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N,
|
||||
ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X },
|
||||
[3] = { ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H,
|
||||
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S },
|
||||
[4] = { ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y,
|
||||
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W },
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR,
|
||||
ACTION_REPEAT, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING },
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_RESET, ACTION_NOTHING,
|
||||
ACTION_NOTHING, ACTION_FN_10, ACTION_FN_9, ACTION_FN_8 },
|
||||
[7] = { APPLE_LEFT_ARROW, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5,
|
||||
ACTION_FN_4, ACTION_FN_3, ACTION_FN_2, ACTION_FN_1 },
|
||||
ASDF_APPLE2_DIP_SWITCHES
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const apple_keycode_matrix_t *apple_maps[] = {
|
||||
[APPLE_CAPS_MAP] = &apple_caps_matrix,
|
||||
[APPLE_PLAIN_MAP] = &apple_plain_matrix,
|
||||
[APPLE_SHIFT_MAP] = &apple_shift_matrix,
|
||||
[APPLE_CTRL_MAP] = &apple_ctrl_matrix,
|
||||
[APPLE_CAPS_SHIFT_MAP] = &apple_caps_shift_matrix
|
||||
};
|
||||
|
||||
void applesoft_keyboard_test(void)
|
||||
{
|
||||
asdf_print("10 GET A$\r");
|
||||
asdf_print("20 A = ASC(A$)\r");
|
||||
asdf_print("30 IF A < 32 THEN A$=\"CTL+\"+CHR$(A + 64)\r");
|
||||
asdf_print("40 ?\"'\";A$;\"' = \";A:\r");
|
||||
asdf_print("50 IF A <> 3 GOTO 10\r");
|
||||
asdf_print("60 END\rRUN\r");
|
||||
|
||||
}
|
||||
|
||||
void apple_add_map(const apple_map_index_t map_index,
|
||||
modifier_index_t modifier_index)
|
||||
{
|
||||
|
||||
asdf_keycode_t (*matrix)[ASDF_APPLE2_NUM_COLS] =
|
||||
(asdf_keycode_t (*)[ASDF_APPLE2_NUM_COLS]) apple_maps[map_index];
|
||||
|
||||
asdf_keymaps_add_map(&matrix[0][0], modifier_index, (uint8_t) ASDF_APPLE2_NUM_ROWS,
|
||||
(uint8_t) ASDF_APPLE2_NUM_COLS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,80 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple_add_map.h
|
||||
//
|
||||
// defines keymap matrices and add_map() function for apple2 layouts
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// To use this ascii for a new keymap, edit the keymaps definitions as
|
||||
// desired. The keymaps are organized from row 0, counting upward, and each row
|
||||
// includes the columns from 0-NUM_COLS.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_KEYMAP_APPLE_ADD_MAP_H)
|
||||
#define ASDF_KEYMAP_APPLE_ADD_MAP_H
|
||||
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
#include "asdf_modifiers.h"
|
||||
|
||||
#define ASDF_APPLE2_NUM_ROWS 9 // DIP switches are row 8 (zero-based)
|
||||
#define ASDF_APPLE2_NUM_COLS 8
|
||||
|
||||
#define APPLE_ACTION_RESET ACTION_VOUT1
|
||||
#define APPLE_VIRTUAL_RESET VOUT1
|
||||
#define APPLE_RESET_OUTPUT PHYSICAL_OUT3_OPEN_HI
|
||||
#define APPLE_RESET_ACTIVE_VALUE 0
|
||||
|
||||
#define APPLE_ACTION_CLEAR ACTION_VOUT2
|
||||
#define APPLE_VIRTUAL_CLR_SCR VOUT2
|
||||
#define APPLE_CLR_SCR_OUTPUT PHYSICAL_OUT1_OPEN_LO
|
||||
#define APPLE_CLR_SCR_ACTIVE_VALUE 1
|
||||
|
||||
#define APPLE_VIRTUAL_POWER_LED VLED1
|
||||
#define APPLE_POWER_LED PHYSICAL_LED1
|
||||
#define APPLE_POWER_LED_INIT_VALUE 0 // Toggles when caps lock is activated
|
||||
|
||||
#define APPLE_VIRTUAL_DISABLED_LED VLED2
|
||||
#define APPLE_DISABLED_LED PHYSICAL_LED3
|
||||
#define APPLE_DISABLED_INIT_VALUE 0
|
||||
|
||||
#define ASDF_APPLE2_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
#define APPLE_LEFT_ARROW ASCII_CTRL_H
|
||||
#define APPLE_RIGHT_ARROW ASCII_CTRL_U
|
||||
|
||||
typedef enum {
|
||||
APPLE_PLAIN_MAP,
|
||||
APPLE_CAPS_MAP,
|
||||
APPLE_SHIFT_MAP,
|
||||
APPLE_CAPS_SHIFT_MAP,
|
||||
APPLE_CTRL_MAP
|
||||
} apple_map_index_t;
|
||||
|
||||
|
||||
// function prototypes
|
||||
void applesoft_keyboard_test(void);
|
||||
|
||||
void apple_add_map(const apple_map_index_t map_index, modifier_index_t modifier_index);
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_APPLE_ADD_MAP_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,80 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple2_caps.c
|
||||
//
|
||||
// set up keymaps for ALL CAPS Apple II keyboards
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
#include "asdf_print.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_virtual.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_keymap_apple2_add_map.h"
|
||||
#include "asdf_keymap_apple2_caps.h"
|
||||
|
||||
void apple2_caps_id_message(void) {
|
||||
asdf_print("[Keymap: Apple 2 CAPS]");
|
||||
}
|
||||
|
||||
// PROCEDURE: setup_apple2_caps_keymap
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Set up keymaps for ALL CAPS apple 2 keyboard
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void setup_apple2_caps_keymap(void)
|
||||
{
|
||||
asdf_set_print_delay(APPLE2_PRINT_DELAY);
|
||||
|
||||
apple_add_map(APPLE_CAPS_MAP, MOD_PLAIN_MAP);
|
||||
apple_add_map(APPLE_CAPS_MAP, MOD_CAPS_MAP);
|
||||
apple_add_map(APPLE_CAPS_SHIFT_MAP, MOD_SHIFT_MAP);
|
||||
apple_add_map(APPLE_CTRL_MAP, MOD_CTRL_MAP);
|
||||
|
||||
asdf_hook_assign(APPLESOFT_KEYBOARD_TEST, applesoft_keyboard_test);
|
||||
asdf_hook_assign(APPLE2_CAPS_ID_MESSAGE, apple2_caps_id_message);
|
||||
|
||||
// Turn the POWER LED on and don't assign to any function
|
||||
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_POWER_LED, APPLE_POWER_LED, V_NOFUNC, APPLE_POWER_LED_INIT_VALUE);
|
||||
|
||||
// Assign CAPS LED to off (disabled)
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_DISABLED_LED, APPLE_DISABLED_LED, V_NOFUNC, APPLE_DISABLED_INIT_VALUE);
|
||||
|
||||
// assign RESET output to the virtual RESET output, configure to produce a short pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_RESET, APPLE_RESET_OUTPUT, V_PULSE_SHORT, !APPLE_RESET_ACTIVE_VALUE);
|
||||
|
||||
// assign the CLRSCR output to the virtual CLRSCR output, configure to produce a long pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_CLR_SCR, APPLE_CLR_SCR_OUTPUT, V_PULSE_LONG, !APPLE_CLR_SCR_ACTIVE_VALUE);
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,51 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple2_caps.h
|
||||
//
|
||||
// Apple 2 keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// This file supplies the Apple 2 ASCII keyboard keymap. Two variants are provided:
|
||||
//
|
||||
// 1) An Upper/Lowercase variant. This variant moves the @ and ^ symbols from
|
||||
// the P and N keys to the REPEAT key, since the P and N keys need to reserve
|
||||
// the shifted value for the uppercase characters. Also, the "Power" key
|
||||
// doubles as a caps-lock key.
|
||||
//
|
||||
// 2) A CAPS only keyboard, following the standard Apple II conventions and
|
||||
// layout, with ^ above the N key and @ above the P key, and a functioning
|
||||
// REPEAT key.
|
||||
//
|
||||
// For both variants, CTRL+RESET is required for a system reset.
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_APPLE2_CAPS_H)
|
||||
#define ASDF_KEYMAP_DEFS_APPLE2_CAPS_H
|
||||
|
||||
#define APPLESOFT_KEYBOARD_TEST ASDF_HOOK_USER_9
|
||||
#define APPLE2_CAPS_ID_MESSAGE ASDF_HOOK_USER_10
|
||||
|
||||
#define APPLE2_PRINT_DELAY 40 // msec
|
||||
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_APPLE2_CAPS_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,106 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_apple2.c
|
||||
//
|
||||
// set up keymaps for Apple II keyboards
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
#include "asdf_keymap_apple2.h"
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
|
||||
|
||||
// PROCEDURE: apple_add_map
|
||||
|
||||
// INPUTS: asdf_keycode_t (*matrix) - a SOL_NUM_ROWS x SOL_NUM_COLS matrix of
|
||||
// keycodes for each physical row/column pair
|
||||
// modifier_index_t modifier index - the modifier state corresponding to
|
||||
// the keycode matrix
|
||||
//
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Passes the keycode matrix and modifier state through to
|
||||
// asdf_keymaps_add_map(), along with the row/column dimensions.
|
||||
//
|
||||
// SIDE EFFECTS: the matrix is added to the keymap
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void apple_add_map(const asdf_keycode_t (*matrix)[APPLE_NUM_COLS],
|
||||
modifier_index_t modifier_index)
|
||||
{
|
||||
asdf_keymaps_add_map(&matrix[0][0], modifier_index, (uint8_t) APPLE_NUM_ROWS,
|
||||
(uint8_t) APPLE_NUM_COLS);
|
||||
}
|
||||
|
||||
void setup_classic_keymap(void)
|
||||
{
|
||||
apple_add_map(apple_plain_map, MOD_PLAIN_MAP);
|
||||
apple_add_map(apple_caps_map, MOD_CAPS_MAP);
|
||||
apple_add_map(apple_shift_map, MOD_SHIFT_MAP);
|
||||
apple_add_map(apple_ctrl_map, MOD_CTRL_MAP);
|
||||
|
||||
asdf_virtual_init();
|
||||
|
||||
|
||||
// Attach the physical POWER LED as the CAPS LED. Assign no triggered
|
||||
// function, and initialize to initial state of the CAPS logic. The CAPS LED
|
||||
// will be controlled by the state of the CAPSLOCK logic.
|
||||
{ .virtual_device = VCAPS_LED, .physical_device = APPLE_POWER_LED, .initial_value = 0 }, \
|
||||
asdf_virtual_assign(VCAPS_LED, APPLE_POWER_LED, V_NOFUNC, APPLE_POWER_LED_INIT_VALUE);
|
||||
|
||||
// Assign CAPS LED to virtual CAPS LED, and initialize to the INIT value, to
|
||||
// match the initial CAPSLOCK state. The capslock state code will alter the
|
||||
// virtual LED according to the state.
|
||||
asdf_virtual_assign(VCAPS_LED, APPLE_CAPS_LED, V_NOFUNC, APPLE_CAPS_LED_INIT_VALUE);
|
||||
{ .virtual_device = APPLE_VIRTUAL_DISABLED_LED, \
|
||||
.physical_device = APPLE_DISABLED_LED, \
|
||||
.initial_value = 0 }, \
|
||||
|
||||
// assign RESET output to the virtual RESET output, configure to produce a short pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_RESET, APPLE_RESET_OUTPUT, V_PULSE_SHORT, !APPLE_RESET_ACTIVE_VALUE);
|
||||
|
||||
// assign the CLRSCR output to the virtual CLRSCR output, configure to produce a long pulse when activated
|
||||
asdf_virtual_assign(APPLE_VIRTUAL_CLR_SCR, APPLE_CLR_SCR_OUTPUT, V_PULSE_LONG, !APPLE_CLR_SCR_ACTIVE_VALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic.c
|
||||
//
|
||||
// Implements the "classic" ADM 3A style keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "asdf.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_virtual.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_print.h"
|
||||
#include "asdf_keymap_classic.h"
|
||||
#include "asdf_keymap_classic_add_map.h"
|
||||
#include "asdf_keymap_apple2_add_map.h"
|
||||
|
||||
void classic_id_message(void) {
|
||||
asdf_print("[Keymap: classic]\n");
|
||||
}
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
void setup_classic_keymap(void)
|
||||
{
|
||||
asdf_set_print_delay(ASDF_CLASSIC_PRINT_SPEED); //msec
|
||||
|
||||
classic_add_map(CLASSIC_PLAIN_MAP, MOD_PLAIN_MAP);
|
||||
classic_add_map(CLASSIC_CAPS_MAP, MOD_CAPS_MAP);
|
||||
classic_add_map(CLASSIC_SHIFT_MAP, MOD_SHIFT_MAP);
|
||||
classic_add_map(CLASSIC_CTRL_MAP, MOD_CTRL_MAP);
|
||||
|
||||
asdf_hook_assign(CLASSIC_ID_MESSAGE_HOOK, classic_id_message);
|
||||
asdf_hook_assign(APPLESOFT_KEYBOARD_TEST_HOOK, applesoft_keyboard_test);
|
||||
|
||||
// Assign power LED to virtual power LED, and initialize to ON
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_POWER_LED, CLASSIC_POWER_LED, V_NOFUNC, CLASSIC_POWER_LED_INIT_VALUE);
|
||||
|
||||
// Assign CAPS LED to virtual CAPS LED, and initialize to the INIT value, to
|
||||
// match the initial CAPSLOCK state. The capslock state code will alter the
|
||||
// virtual LED according to the state.
|
||||
|
||||
asdf_virtual_assign(VCAPS_LED, CLASSIC_CAPS_LED, V_NOFUNC, CLASSIC_CAPS_LED_INIT_VALUE);
|
||||
|
||||
// assign RESET output to the virtual RESET output, configure to produce a short pulse when activated
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_RESET, CLASSIC_RESET_OUTPUT, V_PULSE_SHORT, !CLASSIC_RESET_ACTIVE_VALUE);
|
||||
|
||||
// assign the CLRSCR output to the virtual CLRSCR output, configure to produce a long pulse when activated
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_CLR_SCR, CLASSIC_CLR_SCR_OUT, V_PULSE_LONG, !CLASSIC_CLR_SCR_ACTIVE_VALUE);
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,69 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic.h
|
||||
//
|
||||
// Ascii keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// To use this ascii for a new keymap, edit the keymaps definitions as
|
||||
// desired. The keymaps are organized from row 0, counting upward, and each row
|
||||
// includes the columns from 0-NUM_COLS.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_CLASSIC_H)
|
||||
#define ASDF_KEYMAP_DEFS_CLASSIC_H
|
||||
|
||||
#include "asdf_hook.h"
|
||||
|
||||
// Edit the number of rows and columns used in this map. If the number is less
|
||||
// than the maxium, the unused elements will be initialized to 0.
|
||||
|
||||
#define CLASSIC_NUM_ROWS 9 // DIP switches are row 8 (zero based)
|
||||
#define CLASSIC_NUM_COLS 8
|
||||
|
||||
#define CLASSIC_ACTION_BREAK ACTION_NOTHING
|
||||
|
||||
#define CLASSIC_VIRTUAL_RESET VOUT1
|
||||
#define CLASSIC_ACTION_RESET ACTION_VOUT1
|
||||
#define CLASSIC_RESET_OUTPUT PHYSICAL_OUT3_OPEN_HI
|
||||
#define CLASSIC_RESET_ACTIVE_VALUE 0
|
||||
|
||||
#define CLASSIC_VIRTUAL_CLR_SCR VOUT2
|
||||
#define CLASSIC_ACTION_CLEAR ACTION_VOUT2
|
||||
#define CLASSIC_CLR_SCR_OUT PHYSICAL_OUT1_OPEN_LO
|
||||
#define CLASSIC_CLR_SCR_ACTIVE_VALUE 1
|
||||
|
||||
#define CLASSIC_VIRTUAL_POWER_LED VLED1
|
||||
#define CLASSIC_POWER_LED PHYSICAL_LED1
|
||||
#define CLASSIC_POWER_LED_INIT_VALUE 1
|
||||
|
||||
#define CLASSIC_CAPS_LED PHYSICAL_LED3
|
||||
#define CLASSIC_CAPS_LED_INIT_VALUE 0
|
||||
|
||||
#define CLASSIC_ID_MESSAGE_HOOK ASDF_HOOK_USER_10
|
||||
#define APPLESOFT_KEYBOARD_TEST_HOOK ASDF_HOOK_USER_9
|
||||
|
||||
#define ASDF_CLASSIC_PRINT_SPEED 40
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_ASCII_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,156 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic.c
|
||||
//
|
||||
// defines the keymap matrices used by the "classic" ADM 3A style keymap variants
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "asdf_arch.h"
|
||||
#include "asdf.h"
|
||||
#include "asdf_ascii.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_keymap_classic.h"
|
||||
#include "asdf_keymap_classic_add_map.h"
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
|
||||
// Key Matrix for combination of ASCII controller and Classic ASCII matrix
|
||||
//
|
||||
// Col-> 0 1 2 3 4 5 6 7
|
||||
// Row 0 POWER R-Shift L-Shift (no key) ESC TAB CTRL \(backslash)
|
||||
// Row 1 Rubout P ; / SPACEBAR Z A Q
|
||||
// Row 2 Break ,(comma) M N B V C X
|
||||
// Row 3 Spare K J H G F D A
|
||||
// Row 4 Rt arrow I U Y T R E W
|
||||
// Row 5 LT arrow Repeat CapsLock Return LineFeed O(alpha) L .(period)
|
||||
// Row 6 ~(tilde) ] [ -(dash) :(colon) 0(numeral) 9 8
|
||||
// Row 7 @(at) 7 6 5 4 3 2 1
|
||||
//
|
||||
// Row 15 DIP switches 0-7
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1) The keys above correspond to the silk screen on the PCB. For the OSI and
|
||||
// Apple layouts, the keys may not all match the silk screen. When creating a
|
||||
// layout different from the silk screen, look up the row and column for the
|
||||
// silk screen label at the desired position, and then place the desired
|
||||
// function in the keymap definition at the desired row and column. For
|
||||
// example, the Apple 2 keymap places the "RESET" key at the "[" silk-screen
|
||||
// position, Row 6, Col 2. The keymap places ACTION_RESET at Row 6, Col 2 in
|
||||
// the "ASDF_APPLE2_CTRL_MAP" to map the RESET function to the CTRL-RESET key
|
||||
// combination.
|
||||
//
|
||||
// 2) To ensure consistent DIP switch operation within the keymap, a
|
||||
// ASDF_ASCII_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
|
||||
// definitions in positions 0-3 ensures consistent map selection among all
|
||||
// keymaps.
|
||||
|
||||
#define ASDF_CLASSIC_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
typedef asdf_keycode_t classic_keycode_matrix_t[CLASSIC_NUM_ROWS][CLASSIC_NUM_COLS];
|
||||
|
||||
|
||||
|
||||
const FLASH classic_keycode_matrix_t classic_plain_matrix = {
|
||||
[0] = { ACTION_NOTHING, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, ASCII_ESC, ASCII_TAB,
|
||||
ACTION_CTRL, ASCII_BACKSLASH },
|
||||
[1] = { ASCII_DEL, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' },
|
||||
[2] = { CLASSIC_ACTION_BREAK, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' },
|
||||
[3] = { ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' },
|
||||
[4] = { ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' },
|
||||
[5] = { ACTION_NOTHING, ACTION_REPEAT, ACTION_CAPS, ASCII_CR, ASCII_LF, 'o', 'l', ASCII_PERIOD },
|
||||
[6] = { ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', ASCII_ZERO, '9',
|
||||
'8' },
|
||||
[7] = { ASCII_AT, '7', '6', '5', '4', '3', '2', '1' },
|
||||
ASDF_CLASSIC_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH classic_keycode_matrix_t classic_shift_matrix = {
|
||||
[0] = { ACTION_NOTHING, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, ASCII_ESC, ASCII_TAB,
|
||||
ACTION_CTRL, ASCII_VERT_BAR },
|
||||
[1] = { ASCII_DEL, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' },
|
||||
[2] = { CLASSIC_ACTION_CLEAR, '<', 'M', 'N', 'B', 'V', 'C', 'X' },
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' },
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' },
|
||||
[5] = { ACTION_NOTHING, ACTION_REPEAT, ACTION_CAPS, ASCII_CR, ASCII_LF, 'O', 'L', '>' },
|
||||
[6] = { ASCII_TILDE, ASCII_RT_CURLY_BRACE, ASCII_LT_CURLY_BRACE, '=', '*', ASCII_ZERO,
|
||||
ASCII_RT_PAREN, ASCII_LT_PAREN },
|
||||
[7] = { ASCII_GRAVE_ACCENT, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' },
|
||||
ASDF_CLASSIC_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH classic_keycode_matrix_t classic_caps_matrix = {
|
||||
[0] = { ACTION_NOTHING, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, ASCII_ESC, ASCII_TAB,
|
||||
ACTION_CTRL, ASCII_BACKSLASH },
|
||||
[1] = { ASCII_DEL, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' },
|
||||
[2] = { CLASSIC_ACTION_BREAK, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' },
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' },
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' },
|
||||
[5] = { ACTION_NOTHING, ACTION_REPEAT, ACTION_CAPS, ASCII_CR, ASCII_LF, 'O', 'L', ASCII_PERIOD },
|
||||
[6] = { ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', ASCII_ZERO, '9',
|
||||
'8' },
|
||||
[7] = { ASCII_AT, '7', '6', '5', '4', '3', '2', '1' },
|
||||
ASDF_CLASSIC_DIP_SWITCHES
|
||||
};
|
||||
|
||||
const FLASH classic_keycode_matrix_t classic_ctrl_matrix = {
|
||||
[0] = { ACTION_NOTHING, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, ASCII_ESC, ASCII_TAB,
|
||||
ACTION_CTRL, 0x1c },
|
||||
[1] = { ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, ASCII_SPACE, ASCII_CTRL_Z,
|
||||
ASCII_CTRL_A, ASCII_CTRL_Q },
|
||||
[2] = { CLASSIC_ACTION_RESET, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, ASCII_CTRL_B, ASCII_CTRL_V,
|
||||
ASCII_CTRL_C, ASCII_CTRL_X },
|
||||
[3] = { ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, ASCII_CTRL_G, ASCII_CTRL_F,
|
||||
ASCII_CTRL_D, ASCII_CTRL_S },
|
||||
[4] = { ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, ASCII_CTRL_T, ASCII_CTRL_R,
|
||||
ASCII_CTRL_E, ASCII_CTRL_W },
|
||||
[5] = { ACTION_NOTHING, ACTION_REPEAT, ACTION_CAPS, ASCII_CR, ASCII_LF, ASCII_CTRL_O,
|
||||
ASCII_CTRL_L, ACTION_NOTHING },
|
||||
[6] = { ACTION_NOTHING, 0x1d, ASCII_ESC, ACTION_NOTHING, ACTION_NOTHING, ACTION_FN_10,
|
||||
ACTION_FN_9, ACTION_FN_8 },
|
||||
[7] = { ASCII_NULL, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, ACTION_FN_4, ACTION_FN_3, ACTION_FN_2,
|
||||
ACTION_FN_1 },
|
||||
ASDF_CLASSIC_DIP_SWITCHES
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const classic_keycode_matrix_t *classic_maps[] = {
|
||||
[CLASSIC_CAPS_MAP] = &classic_caps_matrix,
|
||||
[CLASSIC_PLAIN_MAP] = &classic_plain_matrix,
|
||||
[CLASSIC_SHIFT_MAP] = &classic_shift_matrix,
|
||||
[CLASSIC_CTRL_MAP] = &classic_ctrl_matrix,
|
||||
};
|
||||
|
||||
void classic_add_map(const classic_map_index_t map_index,
|
||||
modifier_index_t modifier_index)
|
||||
{
|
||||
|
||||
asdf_keycode_t (*matrix)[CLASSIC_NUM_COLS] =
|
||||
(asdf_keycode_t (*)[CLASSIC_NUM_COLS]) classic_maps[map_index];
|
||||
|
||||
asdf_keymaps_add_map(&matrix[0][0], modifier_index, (uint8_t) CLASSIC_NUM_ROWS,
|
||||
(uint8_t) CLASSIC_NUM_COLS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,50 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic_add_map.h
|
||||
//
|
||||
// defines keymap matrices and add_map() function for classic layouts
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// To use this ascii for a new keymap, edit the keymaps definitions as
|
||||
// desired. The keymaps are organized from row 0, counting upward, and each row
|
||||
// includes the columns from 0-NUM_COLS.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_KEYMAP_CLASSIC_ADD_MAP_H)
|
||||
#define ASDF_KEYMAP_CLASSIC_ADD_MAP_H
|
||||
|
||||
#include "asdf_modifiers.h"
|
||||
|
||||
typedef enum {
|
||||
CLASSIC_PLAIN_MAP,
|
||||
CLASSIC_CAPS_MAP,
|
||||
CLASSIC_SHIFT_MAP,
|
||||
CLASSIC_CTRL_MAP,
|
||||
} classic_map_index_t;
|
||||
|
||||
|
||||
// function prototypes
|
||||
void classic_add_map(const classic_map_index_t map_index, modifier_index_t modifier_index);
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_CLASSIC_ADD_MAP_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,87 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_classic.c
|
||||
//
|
||||
// Implements the "classic" ADM 3A style keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "asdf.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_print.h"
|
||||
#include "asdf_virtual.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_keymap_classic.h"
|
||||
#include "asdf_keymap_classic_add_map.h"
|
||||
#include "asdf_keymap_apple2_add_map.h"
|
||||
|
||||
|
||||
|
||||
void classic_caps_id_message(void) {
|
||||
asdf_print("[Keymap: classic]\n");
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
void setup_classic_caps_keymap(void)
|
||||
{
|
||||
asdf_set_print_delay(ASDF_CLASSIC_PRINT_SPEED);
|
||||
|
||||
// for the ALL CAPS keymap, the "plain" mode is the same as "all caps" mode:
|
||||
classic_add_map(CLASSIC_CAPS_MAP, MOD_PLAIN_MAP);
|
||||
classic_add_map(CLASSIC_CAPS_MAP, MOD_CAPS_MAP);
|
||||
classic_add_map(CLASSIC_SHIFT_MAP, MOD_SHIFT_MAP);
|
||||
classic_add_map(CLASSIC_CTRL_MAP, MOD_CTRL_MAP);
|
||||
|
||||
asdf_hook_assign(CLASSIC_ID_MESSAGE_HOOK, classic_caps_id_message);
|
||||
asdf_hook_assign(APPLESOFT_KEYBOARD_TEST_HOOK, applesoft_keyboard_test);
|
||||
|
||||
// Assign power LED to virtual power LED, and initialize to ON
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_POWER_LED, CLASSIC_POWER_LED, V_NOFUNC, CLASSIC_POWER_LED_INIT_VALUE);
|
||||
|
||||
// Because the virtual power LED never changes, also assign the CAPSLOCK
|
||||
// physical LED to the virtual Power LED, and intialize to OFF (or can change
|
||||
// to ON depending on preference)
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_POWER_LED, CLASSIC_CAPS_LED, V_NOFUNC, CLASSIC_CAPS_LED_INIT_VALUE);
|
||||
|
||||
// assign RESET output to the virtual RESET output, configure to produce a short pulse when activated
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_RESET, CLASSIC_RESET_OUTPUT, V_PULSE_SHORT, !CLASSIC_RESET_ACTIVE_VALUE);
|
||||
|
||||
// assign the CLRSCR output to the virtual CLRSCR output, configure to produce a long pulse when activated
|
||||
asdf_virtual_assign(CLASSIC_VIRTUAL_CLR_SCR, CLASSIC_CLR_SCR_OUT, V_PULSE_LONG, !CLASSIC_CLR_SCR_ACTIVE_VALUE);
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,304 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymaps_apple2.h
|
||||
//
|
||||
// Apple 2 keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// This file supplies the Apple 2 ASCII keyboard keymap. Two variants are provided:
|
||||
//
|
||||
// 1) An Upper/Lowercase variant. This variant moves the @ and ^ symbols from
|
||||
// the P and N keys to the REPEAT key, since the P and N keys need to reserve
|
||||
// the shifted value for the uppercase characters. Also, the "Power" key
|
||||
// doubles as a caps-lock key.
|
||||
//
|
||||
// 2) A CAPS only keyboard, following the standard Apple II conventions and
|
||||
// layout, with ^ above the N key and @ above the P key, and a functioning
|
||||
// REPEAT key.
|
||||
//
|
||||
// For both variants, CTRL+RESET is required for a system reset.
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_APPLE2_H)
|
||||
#define ASDF_KEYMAP_DEFS_APPLE2_H
|
||||
|
||||
// include DIP switch definitions
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
|
||||
// Edit the number of rows and columns used in this map. If the number is less
|
||||
// than the maxium, the unused elements will be initialized to 0.
|
||||
|
||||
#define ASDF_APPLE2_NUM_ROWS 9 // DIP switches are row 8 (zero-based)
|
||||
#define ASDF_APPLE2_NUM_COLS 8
|
||||
|
||||
#define APPLE_ACTION_RESET ACTION_VOUT1
|
||||
#define APPLE_VIRTUAL_RESET VOUT1
|
||||
#define APPLE_RESET_OUTPUT PHYSICAL_OUT3_OPEN_HI
|
||||
#define APPLE_RESET_ACTIVE_VALUE 0
|
||||
|
||||
#define APPLE_ACTION_CLEAR ACTION_VOUT2
|
||||
#define APPLE_VIRTUAL_CLR_SCR VOUT2
|
||||
#define APPLE_CLR_SCR_OUTPUT PHYSICAL_OUT1_OPEN_LO
|
||||
#define APPLE_CLR_SCR_ACTIVE_VALUE 1
|
||||
|
||||
#define APPLE_VIRTUAL_POWER_LED VLED1
|
||||
#define APPLE_POWER_LED PHYSICAL_LED1
|
||||
#define APPLE_POWER_LED_INIT_VALUE 1
|
||||
|
||||
#define APPLE_VIRTUAL_DISABLED_LED VLED2
|
||||
#define APPLE_DISABLED_LED PHYSICAL_LED3
|
||||
#define APPLE_DISABLED_INIT_VALUE 0
|
||||
|
||||
#define ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH 4
|
||||
|
||||
|
||||
// The PLAIN map uses the "power" button as a caps-lock, so map the CAPS LED to
|
||||
// the power button LED.
|
||||
#define ASDF_APPLE2_PLAIN_KEYMAP_INITIALIZER \
|
||||
{ \
|
||||
{ .virtual_device = VCAPS_LED, .physical_device = APPLE_POWER_LED, .initial_value = 0 }, \
|
||||
{ .virtual_device = APPLE_VIRTUAL_DISABLED_LED, \
|
||||
.physical_device = APPLE_DISABLED_LED, \
|
||||
.initial_value = 0 }, \
|
||||
{ .virtual_device = APPLE_VIRTUAL_RESET, \
|
||||
.physical_device = APPLE_RESET_OUTPUT, \
|
||||
.function = V_PULSE_SHORT, \
|
||||
.initial_value = !APPLE_RESET_ACTIVE_VALUE }, \
|
||||
{ \
|
||||
.virtual_device = APPLE_VIRTUAL_CLR_SCR, .physical_device = APPLE_CLR_SCR_OUTPUT, \
|
||||
.function = V_PULSE_LONG, .initial_value = !APPLE_CLR_SCR_ACTIVE_VALUE \
|
||||
} \
|
||||
}
|
||||
|
||||
// The ALL CAPS map is the classic Apple II/II+ map. There is no CAPS LED, since
|
||||
// CAPS doesn't matter in the ALL CAPS keymap.
|
||||
#define ASDF_APPLE2_CAPS_KEYMAP_INITIALIZER \
|
||||
{ \
|
||||
{ .virtual_device = APPLE_VIRTUAL_POWER_LED, \
|
||||
.physical_device = APPLE_POWER_LED, \
|
||||
.initial_value = APPLE_POWER_LED_INIT_VALUE }, \
|
||||
{ .virtual_device = APPLE_VIRTUAL_DISABLED_LED, \
|
||||
.physical_device = APPLE_DISABLED_LED, \
|
||||
.initial_value = 0 }, \
|
||||
{ .virtual_device = APPLE_VIRTUAL_RESET, \
|
||||
.physical_device = APPLE_RESET_OUTPUT, \
|
||||
.function = V_PULSE_SHORT, \
|
||||
.initial_value = !APPLE_RESET_ACTIVE_VALUE }, \
|
||||
{ \
|
||||
.virtual_device = APPLE_VIRTUAL_CLR_SCR, .physical_device = APPLE_CLR_SCR_OUTPUT, \
|
||||
.function = V_PULSE_LONG, .initial_value = !APPLE_CLR_SCR_ACTIVE_VALUE \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_APPLE2_KEYMAP_INITIALIZER \
|
||||
ASDF_APPLE2_PLAIN_KEYMAP_INITIALIZER, ASDF_APPLE2_CAPS_KEYMAP_INITIALIZER
|
||||
|
||||
// Structure to initialize hooks. No hook functions are needed for APPLE2 keyboard.
|
||||
#define ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH 0
|
||||
#define ASDF_APPLE2_PLAIN_KEYMAP_HOOK_INITIALIZER \
|
||||
{ \
|
||||
}
|
||||
#define ASDF_APPLE2_CAPS_KEYMAP_HOOK_INITIALIZER \
|
||||
{ \
|
||||
}
|
||||
#define ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER \
|
||||
ASDF_APPLE2_PLAIN_KEYMAP_HOOK_INITIALIZER, ASDF_APPLE2_CAPS_KEYMAP_HOOK_INITIALIZER
|
||||
|
||||
|
||||
// Key Matrix for combination of ASCII controller and Classic ASCII matrix
|
||||
//
|
||||
// Col-> 0 1 2 3 4 5 6 7
|
||||
// Row 0 POWER R-Shift L-Shift (no key) ESC TAB CTRL \(backslash)
|
||||
// Row 1 Rubout P ; / SPACEBAR Z A Q
|
||||
// Row 2 Break ,(comma) M N B V C X
|
||||
// Row 3 Spare K J H G F D A
|
||||
// Row 4 Rt arrow I U Y T R E W
|
||||
// Row 5 LT arrow Repeat CapsLock Return LineFeed O(alpha) L .(period)
|
||||
// Row 6 ~(tilde) ] [ -(dash) :(colon) 0(numeral) 9 8
|
||||
// Row 7 @(at) 7 6 5 4 3 2 1
|
||||
//
|
||||
// Row 9 DIP switches 0-7
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1) The keys above correspond to the silk screen on the PCB. For the OSI and
|
||||
// Apple layouts, the keys may not all match the silk screen. When creating a
|
||||
// layout different from the silk screen, look up the row and column for the
|
||||
// silk screen label at the desired position, and then place the desired
|
||||
// function in the keymap definition at the desired row and column. For
|
||||
// example, the Apple 2 keymap places the "RESET" key at the "[" silk-screen
|
||||
// position, Row 6, Col 2. The keymap places ACTION_RESET at Row 6, Col 2 in
|
||||
// the "ASDF_APPLE2_CTRL_MAP" to map the RESET function to the CTRL-RESET key
|
||||
// combination.
|
||||
//
|
||||
// 2) To ensure consistent DIP switch operation within the keymap, a
|
||||
// ASDF_ASCII_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
|
||||
// definitions in positions 0-3 ensures consistent map selection among all
|
||||
// keymaps.
|
||||
|
||||
#define ASDF_APPLE2_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
#define APPLE_LEFT_ARROW ASCII_CTRL_H
|
||||
#define APPLE_RIGHT_ARROW ASCII_CTRL_U
|
||||
|
||||
// clang-format off
|
||||
#define ASDF_APPLE2_PLAIN_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW }, \
|
||||
[1] = { ASCII_DEL, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' }, \
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
|
||||
[3] = { ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' }, \
|
||||
[4] = { ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' }, \
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, '^', 'o', 'l', ASCII_PERIOD }, \
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, '-', ':', ASCII_ZERO, '9', '8' }, \
|
||||
[7] = { APPLE_LEFT_ARROW, '7', '6', '5', '4', '3', '2', '1' }, \
|
||||
ASDF_APPLE2_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_APPLE2_SHIFT_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW }, \
|
||||
[1] = { ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
[2] = { ACTION_NOTHING, '<', 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ASCII_AT, 'O', 'L', '>' }, \
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_CLEAR, '=', \
|
||||
'*', ASCII_ZERO, ASCII_RT_PAREN, ASCII_LT_PAREN }, \
|
||||
[7] = { APPLE_LEFT_ARROW, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
|
||||
ASDF_APPLE2_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_APPLE2_CAPS_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW }, \
|
||||
[1] = { ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ACTION_REPEAT, 'O', 'L', ASCII_PERIOD }, \
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, '-', ':', ASCII_ZERO, '9', '8' }, \
|
||||
[7] = { APPLE_LEFT_ARROW, '7', '6', '5', '4', '3', '2', '1' }, \
|
||||
ASDF_APPLE2_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_APPLE2_SHIFT_CAPS_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW }, \
|
||||
[1] = { ACTION_NOTHING, ASCII_AT, '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
[2] = { ACTION_NOTHING, '<', 'M', '^', 'B', 'V', 'C', 'X' }, \
|
||||
[3] = { ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
[4] = { ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, ACTION_REPEAT, 'O', 'L', '>' }, \
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_CLEAR, '=', \
|
||||
'*', ASCII_ZERO, ASCII_RT_PAREN, ASCII_LT_PAREN }, \
|
||||
[7] = { APPLE_LEFT_ARROW, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
|
||||
ASDF_APPLE2_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_APPLE2_CTRL_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CAPS, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, APPLE_RIGHT_ARROW }, \
|
||||
[1] = { ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, \
|
||||
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q }, \
|
||||
[2] = { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
|
||||
ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
|
||||
[3] = { ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, \
|
||||
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S }, \
|
||||
[4] = { ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, \
|
||||
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W }, \
|
||||
[5] = { ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ASCII_CR, \
|
||||
ACTION_REPEAT, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
|
||||
[6] = { ACTION_NOTHING, ACTION_NOTHING, APPLE_ACTION_RESET, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_FN_10, ACTION_FN_9, ACTION_FN_8 }, \
|
||||
[7] = { APPLE_LEFT_ARROW, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, \
|
||||
ACTION_FN_4, ACTION_FN_3, ACTION_FN_2, ACTION_FN_1 }, \
|
||||
ASDF_APPLE2_DIP_SWITCHES \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#define ASDF_APPLE2_MAP_DECLARATIONS \
|
||||
static const FLASH keycode_matrix_t apple2_plain_matrix = ASDF_APPLE2_PLAIN_MAP; \
|
||||
static const FLASH keycode_matrix_t apple2_shift_matrix = ASDF_APPLE2_SHIFT_MAP; \
|
||||
static const FLASH keycode_matrix_t apple2_caps_matrix = ASDF_APPLE2_CAPS_MAP; \
|
||||
static const FLASH keycode_matrix_t apple2_caps_shift_matrix = ASDF_APPLE2_SHIFT_CAPS_MAP; \
|
||||
static const FLASH keycode_matrix_t apple2_ctrl_matrix = ASDF_APPLE2_CTRL_MAP;
|
||||
|
||||
|
||||
// Here, you can specify which maps are associated with which modifier keys.
|
||||
// There can be multiple definitions. For example, as shown here, an ALL CAPS
|
||||
// keymap can be made by assigning the caps map to the "no modifier" position.
|
||||
// Or, more additional keymaps can be defined above, and keymap sets can be
|
||||
// defined below that pick and choose between them. The modifiers are assigned as follows:
|
||||
//
|
||||
// [0]: plain (no modifiers)
|
||||
// [1]: shift (shift key or shift lock active)
|
||||
// [2]: caps (caps lock active)
|
||||
// [3]: ctrl: (control key active)
|
||||
|
||||
#define ASDF_APPLE2_PLAIN_MAP_DEFS \
|
||||
{ \
|
||||
[MOD_PLAIN_MAP] = &apple2_plain_matrix, [MOD_SHIFT_MAP] = &apple2_shift_matrix, \
|
||||
[MOD_CAPS_MAP] = &apple2_caps_matrix, [MOD_CTRL_MAP] = &apple2_ctrl_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_APPLE2_CAPS_MAP_DEFS \
|
||||
{ \
|
||||
[MOD_PLAIN_MAP] = &apple2_caps_matrix, [MOD_SHIFT_MAP] = &apple2_caps_shift_matrix, \
|
||||
[MOD_CAPS_MAP] = &apple2_caps_matrix, [MOD_CTRL_MAP] = &apple2_ctrl_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_APPLE2_ALL_MAPS ASDF_APPLE2_PLAIN_MAP_DEFS, ASDF_APPLE2_CAPS_MAP_DEFS
|
||||
|
||||
#define ASDF_APPLE2_ALL_MAPS_COUNT 2
|
||||
|
||||
#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_APPLE2_NUM_ROWS)
|
||||
#undef ASDF_NUM_ROWS
|
||||
#define ASDF_NUM_ROWS ASDF_APPLE2_NUM_ROWS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_APPLE2_NUM_COLS)
|
||||
#undef ASDF_NUM_COLS
|
||||
#define ASDF_NUM_COLS ASDF_APPLE2_NUM_COLS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_APPLE2_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,46 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_defs_dipswitch.h
|
||||
//
|
||||
// Contains defitions for DIP switch settings shared by all keymaps.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined (DEPS_DIPSWITCH_H)
|
||||
#define DEPS_DIPSWITCH_H
|
||||
|
||||
#define ASDF_KEYMAP_DIP_SWITCHES \
|
||||
[ASDF_ARCH_DIPSWITCH_ROW] = { \
|
||||
[0] = ACTION_MAPSEL_0, \
|
||||
[1] = ACTION_MAPSEL_1, \
|
||||
[2] = ACTION_MAPSEL_2, \
|
||||
[3] = ACTION_MAPSEL_3, \
|
||||
[6] = ACTION_STROBE_POLARITY_SELECT, \
|
||||
[7] = ACTION_AUTOREPEAT_SELECT, \
|
||||
}
|
||||
|
||||
//
|
||||
// Device and peripheral definitions, comments should include use of devices.
|
||||
// Please
|
||||
//
|
||||
|
||||
#endif /* !defined (DEPS_DIPSWITCH_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,311 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymaps_sol.h
|
||||
//
|
||||
// Ascii keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// To use this ascii for a new keymap, edit the keymaps definitions as
|
||||
// desired. The keymaps are organized from row 0, counting upward, and each row
|
||||
// includes the columns from 0-NUM_COLS.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_SOL20_H)
|
||||
#define ASDF_KEYMAP_DEFS_SOL20_H
|
||||
|
||||
// include DIP switch definitions
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
|
||||
// Edit the number of rows and columns used in this map. If the number is less
|
||||
// than the maxium, the unused elements will be initialized to 0.
|
||||
|
||||
#define ASDF_SOL_NUM_ROWS 13 // DIP switches are row 9
|
||||
#define ASDF_SOL_NUM_COLS 8
|
||||
|
||||
|
||||
// Key Matrix for combination of ASCII controller (ATMega328P version) and Classic ASCII matrix
|
||||
//
|
||||
// Col-> 0 1 2 3 4 5 6 7
|
||||
// Row 0 Lt Ctrl ShiftLock A S D F G(alpha) H
|
||||
// Row 1 J K L ;(semi) :(colon) DEL Repeat Rt Ctrl
|
||||
// Row 2 UpperCase Lt Shift Z X C V B(alpha) N
|
||||
// Row 3 M ,(comma) .(period) /(slash) Rt Shift ModeSelect
|
||||
// Row 4 ESC 1 2 3 4 5 6(six) 7
|
||||
// Row 5 8(eight) 9 0(zero) -(Dash) ^(Caret) [ \ ]
|
||||
// Row 6 BREAK TAB Q W E R T Y
|
||||
// Row 7 U I O(alpha) P @(at) Return LineFeed Load
|
||||
// Row 9 LOCAL UpArrow LtArrow Spacebar RtArrow DnArrow Home Clear
|
||||
// Row 10 NP-Minus NP-7 NP-Times NP-8 NP-Divide NP-9 (none) (none)
|
||||
// Row 11 NP-4 NP-1 NP-5 NP-2 NP-6 NP-3 (none) (none)
|
||||
// Row 12 NP-0 NP-period NP-Plus
|
||||
//
|
||||
// Row 8 DIP switches 0-7
|
||||
//
|
||||
// Physical Resource mapping:
|
||||
// LED1: UPPER CASE
|
||||
// LED2: LOCAL
|
||||
// LED3: SHIFT LOCK
|
||||
// OUT1: RESET
|
||||
// OUT2: BREAK
|
||||
// OUT3: LOCAL
|
||||
|
||||
// Notes:
|
||||
//
|
||||
// 1) To ensure consistent DIP switch operation within the keymap, a
|
||||
// ASDF_SOL_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
|
||||
// definitions in positions 0-3 ensures consistent map selection among all
|
||||
// keymaps.
|
||||
|
||||
|
||||
#define SOL_KBD_VRESET VOUT1
|
||||
#define SOL_KBD_VBREAK VOUT2
|
||||
#define SOL_KBD_VLOCAL VOUT3
|
||||
#define SOL_KBD_LED_ON 1
|
||||
#define SOL_KBD_LED_OFF 0
|
||||
|
||||
// The SOL manual (sec. 7.7.8) indicates shiftlock locks SHIFT on, and SHIFT
|
||||
// returns to unshifted. For Toggle behavior, change to ACTION_SHIFTLOCK_TOGGLE.
|
||||
#define SOL_KBD_SHIFTLOCK_ACTION ACTION_SHIFTLOCK_ON
|
||||
|
||||
// The weird C preprocessor expansion behavior requires one dereference for each
|
||||
// expansion.
|
||||
#define SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE) ACTION_ ## SOL_VDEVICE
|
||||
#define SOL_KBD_VIRTUAL_SUB(SOL_VDEVICE) SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE)
|
||||
#define SOL_KBD_LOCAL_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VLOCAL)
|
||||
#define SOL_KBD_RESET_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VRESET)
|
||||
#define SOL_KBD_BREAK_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VBREAK)
|
||||
|
||||
#define SOL_ASCII_LOAD 0x8C
|
||||
#define SOL_ASCII_MODE_SELECT 0x80
|
||||
#define SOL_ASCII_UP_ARROW 0x97
|
||||
#define SOL_ASCII_LT_ARROW 0x81
|
||||
#define SOL_ASCII_RT_ARROW 0x93
|
||||
#define SOL_ASCII_DN_ARROW 0x9a
|
||||
#define SOL_ASCII_HOME 0x8e
|
||||
#define SOL_ASCII_CLEAR 0x8b
|
||||
|
||||
#define SOL_KBD_TTL_HIGH 1
|
||||
#define SOL_KBD_TTL_LOW 0
|
||||
|
||||
#define SOL_KBD_LED_UPPERCASE PHYSICAL_LED1
|
||||
#define SOL_KBD_LED_LOCAL PHYSICAL_LED2
|
||||
#define SOL_KBD_LED_SHIFTLOCK PHYSICAL_LED3
|
||||
#define SOL_KBD_TTLOUT_RESET PHYSICAL_OUT3_OPEN_HI // Emulate open collector output.
|
||||
#define SOL_KBD_TTLOUT_BREAK PHYSICAL_OUT2
|
||||
#define SOL_KBD_TTLOUT_LOCAL PHYSICAL_OUT1
|
||||
|
||||
#define ASDF_SOL_KEYMAP_INITIALIZER_LENGTH 6
|
||||
|
||||
// Notice that TTLOUT_LOCAL (OUT3) and LED_LOCAL (PHYSICAL_LED2) are both bound
|
||||
// to the VLOCAL_OUT virtual device.
|
||||
#define ASDF_SOL_KEYMAP_INITIALIZER \
|
||||
{ \
|
||||
{ .virtual_device = VCAPS_LED, \
|
||||
.physical_device = SOL_KBD_LED_UPPERCASE, \
|
||||
.initial_value = SOL_KBD_LED_OFF }, \
|
||||
{ .virtual_device = VSHIFT_LED, \
|
||||
.physical_device = SOL_KBD_LED_SHIFTLOCK, \
|
||||
.initial_value = SOL_KBD_LED_OFF }, \
|
||||
{ .virtual_device = SOL_KBD_VLOCAL, \
|
||||
.physical_device = SOL_KBD_TTLOUT_LOCAL, \
|
||||
.function = V_TOGGLE, \
|
||||
.initial_value = SOL_KBD_TTL_HIGH }, \
|
||||
{ .virtual_device = SOL_KBD_VLOCAL, \
|
||||
.physical_device = SOL_KBD_LED_LOCAL, \
|
||||
.function = V_TOGGLE, \
|
||||
.initial_value = SOL_KBD_LED_OFF }, \
|
||||
{ .virtual_device = SOL_KBD_VRESET, \
|
||||
.physical_device = SOL_KBD_TTLOUT_RESET, \
|
||||
.function = V_PULSE_SHORT, \
|
||||
.initial_value = SOL_KBD_TTL_HIGH }, \
|
||||
{ .virtual_device = SOL_KBD_VBREAK, \
|
||||
.physical_device = SOL_KBD_TTLOUT_BREAK, \
|
||||
.function = V_PULSE_LONG, \
|
||||
.initial_value = SOL_KBD_TTL_HIGH }, \
|
||||
}
|
||||
|
||||
// function hooks for the SOL keyboard:
|
||||
// - At Setup, activate CAPSLOCK to emulate original keyboard.
|
||||
// - At Setup, configure negative strobe
|
||||
#define ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH 2
|
||||
#define ASDF_SOL_KEYMAP_HOOK_INITIALIZER \
|
||||
{ \
|
||||
{ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = asdf_modifier_capslock_activate, \
|
||||
}, \
|
||||
{ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = asdf_arch_set_neg_strobe, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ASDF_SOL_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
// clang-format off
|
||||
#define ASDF_SOL_PLAIN_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'a', 's', 'd', 'f', 'g', 'h' }, \
|
||||
[1] = { 'j', 'k', 'l', ';', ':', ASCII_DEL, ACTION_REPEAT, ACTION_CTRL }, \
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'z', 'x', 'c', 'v', 'b', 'n' }, \
|
||||
[3] = { 'm', ASCII_COMMA, ASCII_PERIOD, '/', \
|
||||
ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[4] = { ASCII_ESC, '1', '2', '3', '4', '5', '6', '7' }, /**/ \
|
||||
[5] = { '8', '9', ASCII_ZERO, '-', '^', \
|
||||
ASCII_LT_SQUARE_BRACE, ASCII_BACKSLASH, ASCII_RT_SQUARE_BRACE }, \
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'q', 'w', 'e', 'r', 't', 'y' }, /**/ \
|
||||
[7] = { 'u', 'i', 'o', 'p', ASCII_AT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD }, \
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, \
|
||||
ASCII_SPACE, SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, \
|
||||
SOL_ASCII_HOME, SOL_ASCII_CLEAR }, \
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
ASDF_SOL_DIP_SWITCHES, \
|
||||
}
|
||||
|
||||
#define ASDF_SOL_CAPS_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'A', 'S', 'D', 'F', 'G', 'H' }, \
|
||||
[1] = { 'J', 'K', 'L', ';', ':', ASCII_DEL, ACTION_REPEAT, ACTION_CTRL }, \
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'Z', 'X', 'C', 'V', 'B', 'N' }, \
|
||||
[3] = { 'M', ASCII_COMMA, ASCII_PERIOD, '/', \
|
||||
ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[4] = { ASCII_ESC, '1', '2', '3', '4', '5', '6', '7' }, /**/ \
|
||||
[5] = { '8', '9', ASCII_ZERO, '-', '^', \
|
||||
ASCII_LT_SQUARE_BRACE, ASCII_BACKSLASH, ASCII_RT_SQUARE_BRACE }, \
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y' }, /**/ \
|
||||
[7] = { 'U', 'I', 'O', 'P', ASCII_AT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD }, \
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, \
|
||||
ASCII_SPACE, SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, \
|
||||
SOL_ASCII_HOME, SOL_ASCII_CLEAR }, \
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
ASDF_SOL_DIP_SWITCHES, \
|
||||
}
|
||||
|
||||
#define ASDF_SOL_SHIFT_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'A', 'S', 'D', 'F', 'G', 'H' }, \
|
||||
[1] = { 'J', 'K', 'L', ';', ':', ASCII_UNDERSCORE, ACTION_REPEAT, ACTION_CTRL }, \
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'Z', 'X', 'C', 'V', 'B', 'N' }, \
|
||||
[3] = { 'M', '<', '>', '?', \
|
||||
ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[4] = { ASCII_ESC, '!', ASCII_DOUBLE_QUOTE, '#', '$', '%', '&', ASCII_SINGLE_QUOTE }, \
|
||||
[5] = { ASCII_LT_PAREN, ASCII_RT_PAREN, ASCII_SPACE, '=', ASCII_TILDE, \
|
||||
ASCII_LT_SQUARE_BRACE, ASCII_BACKSLASH, ASCII_RT_SQUARE_BRACE }, \
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y' }, \
|
||||
[7] = { 'U', 'I', 'O', 'P', ASCII_GRAVE_ACCENT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD }, \
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, \
|
||||
ASCII_SPACE, SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, \
|
||||
SOL_ASCII_HOME, SOL_ASCII_CLEAR }, \
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
ASDF_SOL_DIP_SWITCHES, \
|
||||
}
|
||||
|
||||
#define ASDF_SOL_CTRL_MAP \
|
||||
{ \
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, ASCII_CTRL_A, ASCII_CTRL_S, \
|
||||
ASCII_CTRL_D, ASCII_CTRL_F, ASCII_CTRL_G, ASCII_CTRL_H }, \
|
||||
[1] = { ASCII_CTRL_J, ASCII_CTRL_K, ASCII_CTRL_L, ASCII_VT, \
|
||||
ASCII_LF, ASCII_DEL, SOL_KBD_RESET_ACTION, ACTION_CTRL }, \
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, ASCII_CTRL_Z, ASCII_CTRL_X, \
|
||||
ASCII_CTRL_C, ASCII_CTRL_V, ASCII_CTRL_B, ASCII_CTRL_N }, \
|
||||
[3] = { ASCII_CTRL_M, ASCII_FF, ASCII_SO, ASCII_SI, \
|
||||
ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[4] = { ASCII_ESC, ASCII_SOH, ASCII_STX, ASCII_ETX, \
|
||||
ASCII_EOT, ASCII_ENQ, ASCII_ACK, ASCII_BEL }, \
|
||||
[5] = { ASCII_BS, ASCII_TAB, ASCII_NULL, ASCII_CR, ASCII_RS, \
|
||||
ASCII_ESC, ASCII_FS, ASCII_GS }, \
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, ASCII_CTRL_Q, ASCII_CTRL_W, \
|
||||
ASCII_CTRL_E, ASCII_CTRL_R, ASCII_CTRL_T, ASCII_CTRL_Y }, \
|
||||
[7] = { ASCII_CTRL_U, ASCII_CTRL_I, ASCII_CTRL_O, ASCII_CTRL_P, \
|
||||
ASCII_NULL, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD }, \
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, \
|
||||
ASCII_SPACE, SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, \
|
||||
SOL_ASCII_HOME, SOL_ASCII_CLEAR }, \
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING }, \
|
||||
ASDF_SOL_DIP_SWITCHES, \
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
||||
#define ASDF_SOL_MAP_DECLARATIONS \
|
||||
static const FLASH keycode_matrix_t asdf_sol_plain_matrix = ASDF_SOL_PLAIN_MAP; \
|
||||
static const FLASH keycode_matrix_t asdf_sol_shift_matrix = ASDF_SOL_SHIFT_MAP; \
|
||||
static const FLASH keycode_matrix_t asdf_sol_caps_matrix = ASDF_SOL_CAPS_MAP; \
|
||||
static const FLASH keycode_matrix_t asdf_sol_ctrl_matrix = ASDF_SOL_CTRL_MAP;
|
||||
|
||||
|
||||
// Here, you can specify which maps are associated with which modifier keys.
|
||||
// There can be multiple definitions. For example, as shown here, an ALL CAPS
|
||||
// keymap can be made by assigning the caps map to the "no modifier" position.
|
||||
// Or, more additional keymaps can be defined above, and keymap sets can be
|
||||
// defined below that pick and choose between them. The modifiers are assigned as follows:
|
||||
//
|
||||
// [0]: plain (no modifiers)
|
||||
// [1]: shift (shift key or shift lock active)
|
||||
// [2]: caps (caps lock active)
|
||||
// [3]: ctrl: (control key active)
|
||||
|
||||
#define ASDF_SOL_MAP_DEFS \
|
||||
{ \
|
||||
[MOD_PLAIN_MAP] = &asdf_sol_plain_matrix, [MOD_SHIFT_MAP] = &asdf_sol_shift_matrix, \
|
||||
[MOD_CAPS_MAP] = &asdf_sol_caps_matrix, [MOD_CTRL_MAP] = &asdf_sol_ctrl_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_SOL_ALL_MAPS ASDF_SOL_MAP_DEFS
|
||||
|
||||
#define ASDF_SOL_ALL_MAPS_COUNT 1
|
||||
|
||||
#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_SOL_NUM_ROWS)
|
||||
#undef ASDF_NUM_ROWS
|
||||
#define ASDF_NUM_ROWS ASDF_SOL_NUM_ROWS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_SOL_NUM_COLS)
|
||||
#undef ASDF_NUM_COLS
|
||||
#define ASDF_NUM_COLS ASDF_SOL_NUM_COLS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_SOL_KEYMAP_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_SOL_KEYMAP_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_SOL20_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,275 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymaps.h
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// While there is nothing preventing a standard keyboard from having both a
|
||||
// "Shift Lock" key and a "Caps Lock" key, usually only one will be present. For
|
||||
// testing, both must be present to test their functionality.
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_TEST_H)
|
||||
#define ASDF_KEYMAP_DEFS_TEST_H
|
||||
|
||||
#define ASDF_TEST_NUM_ROWS 9
|
||||
#define ASDF_TEST_NUM_COLS 8
|
||||
|
||||
// The first value in each row serves two purposes:
|
||||
//
|
||||
// 1) Indicate a valid row of codes if the value is nonzero.
|
||||
// 2) Indicate the physical row number corresponding to the keymap row.
|
||||
//
|
||||
// Multiple keymaps may be combined, some of which use more rows than other
|
||||
// keymaps. The keymap with the most rows determines how many rows are allocated
|
||||
// for each keymap. Since each keymap only initializes the rows it uses, then
|
||||
// the shorter keymaps may have multiple uninitialized rows that should not be
|
||||
// scanned. The C99 standard guarantees that all elements no explicitly
|
||||
// initialized shall be initialized to 0 (C99 Standard 6.7.8.21). Therefore,
|
||||
// keymap rows starting with a 0 are not valid and are not scanned.
|
||||
//
|
||||
// Some hardware may contain blank physical rows To avoid having unused empty
|
||||
// rows, the first column of each row indicates the physical row. For example, 8
|
||||
// rows of switches (0-7), and a bank of DIP switches on row 15. In this case,
|
||||
// only 9 rows need be allocated.
|
||||
|
||||
|
||||
#define PLAIN_MATRIX_1 RESERVED_1
|
||||
#define CAPS_MATRIX_1 RESERVED_2
|
||||
#define SHIFT_MATRIX_1 RESERVED_3
|
||||
#define CTRL_MATRIX_1 RESERVED_4
|
||||
|
||||
#define ASDF_LAST_ROW (ASDF_NUM_ROWS - 1)
|
||||
#define ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
[ASDF_LAST_ROW] = { ACTION_MAPSEL_0, ACTION_MAPSEL_1, ACTION_MAPSEL_2, ACTION_MAPSEL_3 }
|
||||
|
||||
#define ASDF_TEST_PLAIN_MAP \
|
||||
{ \
|
||||
{ PLAIN_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_CAPS, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
|
||||
{ ACTION_NOTHING, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
|
||||
{ ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' }, \
|
||||
{ ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' }, \
|
||||
/**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
|
||||
'l', ASCII_PERIOD }, \
|
||||
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
|
||||
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_CAPS_MAP \
|
||||
{ \
|
||||
{ CAPS_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
|
||||
{ ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
/**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
|
||||
'L', ASCII_PERIOD }, \
|
||||
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
|
||||
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_SHIFT_MAP \
|
||||
{ \
|
||||
\
|
||||
{ SHIFT_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_VERT_BAR }, \
|
||||
{ ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
{ ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
{ ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
|
||||
{ ASCII_TILDE, ASCII_RT_CURLY_BRACE, ASCII_LT_CURLY_BRACE, '=', '*', \
|
||||
'0', ASCII_RT_PAREN, ASCII_LT_PAREN }, \
|
||||
{ ACTION_NOTHING, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
|
||||
ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_TEST_CTRL_MAP \
|
||||
{ \
|
||||
{ CTRL_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, 0x1c }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, \
|
||||
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
|
||||
ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, \
|
||||
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, \
|
||||
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W }, \
|
||||
{ ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
|
||||
ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
|
||||
{ ACTION_NOTHING, 0x1d, ASCII_ESC, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_FN_1, ACTION_FN_9, ACTION_FN_8 }, \
|
||||
{ ACTION_NOTHING, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, \
|
||||
ACTION_FN_4, ACTION_FN_3, ACTION_FN_2, ACTION_FN_2 }, \
|
||||
ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_TEST_DECLARATIONS \
|
||||
static const FLASH keycode_matrix_t test_PLAIN_matrix = ASDF_TEST_PLAIN_MAP; \
|
||||
static const FLASH keycode_matrix_t test_SHIFT_matrix = ASDF_TEST_SHIFT_MAP; \
|
||||
static const FLASH keycode_matrix_t test_CAPS_matrix = ASDF_TEST_CAPS_MAP; \
|
||||
static const FLASH keycode_matrix_t test_CTRL_matrix = ASDF_TEST_CTRL_MAP;
|
||||
|
||||
#define ASDF_TEST_MAP_DEFS \
|
||||
{ \
|
||||
&test_PLAIN_matrix, &test_SHIFT_matrix, &test_CAPS_matrix, &test_CTRL_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_CAPS_MAP_DEFS \
|
||||
{ \
|
||||
&test_CAPS_matrix, &test_SHIFT_matrix, &test_CAPS_matrix, &test_CTRL_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_KEYMAPS ASDF_TEST_MAP_DEFS, ASDF_TEST_CAPS_MAP_DEFS
|
||||
|
||||
#define ASDF_TEST_KEYMAPS_COUNT 2
|
||||
#define ASDF_TEST_PLAIN_MAP_INDEX ASDF_TEST_BASE + 0
|
||||
#define ASDF_TEST_CAPS_MAP_INDEX ASDF_TEST_BASE + 1
|
||||
|
||||
#define SINGLE_TESTS_KEYMAP ASDF_TEST_PLAIN_MAP_INDEX
|
||||
#define DOUBLE_ASSIGN_TEST_KEYMAP ASDF_TEST_PLAIN_MAP_INDEX
|
||||
|
||||
#define TRIPLE_TESTS_KEYMAP ASDF_TEST_CAPS_MAP_INDEX
|
||||
|
||||
#define ASDF_TEST_KEYMAP_INITIALIZER_LENGTH 5
|
||||
#define ASDF_TEST_KEYMAP_INITIALIZER_1 \
|
||||
{ \
|
||||
{ \
|
||||
/* Single assignment */ \
|
||||
.virtual_device = VOUT1, \
|
||||
.physical_device = PHYSICAL_OUT1, \
|
||||
.function = V_NOFUNC, \
|
||||
.initial_value = 0, \
|
||||
}, \
|
||||
{ \
|
||||
/* single toggle */ \
|
||||
.virtual_device = VOUT2, \
|
||||
.physical_device = PHYSICAL_OUT2, \
|
||||
.function = V_TOGGLE, \
|
||||
.initial_value = 0, \
|
||||
}, \
|
||||
{ \
|
||||
/* single pulse */ \
|
||||
.virtual_device = VOUT3, \
|
||||
.physical_device = PHYSICAL_OUT3, \
|
||||
.function = V_PULSE_SHORT, \
|
||||
.initial_value = 0, \
|
||||
}, \
|
||||
{ /* first of double assignment attempt */ \
|
||||
.virtual_device = VOUT4, \
|
||||
.physical_device = PHYSICAL_LED1, \
|
||||
.initial_value = 0 \
|
||||
}, \
|
||||
{ /* second of double assignment attempt */ \
|
||||
.virtual_device = VOUT5, .physical_device = PHYSICAL_LED1, .initial_value = 1 \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_KEYMAP_INITIALIZER_2 \
|
||||
{ \
|
||||
{ \
|
||||
/* Triple assignment */ \
|
||||
.virtual_device = VOUT1, \
|
||||
.physical_device = PHYSICAL_OUT1, \
|
||||
.function = V_TOGGLE, \
|
||||
.initial_value = 0, \
|
||||
}, \
|
||||
{ \
|
||||
.virtual_device = VOUT1, \
|
||||
.physical_device = PHYSICAL_OUT2, \
|
||||
.function = V_TOGGLE, \
|
||||
.initial_value = 1, \
|
||||
}, \
|
||||
{ \
|
||||
.virtual_device = VOUT1, .physical_device = PHYSICAL_OUT3, .function = V_TOGGLE, \
|
||||
.initial_value = 0, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_KEYMAP_INITIALIZER ASDF_TEST_KEYMAP_INITIALIZER_1, ASDF_TEST_KEYMAP_INITIALIZER_2
|
||||
|
||||
#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH 2
|
||||
|
||||
#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_1 \
|
||||
{ \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = &test_hook_1, \
|
||||
}, \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = &test_hook_2, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_2 \
|
||||
{ \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = &test_hook_3, \
|
||||
}, \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_KEYMAP_SETUP, \
|
||||
.hook_func = &test_hook_4, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER \
|
||||
ASDF_TEST_KEYMAP_HOOK_INITIALIZER_1, ASDF_TEST_KEYMAP_HOOK_INITIALIZER_2
|
||||
|
||||
|
||||
// The following preprocessor "code" permits various keymaps to be created and
|
||||
// included without generating a lot of complicating code dependencies. The use
|
||||
// of macros in this way is a bit ugly, I realize, and stretches the intention
|
||||
// of the C preprocessor. The C preprocessor is used to store a bit of state to
|
||||
// keep track of the number and ordering of the keymaps as they are added, and
|
||||
// to keep track of the array sizes to be allocated at compile time.
|
||||
|
||||
|
||||
#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_TEST_NUM_ROWS)
|
||||
#undef ASDF_NUM_ROWS
|
||||
#define ASDF_NUM_ROWS ASDF_TEST_NUM_ROWS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_TEST_NUM_COLS)
|
||||
#undef ASDF_NUM_COLS
|
||||
#define ASDF_NUM_COLS ASDF_TEST_NUM_COLS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_TEST_KEYMAP_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_TEST_KEYMAP_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_TEST_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,239 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymaps.h
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// While there is nothing preventing a standard keyboard from having both a
|
||||
// "Shift Lock" key and a "Caps Lock" key, usually only one will be present. For
|
||||
// testing, both must be present to test their functionality.
|
||||
|
||||
#if !defined(ASDF_KEYMAP_DEFS_TEST2_H)
|
||||
#define ASDF_KEYMAP_DEFS_TEST2_H
|
||||
|
||||
#define ASDF_TEST2_NUM_ROWS 16
|
||||
#define ASDF_TEST2_NUM_COLS 8
|
||||
|
||||
// The first value in each row serves two purposes:
|
||||
//
|
||||
// 1) Indicate a valid row of codes if the value is nonzero.
|
||||
// 2) Indicate the physical row number corresponding to the keymap row.
|
||||
//
|
||||
// Multiple keymaps may be combined, some of which use more rows than other
|
||||
// keymaps. The keymap with the most rows determines how many rows are allocated
|
||||
// for each keymap. Since each keymap only initializes the rows it uses, then
|
||||
// the shorter keymaps may have multiple uninitialized rows that should not be
|
||||
// scanned. The C99 standard guarantees that all elements no explicitly
|
||||
// initialized shall be initialized to 0 (C99 Standard 6.7.8.21). Therefore,
|
||||
// keymap rows starting with a 0 are not valid and are not scanned.
|
||||
//
|
||||
// Some hardware may contain blank physical rows To avoid having unused empty
|
||||
// rows, the first column of each row indicates the physical row. For example, 8
|
||||
// rows of switches (0-7), and a bank of DIP switches on row 15. In this case,
|
||||
// only 9 rows need be allocated.
|
||||
|
||||
|
||||
#define PLAIN_MATRIX_2 RESERVED_5
|
||||
#define CAPS_MATRIX_2 RESERVED_6
|
||||
#define SHIFT_MATRIX_2 RESERVED_7
|
||||
#define CTRL_MATRIX_2 RESERVED_8
|
||||
|
||||
#define ASDF_LAST_ROW (ASDF_NUM_ROWS - 1)
|
||||
|
||||
#define ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
[ASDF_LAST_ROW] = { ACTION_MAPSEL_0, ACTION_MAPSEL_1, ACTION_MAPSEL_2, ACTION_MAPSEL_3 }
|
||||
|
||||
#define ASDF_TEST2_PLAIN_MAP \
|
||||
{ \
|
||||
{ PLAIN_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_CAPS, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
|
||||
{ ACTION_NOTHING, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
|
||||
{ ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' }, \
|
||||
{ ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' }, \
|
||||
/**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
|
||||
'l', ASCII_PERIOD }, \
|
||||
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
|
||||
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_CAPS_MAP \
|
||||
{ \
|
||||
{ CAPS_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
|
||||
{ ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
/**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
|
||||
'L', ASCII_PERIOD }, \
|
||||
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
|
||||
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_SHIFT_MAP \
|
||||
{ \
|
||||
\
|
||||
{ SHIFT_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_VERT_BAR }, \
|
||||
{ ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
|
||||
{ ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
|
||||
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
|
||||
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
|
||||
{ ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
|
||||
{ ASCII_TILDE, ASCII_RT_CURLY_BRACE, ASCII_LT_CURLY_BRACE, '=', '*', \
|
||||
'0', ASCII_RT_PAREN, ASCII_LT_PAREN }, \
|
||||
{ ACTION_NOTHING, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
|
||||
ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_TEST2_CTRL_MAP \
|
||||
{ \
|
||||
{ CTRL_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, 0x1c }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, \
|
||||
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q }, \
|
||||
{ ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
|
||||
ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, \
|
||||
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S }, \
|
||||
{ ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, \
|
||||
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W }, \
|
||||
{ ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
|
||||
ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
|
||||
{ ACTION_NOTHING, 0x1d, ASCII_ESC, ACTION_NOTHING, \
|
||||
ACTION_NOTHING, ACTION_FN_1, ACTION_FN_9, ACTION_FN_8 }, \
|
||||
{ ACTION_NOTHING, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, \
|
||||
ACTION_FN_4, ACTION_FN_3, ACTION_FN_2, ACTION_FN_2 }, \
|
||||
ASDF_TEST_MAP_DIP_SWITCHES \
|
||||
}
|
||||
|
||||
|
||||
#define ASDF_TEST2_DECLARATIONS \
|
||||
static const FLASH keycode_matrix_t test2_PLAIN_matrix = ASDF_TEST2_PLAIN_MAP; \
|
||||
static const FLASH keycode_matrix_t test2_SHIFT_matrix = ASDF_TEST2_SHIFT_MAP; \
|
||||
static const FLASH keycode_matrix_t test2_CAPS_matrix = ASDF_TEST2_CAPS_MAP; \
|
||||
static const FLASH keycode_matrix_t test2_CTRL_matrix = ASDF_TEST2_CTRL_MAP;
|
||||
|
||||
#define ASDF_TEST2_MAP_DEFS \
|
||||
{ \
|
||||
&test2_PLAIN_matrix, &test2_SHIFT_matrix, &test2_CAPS_matrix, &test2_CTRL_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_CAPS_MAP_DEFS \
|
||||
{ \
|
||||
&test2_CAPS_matrix, &test2_SHIFT_matrix, &test2_CAPS_matrix, &test2_CTRL_matrix \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_KEYMAPS ASDF_TEST2_MAP_DEFS, ASDF_TEST2_CAPS_MAP_DEFS
|
||||
|
||||
#define ASDF_TEST2_KEYMAPS_COUNT 2
|
||||
#define ASDF_TEST2_PLAIN_MAP_INDEX (ASDF_TEST2_BASE + 0)
|
||||
#define ASDF_TEST2_CAPS_MAP_INDEX (ASDF_TEST2_BASE + 1)
|
||||
#define VCAPS_TEST_KEYMAP ASDF_TEST2_PLAIN_MAP_INDEX
|
||||
#define VSHIFT_TEST_KEYMAP ASDF_TEST2_PLAIN_MAP_INDEX
|
||||
|
||||
#define ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH 4
|
||||
#define ASDF_TEST2_KEYMAP_INITIALIZER_1 \
|
||||
{ \
|
||||
{ .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
|
||||
{ .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
|
||||
{ .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
|
||||
{ \
|
||||
.virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_KEYMAP_INITIALIZER_2 \
|
||||
{ \
|
||||
{ .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
|
||||
{ .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
|
||||
{ .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
|
||||
{ \
|
||||
.virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_KEYMAP_INITIALIZER \
|
||||
ASDF_TEST2_KEYMAP_INITIALIZER_1, ASDF_TEST2_KEYMAP_INITIALIZER_2
|
||||
|
||||
|
||||
#define ASDF_TEST_ALTERNATE_SCANNER_MAP (ASDF_TEST2_BASE + 0)
|
||||
#define ASDF_TEST_ALTERNATE_OUTPUT_MAP (ASDF_TEST2_BASE + 0)
|
||||
#define ASDF_TEST_EACH_SCAN_MAP (ASDF_TEST2_BASE + 1)
|
||||
#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH 2
|
||||
#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_1 \
|
||||
{ \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_SCANNER, \
|
||||
.hook_func = (asdf_hook_function_t) test_hook_read_row, \
|
||||
}, \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_OUTPUT, \
|
||||
.hook_func = (asdf_hook_function_t) test_hook_output, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_2 \
|
||||
{ \
|
||||
{ \
|
||||
.hook_id = ASDF_HOOK_EACH_SCAN, \
|
||||
.hook_func = (asdf_hook_function_t) test_hook_each_scan, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER \
|
||||
ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_1, ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_2
|
||||
|
||||
|
||||
// The following preprocessor "code" permits various keymaps to be created and
|
||||
// included without generating a lot of complicating code dependencies. The use
|
||||
// of macros in this way is a bit ugly, I realize, and stretches the intention
|
||||
// of the C preprocessor. The C preprocessor is used to store a bit of state to
|
||||
// keep track of the number and ordering of the keymaps as they are added, and
|
||||
// to keep track of the array sizes to be allocated at compile time.
|
||||
|
||||
|
||||
#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_TEST2_NUM_ROWS)
|
||||
#undef ASDF_NUM_ROWS
|
||||
#define ASDF_NUM_ROWS ASDF_TEST2_NUM_ROWS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_TEST2_NUM_COLS)
|
||||
#undef ASDF_NUM_COLS
|
||||
#define ASDF_NUM_COLS ASDF_TEST2_NUM_COLS
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
|
||||
|| (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH)
|
||||
#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH
|
||||
#endif
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_DEFS_TEST2_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,187 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymap_sol.c
|
||||
//
|
||||
// Implements the keymap definition and setup routines for the sol-20 keymap
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "asdf_arch.h"
|
||||
#include "asdf_keymap_sol.h"
|
||||
#include "asdf.h"
|
||||
#include "asdf_ascii.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_print.h"
|
||||
|
||||
|
||||
#define SOL_PRINT_DELAY 40 // msec
|
||||
#define SOL_ID_MESSAGE_HOOK ASDF_HOOK_USER_10
|
||||
|
||||
static const FLASH asdf_keycode_t sol_plain_map[ASDF_SOL_NUM_ROWS][ASDF_SOL_NUM_COLS] = {
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'a', 's', 'd', 'f', 'g', 'h' },
|
||||
[1] = { 'j', 'k', 'l', ';', ':', ASCII_DEL, ACTION_REPEAT, ACTION_CTRL },
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'z', 'x', 'c', 'v', 'b', 'n' },
|
||||
[3] = { 'm', ASCII_COMMA, ASCII_PERIOD, '/', ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
[4] = { ASCII_ESC, '1', '2', '3', '4', '5', '6', '7' },
|
||||
[5] = { '8', '9', ASCII_ZERO, '-', '^', ASCII_LT_SQUARE_BRACE, ASCII_BACKSLASH,
|
||||
ASCII_RT_SQUARE_BRACE },
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'q', 'w', 'e', 'r', 't', 'y' },
|
||||
[7] = { 'u', 'i', 'o', 'p', ASCII_AT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD },
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, ASCII_SPACE,
|
||||
SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, SOL_ASCII_HOME, SOL_ASCII_CLEAR },
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
ASDF_SOL_DIP_SWITCHES,
|
||||
};
|
||||
|
||||
static const FLASH asdf_keycode_t sol_caps_map[ASDF_SOL_NUM_ROWS][ASDF_SOL_NUM_COLS] = {
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'A', 'S', 'D', 'F', 'G', 'H' },
|
||||
[1] = { 'J', 'K', 'L', ';', ':', ASCII_DEL, ACTION_REPEAT, ACTION_CTRL },
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'Z', 'X', 'C', 'V', 'B', 'N' },
|
||||
[3] = { 'M', ASCII_COMMA, ASCII_PERIOD, '/', ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
[4] = { ASCII_ESC, '1', '2', '3', '4', '5', '6', '7' }, /**/
|
||||
[5] = { '8', '9', ASCII_ZERO, '-', '^', ASCII_LT_SQUARE_BRACE, ASCII_BACKSLASH,
|
||||
ASCII_RT_SQUARE_BRACE },
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y' },
|
||||
[7] = { 'U', 'I', 'O', 'P', ASCII_AT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD },
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, ASCII_SPACE,
|
||||
SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, SOL_ASCII_HOME, SOL_ASCII_CLEAR },
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
ASDF_SOL_DIP_SWITCHES,
|
||||
};
|
||||
|
||||
|
||||
static const FLASH asdf_keycode_t sol_shift_map[ASDF_SOL_NUM_ROWS][ASDF_SOL_NUM_COLS] = {
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, 'A', 'S', 'D', 'F', 'G', 'H' },
|
||||
[1] = { 'J', 'K', 'L', ';', ':', ASCII_UNDERSCORE, ACTION_REPEAT, ACTION_CTRL },
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, 'Z', 'X', 'C', 'V', 'B', 'N' },
|
||||
[3] = { 'M', '<', '>', '?', ACTION_SHIFT, SOL_ASCII_MODE_SELECT, ACTION_NOTHING, ACTION_NOTHING },
|
||||
[4] = { ASCII_ESC, '!', ASCII_DOUBLE_QUOTE, '#', '$', '%', '&', ASCII_SINGLE_QUOTE },
|
||||
[5] = { ASCII_LT_PAREN, ASCII_RT_PAREN, ASCII_SPACE, '=', ASCII_TILDE, ASCII_LT_SQUARE_BRACE,
|
||||
ASCII_BACKSLASH, ASCII_RT_SQUARE_BRACE },
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y' },
|
||||
[7] = { 'U', 'I', 'O', 'P', ASCII_GRAVE_ACCENT, ASCII_CR, ASCII_LF, SOL_ASCII_LOAD },
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, ASCII_SPACE,
|
||||
SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, SOL_ASCII_HOME, SOL_ASCII_CLEAR },
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
ASDF_SOL_DIP_SWITCHES,
|
||||
};
|
||||
|
||||
|
||||
static const FLASH asdf_keycode_t sol_ctrl_map[ASDF_SOL_NUM_ROWS][ASDF_SOL_NUM_COLS] = {
|
||||
[0] = { ACTION_CTRL, SOL_KBD_SHIFTLOCK_ACTION, ASCII_CTRL_A, ASCII_CTRL_S, ASCII_CTRL_D,
|
||||
ASCII_CTRL_F, ASCII_CTRL_G, ASCII_CTRL_H },
|
||||
[1] = { ASCII_CTRL_J, ASCII_CTRL_K, ASCII_CTRL_L, ASCII_VT, ASCII_LF, ASCII_DEL,
|
||||
SOL_KBD_RESET_ACTION, ACTION_CTRL },
|
||||
[2] = { ACTION_CAPS, ACTION_SHIFT, ASCII_CTRL_Z, ASCII_CTRL_X, ASCII_CTRL_C, ASCII_CTRL_V,
|
||||
ASCII_CTRL_B, ASCII_CTRL_N },
|
||||
[3] = { ASCII_CTRL_M, ASCII_FF, ASCII_SO, ASCII_SI, ACTION_SHIFT, SOL_ASCII_MODE_SELECT,
|
||||
ACTION_NOTHING, ACTION_NOTHING },
|
||||
[4] = { ASCII_ESC, ASCII_SOH, ASCII_STX, ASCII_ETX, ASCII_EOT, ASCII_ENQ, ASCII_ACK, ASCII_BEL },
|
||||
[5] = { ASCII_BS, ASCII_TAB, ASCII_NULL, ASCII_CR, ASCII_RS, ASCII_ESC, ASCII_FS, ASCII_GS },
|
||||
[6] = { SOL_KBD_BREAK_ACTION, ASCII_TAB, ASCII_CTRL_Q, ASCII_CTRL_W, ASCII_CTRL_E, ASCII_CTRL_R,
|
||||
ASCII_CTRL_T, ASCII_CTRL_Y },
|
||||
[7] = { ASCII_CTRL_U, ASCII_CTRL_I, ASCII_CTRL_O, ASCII_CTRL_P, ASCII_NULL, ASCII_CR, ASCII_LF,
|
||||
SOL_ASCII_LOAD },
|
||||
[9] = { SOL_KBD_LOCAL_ACTION, SOL_ASCII_UP_ARROW, SOL_ASCII_LT_ARROW, ASCII_SPACE,
|
||||
SOL_ASCII_RT_ARROW, SOL_ASCII_DN_ARROW, SOL_ASCII_HOME, SOL_ASCII_CLEAR },
|
||||
[10] = { '-', '7', '*', '8', '/', '9', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[11] = { '4', '1', '5', '2', '6', '3', ACTION_NOTHING, ACTION_NOTHING },
|
||||
[12] = { '0', ASCII_PERIOD, '+', ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING, ACTION_NOTHING,
|
||||
ACTION_NOTHING },
|
||||
ASDF_SOL_DIP_SWITCHES,
|
||||
};
|
||||
|
||||
|
||||
// PROCEDURE: sol_add_map
|
||||
// INPUTS: asdf_keycode_t (*matrix) - a SOL_NUM_ROWS x SOL_NUM_COLS matrix of keycodes for each physical row/column pair
|
||||
// modifier_index_t modifier index - the modifier state corresponding to the keycode matrix
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Passes the keycode matrix and modifier state through to
|
||||
// asdf_keymaps_add_map(), along with the row/column dimensions.
|
||||
//
|
||||
// SIDE EFFECTS: the matrix is added to the keymap
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
static void sol_add_map(const asdf_keycode_t (*matrix)[ASDF_SOL_NUM_COLS],
|
||||
modifier_index_t modifier_index)
|
||||
{
|
||||
asdf_keymaps_add_map(&matrix[0][0], modifier_index, (uint8_t) ASDF_SOL_NUM_ROWS,
|
||||
(uint8_t) ASDF_SOL_NUM_COLS);
|
||||
}
|
||||
|
||||
|
||||
static void sol_id_message(void)
|
||||
{
|
||||
asdf_print("[Keybd: Sol-20]");
|
||||
}
|
||||
|
||||
void setup_sol_keymap(void)
|
||||
{
|
||||
sol_add_map(sol_plain_map, MOD_PLAIN_MAP);
|
||||
sol_add_map(sol_caps_map, MOD_CAPS_MAP);
|
||||
sol_add_map(sol_shift_map, MOD_SHIFT_MAP);
|
||||
sol_add_map(sol_ctrl_map, MOD_CTRL_MAP);
|
||||
|
||||
asdf_set_print_delay(SOL_PRINT_DELAY);
|
||||
|
||||
// Set up the ALL CAPS LED, default = off
|
||||
asdf_virtual_assign(VCAPS_LED, SOL_KBD_LED_UPPERCASE, V_NOFUNC, SOL_KBD_LED_OFF);
|
||||
|
||||
// Set up the SHIFT LED, default = off
|
||||
asdf_virtual_assign(VSHIFT_LED, SOL_KBD_LED_SHIFTLOCK, V_NOFUNC, SOL_KBD_LED_OFF);
|
||||
|
||||
// Set up the LOCAL LED and output, default LED=OFF, TTL output HIGH. Both LED
|
||||
// and TTL out are bound to the save virtual device.
|
||||
asdf_virtual_assign(SOL_KBD_VLOCAL, SOL_KBD_TTLOUT_LOCAL, V_TOGGLE, SOL_KBD_TTL_HIGH);
|
||||
asdf_virtual_assign(SOL_KBD_VLOCAL, SOL_KBD_LED_LOCAL, V_TOGGLE, SOL_KBD_LED_OFF);
|
||||
|
||||
// Set up the RESET output, produce a short pulse when activated. Default output HIGH
|
||||
asdf_virtual_assign(SOL_KBD_VRESET, SOL_KBD_TTLOUT_RESET, V_PULSE_SHORT, SOL_KBD_TTL_HIGH);
|
||||
|
||||
// Set up the BREAK output, produce a long pulse when activated, default output high
|
||||
asdf_virtual_assign(SOL_KBD_VBREAK, SOL_KBD_TTLOUT_BREAK, V_PULSE_LONG, SOL_KBD_TTL_HIGH);
|
||||
|
||||
// Activate the ALL CAPS mode to emulate the original keyboard:
|
||||
asdf_modifier_capslock_activate();
|
||||
|
||||
// Configure negative strobe
|
||||
asdf_arch_set_neg_strobe();
|
||||
|
||||
asdf_hook_assign(SOL_ID_MESSAGE_HOOK, sol_id_message);
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,127 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_keymaps_sol.h
|
||||
//
|
||||
// Ascii keymaps
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// To use this ascii for a new keymap, edit the keymaps definitions as
|
||||
// desired. The keymaps are organized from row 0, counting upward, and each row
|
||||
// includes the columns from 0-NUM_COLS.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_KEYMAP_SOL_H)
|
||||
#define ASDF_KEYMAP_SOL_H
|
||||
#include "asdf.h"
|
||||
#include "asdf_keymap_defs_dipswitch.h"
|
||||
|
||||
// Edit the number of rows and columns used in this map. If the number is less
|
||||
// than the maxium, the unused elements will be initialized to 0.
|
||||
|
||||
#define ASDF_SOL_NUM_ROWS 13 // DIP switches are row 9
|
||||
#define ASDF_SOL_NUM_COLS 8
|
||||
|
||||
|
||||
// Key Matrix for combination of ASCII controller (ATMega328P version) and Classic ASCII matrix
|
||||
//
|
||||
// Col-> 0 1 2 3 4 5 6 7
|
||||
// Row 0 Lt Ctrl ShiftLock A S D F G(alpha) H
|
||||
// Row 1 J K L ;(semi) :(colon) DEL Repeat Rt Ctrl
|
||||
// Row 2 UpperCase Lt Shift Z X C V B(alpha) N
|
||||
// Row 3 M ,(comma) .(period) /(slash) Rt Shift ModeSelect
|
||||
// Row 4 ESC 1 2 3 4 5 6(six) 7
|
||||
// Row 5 8(eight) 9 0(zero) -(Dash) ^(Caret) [ \ ]
|
||||
// Row 6 BREAK TAB Q W E R T Y
|
||||
// Row 7 U I O(alpha) P @(at) Return LineFeed Load
|
||||
// Row 9 LOCAL UpArrow LtArrow Spacebar RtArrow DnArrow Home Clear
|
||||
// Row 10 NP-Minus NP-7 NP-Times NP-8 NP-Divide NP-9 (none) (none)
|
||||
// Row 11 NP-4 NP-1 NP-5 NP-2 NP-6 NP-3 (none) (none)
|
||||
// Row 12 NP-0 NP-period NP-Plus
|
||||
//
|
||||
// Row 8 DIP switches 0-7
|
||||
//
|
||||
// Physical Resource mapping:
|
||||
// LED1: UPPER CASE
|
||||
// LED2: LOCAL
|
||||
// LED3: SHIFT LOCK
|
||||
// OUT1: RESET
|
||||
// OUT2: BREAK
|
||||
// OUT3: LOCAL
|
||||
|
||||
// Notes:
|
||||
//
|
||||
// 1) To ensure consistent DIP switch operation within the keymap, a
|
||||
// ASDF_SOL_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
|
||||
// definitions in positions 0-3 ensures consistent map selection among all
|
||||
// keymaps.
|
||||
|
||||
|
||||
#define SOL_PRINT_DELAY 40 // msec
|
||||
#define SOL_ID_MESSAGE_HOOK ASDF_HOOK_USER_10
|
||||
|
||||
#define SOL_NUM_ROWS 13
|
||||
#define SOL_NUM_COLS 8
|
||||
|
||||
#define SOL_KBD_VRESET VOUT1
|
||||
#define SOL_KBD_VBREAK VOUT2
|
||||
#define SOL_KBD_VLOCAL VOUT3
|
||||
#define SOL_KBD_LED_ON 1
|
||||
#define SOL_KBD_LED_OFF 0
|
||||
|
||||
// The SOL manual (sec. 7.7.8) indicates shiftlock locks SHIFT on, and SHIFT
|
||||
// returns to unshifted. For Toggle behavior, change to ACTION_SHIFTLOCK_TOGGLE.
|
||||
#define SOL_KBD_SHIFTLOCK_ACTION ACTION_SHIFTLOCK_ON
|
||||
|
||||
|
||||
// The weird C preprocessor expansion behavior requires one dereference for each
|
||||
// expansion.
|
||||
#define SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE) ACTION_ ## SOL_VDEVICE
|
||||
#define SOL_KBD_VIRTUAL_SUB(SOL_VDEVICE) SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE)
|
||||
#define SOL_KBD_LOCAL_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VLOCAL)
|
||||
#define SOL_KBD_RESET_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VRESET)
|
||||
#define SOL_KBD_BREAK_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VBREAK)
|
||||
|
||||
#define SOL_ASCII_LOAD 0x8C
|
||||
#define SOL_ASCII_MODE_SELECT 0x80
|
||||
#define SOL_ASCII_UP_ARROW 0x97
|
||||
#define SOL_ASCII_LT_ARROW 0x81
|
||||
#define SOL_ASCII_RT_ARROW 0x93
|
||||
#define SOL_ASCII_DN_ARROW 0x9a
|
||||
#define SOL_ASCII_HOME 0x8e
|
||||
#define SOL_ASCII_CLEAR 0x8b
|
||||
|
||||
#define SOL_KBD_TTL_HIGH 1
|
||||
#define SOL_KBD_TTL_LOW 0
|
||||
|
||||
#define SOL_KBD_LED_UPPERCASE PHYSICAL_LED1
|
||||
#define SOL_KBD_LED_LOCAL PHYSICAL_LED2
|
||||
#define SOL_KBD_LED_SHIFTLOCK PHYSICAL_LED3
|
||||
#define SOL_KBD_TTLOUT_RESET PHYSICAL_OUT3_OPEN_HI // Emulate open collector output.
|
||||
#define SOL_KBD_TTLOUT_BREAK PHYSICAL_OUT2
|
||||
#define SOL_KBD_TTLOUT_LOCAL PHYSICAL_OUT1
|
||||
|
||||
#define ASDF_SOL_DIP_SWITCHES ASDF_KEYMAP_DIP_SWITCHES
|
||||
|
||||
|
||||
#endif /* !defined (ASDF_KEYMAP_SOL_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,14 +0,0 @@
|
|||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
|
@ -1,125 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// <FIXME-filename>.c
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
|
||||
// Wiring Information:
|
||||
// Chip: {Microcontroller type and version}
|
||||
//
|
||||
// Example:
|
||||
// PIN NAME FUNCTION
|
||||
// 3 AN1 ADC INPUT: Line sense analog input
|
||||
//
|
||||
// 6 A4 INPUT: (T0CK) COUNT DOWN from quadrature decoder.
|
||||
// configured to count on rising edge, synced with xtal
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Headers
|
||||
//
|
||||
|
||||
#include <version.h>
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Global Variable declarations: Use very sparingly. Used for communication
|
||||
// with ISR's. Exceptions should be documented.
|
||||
//
|
||||
|
||||
// Examples:
|
||||
|
||||
// run_clock_thread (global uns 8) when this is set to TRUE (by the
|
||||
// clock_tick() ISR every 20 ms), the main loop performs certain
|
||||
// actions, and resets the value to FALSE (see main loop comments)
|
||||
//
|
||||
uint8 send_count = FALSE;
|
||||
|
||||
|
||||
//
|
||||
// ISR routines
|
||||
//
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
//
|
||||
// Regular functions
|
||||
//
|
||||
|
||||
// PROCEDURE:
|
||||
// INPUTS:
|
||||
// OUTPUTS:
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE:
|
||||
//
|
||||
// COMPLEXITY:
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// PROCEDURE: main()
|
||||
//
|
||||
// Main program loop; invoked at processor startup.
|
||||
//
|
||||
|
||||
main()
|
||||
{
|
||||
// INITIALIZATION SECTION
|
||||
|
||||
cold_start:
|
||||
|
||||
|
||||
// re-initialize variables and re-enter control loop, when the "R" command
|
||||
// is received
|
||||
|
||||
warm_start:
|
||||
|
||||
// END OF INITIALIZATION SECTION
|
||||
|
||||
// Main Section:
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unfified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// <FIXME-filename>.h
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined (FILENAME_H)
|
||||
#define FILENAME_H
|
||||
|
||||
//
|
||||
// Headers
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Device and peripheral definitions, comments should include use of devices.
|
||||
// Please
|
||||
//
|
||||
|
||||
#endif /* !defined (FILENAME_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
---
|
||||
BasedOnStyle: Mozilla
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignOperands: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'true'
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: 'false'
|
||||
AllowShortLoopsOnASingleLine: 'true'
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: 'true'
|
||||
BinPackArguments: 'true'
|
||||
BinPackParameters: 'true'
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Stroustrup
|
||||
ColumnLimit: '100'
|
||||
ConstructorInitializerIndentWidth: '2'
|
||||
ContinuationIndentWidth: '2'
|
||||
DerivePointerAlignment: 'false'
|
||||
DisableFormat: 'false'
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseLabels: 'true'
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: '2'
|
||||
IndentWrappedFunctionNames: 'false'
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'true'
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: '2'
|
||||
PointerAlignment: Right
|
||||
ReflowComments: 'true'
|
||||
SortIncludes: 'false'
|
||||
SpaceAfterCStyleCast: 'true'
|
||||
SpaceBeforeAssignmentOperators: 'true'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesBeforeTrailingComments: '1'
|
||||
SpacesInCStyleCastParentheses: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
TabWidth: '8'
|
||||
UseTab: Never
|
||||
|
||||
...
|
|
@ -1,667 +0,0 @@
|
|||
// File recommented by recomment.cpp
|
||||
// on Dec 9 2019 at 10:14:05.
|
||||
//
|
||||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Universal Keyboard Project
|
||||
// ASDF firmware - small, fast, and simple keyboard encoder.
|
||||
//
|
||||
// asdf.c
|
||||
//
|
||||
// This file contains code for:
|
||||
// - the main scan code and key handler routines
|
||||
// - key matrix declarations and keyboard state variables not delegated
|
||||
// elsewhere.
|
||||
// - Key debouncing logic and data stuctures
|
||||
// - dispatch of special functions bound to keys.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option) any
|
||||
// later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "asdf.h"
|
||||
#include "asdf_ascii.h"
|
||||
#include "asdf_physical.h"
|
||||
#include "asdf_virtual.h"
|
||||
#include "asdf_keymaps.h"
|
||||
#include "asdf_repeat.h"
|
||||
#include "asdf_modifiers.h"
|
||||
#include "asdf_buffer.h"
|
||||
#include "asdf_arch.h"
|
||||
#include "asdf_hook.h"
|
||||
|
||||
// The key scanner keeps track of the last stable (debounced) state of each key
|
||||
// in the matrix, one bit per key, 8 bits per row.
|
||||
static asdf_cols_t last_stable_key_state[ASDF_MAX_ROWS];
|
||||
|
||||
// Each key is debounced separately, supporting true N-key rollover, allowing a
|
||||
// new key to be pressed when the previously pressed key is still debouncing.
|
||||
// This requires a debounce counter for each key. This is is a large RAM
|
||||
// footprint, 64 bytes for an 8 x 8 key matrix. It would be possible to only
|
||||
// debounce the most recently pressed key and reduce the RAM usage to a single
|
||||
// debounce counuter. However, this would probably require different handling of
|
||||
// key presses and releases, and special handling for modifier keys, perhaps
|
||||
// including separate debounce logic in the handlers for toggle keys such as
|
||||
// CAPS_LOCK.
|
||||
static uint8_t debounce_counters[ASDF_MAX_ROWS][ASDF_MAX_COLS];
|
||||
|
||||
// Stores the last key pressed
|
||||
static asdf_keycode_t last_key;
|
||||
|
||||
// This is the handle for the char output buffer
|
||||
static asdf_buffer_handle_t asdf_keycode_buffer;
|
||||
|
||||
// This is the handle for the message output buffer
|
||||
static asdf_buffer_handle_t asdf_message_buffer;
|
||||
|
||||
// The delay time for strings sent via parallel port. This is needed because
|
||||
// most keyboards have no handshaking, and we need to allow time for various
|
||||
// environments to process the characters. Some, such as basic interpreters, are
|
||||
// rather slow. So we we allow keyboard modules to modifiy this delay.
|
||||
static uint16_t asdf_print_delay_ms;
|
||||
|
||||
// PROCEDURE: asdf_put_code
|
||||
// INPUTS: (asdf_keycode_t) code: code to be buffered for output
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a keycode argument and buffers for output.
|
||||
//
|
||||
// SIDE EFFECTS: modifies buffer state.
|
||||
//
|
||||
// NOTES: If buffer is full, silently drop the code.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_put_code(asdf_keycode_t code)
|
||||
{
|
||||
asdf_buffer_put(asdf_keycode_buffer, code);
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_putc
|
||||
// INPUTS: (char) c: character to be buffered for output
|
||||
// (FILE *) stream - only used to match prototype.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Takes a character generated by the system and buffers for
|
||||
// output.
|
||||
//
|
||||
// SIDE EFFECTS: modifies buffer state.
|
||||
//
|
||||
// NOTES: If buffer is full, silently drop the code.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
int asdf_putc(char c, FILE *stream)
|
||||
{
|
||||
// for messages, add CR to LF:
|
||||
if ('\n' == c) {
|
||||
asdf_putc('\r', stream);
|
||||
}
|
||||
asdf_buffer_put(asdf_message_buffer, (asdf_keycode_t) c);
|
||||
return (int) c;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_next_code
|
||||
// INPUTS: none
|
||||
//
|
||||
// OUTPUTS: (asdf_keycode_t) returns next value in buffer. If both buffers are
|
||||
// empty, the code ASDF_INVALID_CODE is returned.
|
||||
//
|
||||
// DESCRIPTION: Checks the message buffer, and returns a character
|
||||
// if present. Otherwise, return the next code in the keycode
|
||||
// buffer.
|
||||
//
|
||||
// SIDE EFFECTS: modifies buffer state.
|
||||
//
|
||||
// NOTES: A delay is enforced for system messages, to reduce the risk of dropped
|
||||
// characters with unbuffered polling hosts. No delay is needed for typed
|
||||
// keycodes, as these are generated at human speeds.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
asdf_keycode_t asdf_next_code(void)
|
||||
{
|
||||
asdf_keycode_t code = asdf_buffer_get(asdf_message_buffer);
|
||||
if (ASDF_INVALID_CODE == code) {
|
||||
code = asdf_buffer_get(asdf_keycode_buffer);
|
||||
} else {
|
||||
// for system message
|
||||
asdf_arch_delay_ms(asdf_print_delay_ms);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_set_print_delay
|
||||
// INPUTS: (uint8_t) delay_ms
|
||||
//
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: sets the delay to be used by the system print buffer
|
||||
//
|
||||
// SIDE EFFECTS: modifies character delay variable.
|
||||
//
|
||||
// NOTES: A delay is enforced for system messages, to reduce the risk of dropped
|
||||
// characters with unbuffered polling hosts. No delay is needed for typed
|
||||
// keycodes, as these are generated at human speeds.
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_set_print_delay(uint8_t delay_ms)
|
||||
{
|
||||
asdf_print_delay_ms = delay_ms;
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_lookup_keycode
|
||||
// INPUTS: row, col: specify a row and column in the keyboard matrix
|
||||
// OUTPUTS: returns a keycode
|
||||
//
|
||||
// DESCRIPTION: Given a row and column in the keyboard matrix, returns the
|
||||
// corresponding keycode, depending on the state of the modifier keys.
|
||||
//
|
||||
// SIDE EFFECTS: none
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
asdf_keycode_t asdf_lookup_keycode(uint8_t row, uint8_t col)
|
||||
{
|
||||
return asdf_keymaps_get_code(row, col, asdf_modifier_index());
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_activate_action
|
||||
// INPUTS: keycode: an action key code
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: This routine is called when a key bound to an action code is
|
||||
// pressed, and maps the action code to a function call, or other action
|
||||
// appropriate for activation of the function.
|
||||
//
|
||||
// SIDE EFFECTS: All the actions may have side effects, depending on the function called.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// NOTES: The switch() could be implemented as an array of function pointers,
|
||||
// essentially a jump table. However, the switch statement will also be
|
||||
// implemented as a jump table, and may be more efficiently implemented as a
|
||||
// code jump table than an array of pointers stored in flash that would require
|
||||
// an additional flash-read operation. Also, the switch jumptable will make more
|
||||
// efficient use of space than a sparse array of function pointers. The
|
||||
// reduction in cyclometric complexity by using an array is a technicality,
|
||||
// since the elements must still be entered as lines of code in some part of the
|
||||
// program. Here, they are arranged in the place they are used.
|
||||
//
|
||||
// COMPLEXITY: 1 (+18 for the switch)
|
||||
//
|
||||
static void asdf_activate_action(action_t keycode)
|
||||
{
|
||||
switch (keycode) {
|
||||
|
||||
case ACTION_SHIFT: {
|
||||
asdf_modifier_shift_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_SHIFTLOCK_ON: {
|
||||
asdf_modifier_shiftlock_on_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_SHIFTLOCK_TOGGLE: {
|
||||
asdf_modifier_shiftlock_toggle_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_CAPS: {
|
||||
asdf_modifier_capslock_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_CTRL: {
|
||||
asdf_modifier_ctrl_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_REPEAT: {
|
||||
asdf_repeat_activate();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_0: {
|
||||
asdf_keymaps_map_select_0_set();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_1: {
|
||||
asdf_keymaps_map_select_1_set();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_2: {
|
||||
asdf_keymaps_map_select_2_set();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_3: {
|
||||
asdf_keymaps_map_select_3_set();
|
||||
break;
|
||||
}
|
||||
case ACTION_STROBE_POLARITY_SELECT: {
|
||||
asdf_arch_set_pos_strobe();
|
||||
break;
|
||||
}
|
||||
case ACTION_AUTOREPEAT_SELECT: {
|
||||
asdf_repeat_auto_on();
|
||||
break;
|
||||
}
|
||||
case ACTION_VLED1: {
|
||||
asdf_virtual_activate(VLED1);
|
||||
break;
|
||||
}
|
||||
case ACTION_VLED2: {
|
||||
asdf_virtual_activate(VLED2);
|
||||
break;
|
||||
}
|
||||
case ACTION_VLED3: {
|
||||
asdf_virtual_activate(VLED3);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT1: {
|
||||
asdf_virtual_activate(VOUT1);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT2: {
|
||||
asdf_virtual_activate(VOUT2);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT3: {
|
||||
asdf_virtual_activate(VOUT3);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT4: {
|
||||
asdf_virtual_activate(VOUT4);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT5: {
|
||||
asdf_virtual_activate(VOUT5);
|
||||
break;
|
||||
}
|
||||
case ACTION_VOUT6: {
|
||||
asdf_virtual_activate(VOUT6);
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTHING:
|
||||
case ACTION_HERE_IS:
|
||||
case ACTION_FN_1:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_1);
|
||||
break;
|
||||
case ACTION_FN_2:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_2);
|
||||
break;
|
||||
case ACTION_FN_3:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_3);
|
||||
break;
|
||||
case ACTION_FN_4:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_4);
|
||||
break;
|
||||
case ACTION_FN_5:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_5);
|
||||
break;
|
||||
case ACTION_FN_6:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_6);
|
||||
break;
|
||||
case ACTION_FN_7:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_7);
|
||||
break;
|
||||
case ACTION_FN_8:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_8);
|
||||
break;
|
||||
case ACTION_FN_9:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_9);
|
||||
break;
|
||||
case ACTION_FN_10:
|
||||
asdf_hook_execute(ASDF_HOOK_USER_10);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_deactivate_action
|
||||
// INPUTS: keycode: an action key code
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: This routine is called when a key bound to an action code is
|
||||
// released, and maps the action code to a function call, or other action
|
||||
// appropriate for deactivation of the function.
|
||||
//
|
||||
// SIDE EFFECTS: All the actions may have side effects, depending on the function called.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// NOTES: See NOTE for asdf_activate_action(). The Virtual Outputs have
|
||||
// activate() functions, but no deactivate() functions, and are handled by the
|
||||
// default case.
|
||||
//
|
||||
// COMPLEXITY: 1 (+9 for the switch, see note)
|
||||
//
|
||||
static void asdf_deactivate_action(action_t keycode)
|
||||
{
|
||||
switch (keycode) {
|
||||
case ACTION_SHIFT: {
|
||||
asdf_modifier_shift_deactivate();
|
||||
break;
|
||||
}
|
||||
case ACTION_CTRL: {
|
||||
asdf_modifier_ctrl_deactivate();
|
||||
break;
|
||||
}
|
||||
case ACTION_REPEAT: {
|
||||
asdf_repeat_deactivate();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_0: {
|
||||
asdf_keymaps_map_select_0_clear();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_1: {
|
||||
asdf_keymaps_map_select_1_clear();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_2: {
|
||||
asdf_keymaps_map_select_2_clear();
|
||||
break;
|
||||
}
|
||||
case ACTION_MAPSEL_3: {
|
||||
asdf_keymaps_map_select_3_clear();
|
||||
break;
|
||||
}
|
||||
case ACTION_STROBE_POLARITY_SELECT: {
|
||||
asdf_arch_set_neg_strobe();
|
||||
break;
|
||||
}
|
||||
case ACTION_AUTOREPEAT_SELECT: {
|
||||
asdf_repeat_auto_off();
|
||||
break;
|
||||
}
|
||||
case ACTION_NOTHING:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_activate_key
|
||||
// INPUTS: keycode - the code for a key that has been pressed.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Called when a key has been pressed. If the key is bound to a
|
||||
// value, output the value. If the key is bound to an action, call the activate action
|
||||
// handler with the keycode.
|
||||
//
|
||||
// SIDE EFFECTS: If the code is a value, the last key is updated to the current
|
||||
// value, and repeat timer is reset. If the code is an action code, the activate
|
||||
// action dispatcher produces side effects. See asdf_activate_action()
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
static void asdf_activate_key(asdf_keycode_t keycode)
|
||||
{
|
||||
if (keycode > ASDF_ACTION) { // ASDF_ACTION = ASDF_NOTHING = no action.
|
||||
asdf_activate_action((action_t) keycode);
|
||||
}
|
||||
else {
|
||||
|
||||
// activate a new codable keypress
|
||||
asdf_put_code(keycode);
|
||||
if (last_key != keycode) {
|
||||
last_key = keycode;
|
||||
asdf_repeat_reset_count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_deactivate_key
|
||||
// INPUTS: keycode - the code for a key that has been released
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Called when a key has been released. If the key is bound to a
|
||||
// value, output the value. If the key is bound to an action, call the deactivate
|
||||
// action handler with the keycode.
|
||||
//
|
||||
// SIDE EFFECTS: If the code is a value, the last key is set to ACTION_NOTHING,
|
||||
// which is effectively a NOP. If the code is an action code, the deactivate action
|
||||
// dispatcher produces side effects. See asdf_deactivate_action()
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
static void asdf_deactivate_key(asdf_keycode_t keycode)
|
||||
{
|
||||
if (keycode > ASDF_ACTION) {
|
||||
asdf_deactivate_action((action_t) keycode);
|
||||
}
|
||||
else {
|
||||
// deactivate a released keypress
|
||||
if (last_key == keycode) {
|
||||
last_key = ACTION_NOTHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_handle_key_press_or_release
|
||||
// INPUTS: row, col: the row and column number of the key that has changed.
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Given a row and column of a key that has changed:
|
||||
//
|
||||
// 1) Debounce the key by decrementing a debounce timer. If not yet debounced,
|
||||
// return.
|
||||
// 2) When the key is debounced, if the key is pressed, then call the activation
|
||||
// function associated with the key. Otherwise, if the key is released, call
|
||||
// the deactivation function for the key.
|
||||
//
|
||||
// SIDE EFFECTS: - Modifies debounce counter for the row and column
|
||||
// - After key debounces, modifies the table of stable key states
|
||||
// - Activate/deactivate functions have side effects
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
static void asdf_handle_key_press_or_release(uint8_t row, uint8_t col, uint8_t key_was_pressed)
|
||||
{
|
||||
uint8_t *debounce_count = &debounce_counters[row][col];
|
||||
|
||||
if (!(--(*debounce_count))) {
|
||||
|
||||
// debounce timed out. Set new stable state and activate or
|
||||
|
||||
// deactivate key.
|
||||
*debounce_count = ASDF_DEBOUNCE_TIME_MS;
|
||||
if (key_was_pressed) {
|
||||
last_stable_key_state[row] |= 1 << col;
|
||||
asdf_activate_key(asdf_lookup_keycode(row, col));
|
||||
}
|
||||
else {
|
||||
// key was released
|
||||
last_stable_key_state[row] &= ~(1 << col);
|
||||
asdf_deactivate_key(asdf_lookup_keycode(row, col));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_handle_key_held_pressed
|
||||
// INPUTS: row, col: The row and column of a key that is being held down
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Given a row and column of a key that has been debounced and
|
||||
// continues to be pressed:
|
||||
// 1) Determine if this is the last key pressed.
|
||||
// 2) If it's the most recent key, then check to see if it's time to repeat the key code.
|
||||
// 3) If it's time to repeat, then do the repeat and reset the repeat timer.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
// - Causes repeat timer to tick, and may reset the repeat timer.
|
||||
// - activate_key() will send a key code.
|
||||
//
|
||||
// NOTES: last_key is always a key code, never an action function, so only valid
|
||||
// key codes will be repeated.
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
static void asdf_handle_key_held_pressed(uint8_t row, uint8_t col)
|
||||
{
|
||||
if (asdf_lookup_keycode(row, col) == last_key) {
|
||||
|
||||
// if last debounced code-producing key is still pressed, handle repeat
|
||||
if (asdf_repeat()) {
|
||||
asdf_activate_key(last_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_keyscan
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Scans the key matrix. For each row, read the columns and compare
|
||||
// with last stable state. For each changed key, call a key-change handler
|
||||
// function. For each stable pressed key, call a "continued press" handler
|
||||
// function.
|
||||
//
|
||||
// SIDE EFFECTS:
|
||||
//
|
||||
// NOTES: 1) The keyboard state is stored as an array of words, with one word
|
||||
// per row, and each bit in a word representing one key in the row.
|
||||
//
|
||||
// 2) While it is tempting to use bit hacks to reduce the number of
|
||||
// cycles through the inner loop, I have opted to just loop over all
|
||||
// the bits (as long as there are some changed or pressed keys). For
|
||||
// an 8-bit word, bit tricks don't deliver much performance boost,
|
||||
// but do decrease code clarity.
|
||||
//
|
||||
// COMPLEXITY: 5
|
||||
//
|
||||
void asdf_keyscan(void)
|
||||
{
|
||||
asdf_cols_t (*row_reader)(uint8_t) = (asdf_cols_t(*)(uint8_t)) asdf_hook_get(ASDF_HOOK_SCANNER);
|
||||
|
||||
asdf_hook_execute(ASDF_HOOK_EACH_SCAN);
|
||||
for (uint8_t row = 0; row < asdf_keymaps_num_rows(); row++) {
|
||||
asdf_cols_t row_key_state = (*row_reader)(row);
|
||||
|
||||
asdf_cols_t changed = row_key_state ^ last_stable_key_state[row];
|
||||
|
||||
// loop over the bits until all changed or pressed keys in the row are handled.
|
||||
for (uint8_t col = 0; /*(changed || row_key_state) && */col < asdf_keymaps_num_cols(); col++) {
|
||||
if (changed & 1) {
|
||||
// key state is different from last stable state
|
||||
asdf_handle_key_press_or_release(row, col, row_key_state & 1);
|
||||
}
|
||||
else if (row_key_state & 1) {
|
||||
asdf_handle_key_held_pressed(row, col);
|
||||
}
|
||||
changed >>= 1;
|
||||
row_key_state >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_apply_all_actions
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Scans the key matrix. For each row, read the columns, and for
|
||||
// each bit, if an action is specified, then call the activate or deactivate
|
||||
// function for that action, based on the key state. This is necessary to ensure
|
||||
// that configuration settings, such as DIP switches and jumper settings, are
|
||||
// properly handled when a keymap is changed.
|
||||
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// COMPLEXITY: 5
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
void asdf_apply_all_actions(void)
|
||||
{
|
||||
asdf_cols_t (*row_reader)(uint8_t) = (asdf_cols_t(*)(uint8_t)) asdf_hook_get(ASDF_HOOK_SCANNER);
|
||||
|
||||
for (uint8_t row = 0; row < asdf_keymaps_num_rows(); row++) {
|
||||
asdf_cols_t row_key_state = (*row_reader)(row);
|
||||
|
||||
// To avoid double actions, assign last stable key state to current state.
|
||||
last_stable_key_state[row] = row_key_state;
|
||||
|
||||
// loop over the bits until all changed or pressed keys in the row are handled.
|
||||
for (uint8_t col = 0; col < asdf_keymaps_num_cols(); col++) {
|
||||
asdf_keycode_t code = asdf_lookup_keycode(row, col);
|
||||
if (row_key_state & 1) {
|
||||
asdf_activate_action(code);
|
||||
} else {
|
||||
asdf_deactivate_action(code);
|
||||
}
|
||||
row_key_state >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Reserve an output buffer to hold keycodes to be sent, and
|
||||
// initialize the keyboard state and debounce counters
|
||||
//
|
||||
// SIDE EFFECTS: see DESCRIPTION
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
void asdf_init(void)
|
||||
{
|
||||
|
||||
last_key = ACTION_NOTHING;
|
||||
|
||||
asdf_buffer_init(); // initialize the buffers
|
||||
asdf_repeat_init(); // initialize the repeat counters
|
||||
asdf_keymaps_init(); // initialize keymaps. This also initializes the modifier
|
||||
// key states.
|
||||
// reserve a buffer for the ASCII output:
|
||||
asdf_keycode_buffer = asdf_buffer_new(ASDF_KEYCODE_BUFFER_SIZE);
|
||||
asdf_message_buffer = asdf_buffer_new(ASDF_MESSAGE_BUFFER_SIZE);
|
||||
|
||||
// Initialize all the keys to the unpressed state, and initialze the debounce
|
||||
// counters.
|
||||
for (uint8_t row = 0; row < ASDF_MAX_ROWS; row++) {
|
||||
last_stable_key_state[row] = 0;
|
||||
for (uint8_t col = 0; col < ASDF_MAX_COLS; col++) {
|
||||
debounce_counters[row][col] = ASDF_DEBOUNCE_TIME_MS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,163 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Universal Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf.h
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_H)
|
||||
#define ASDF_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Define the code at which keyboard actions begin. Codes below this value are
|
||||
// values to be transmitted to the host machine. Codes above this value are
|
||||
// actions to be performed.
|
||||
#define ASDF_ACTION 0xA0 // SOL-20 uses codes 0x80-0x9A
|
||||
|
||||
// an action code is not a valid keycode.
|
||||
#define ASDF_INVALID_CODE ASDF_ACTION
|
||||
|
||||
// define ASDF_MAX_COLS to fit in asdf_cols_t
|
||||
#define ASDF_MAX_COLS 8
|
||||
#define ASDF_MAX_ROWS 16
|
||||
|
||||
// for efficiency on 8-bit machines, use 8 columns per row. For 16 columns per
|
||||
// row, change cols_t to uint16_t and increase ASDF_NUM_COLS to 16.
|
||||
typedef uint8_t asdf_cols_t;
|
||||
|
||||
// ASCII keycodes are 7 bits. An 8-bit datatype encodes ASCII, plus a flag for a
|
||||
// key function. For longer codes, such as extended ASCII or unicode, change
|
||||
// keycode_t appropriately, and also change ASDF_ACTION so that the action key
|
||||
// codes (enumerated in action_t) do not conflict with the encoding scheme.
|
||||
typedef uint8_t asdf_keycode_t;
|
||||
|
||||
|
||||
// This typedef enumerates the valid ACTIONS than can be specified in a keymap.
|
||||
typedef enum {
|
||||
ACTION_NOTHING = ASDF_ACTION,
|
||||
ACTION_SHIFT,
|
||||
ACTION_SHIFTLOCK_ON,
|
||||
ACTION_SHIFTLOCK_TOGGLE,
|
||||
ACTION_CAPS,
|
||||
ACTION_CTRL,
|
||||
ACTION_REPEAT,
|
||||
ACTION_HERE_IS,
|
||||
ACTION_MAPSEL_0,
|
||||
ACTION_MAPSEL_1,
|
||||
ACTION_MAPSEL_2,
|
||||
ACTION_MAPSEL_3,
|
||||
ACTION_AUTOREPEAT_SELECT,
|
||||
ACTION_STROBE_POLARITY_SELECT,
|
||||
ACTION_VLED1,
|
||||
ACTION_VLED2,
|
||||
ACTION_VLED3,
|
||||
ACTION_VOUT1,
|
||||
ACTION_VOUT2,
|
||||
ACTION_VOUT3,
|
||||
ACTION_VOUT4,
|
||||
ACTION_VOUT5,
|
||||
ACTION_VOUT6,
|
||||
ACTION_FN_1,
|
||||
ACTION_FN_2,
|
||||
ACTION_FN_3,
|
||||
ACTION_FN_4,
|
||||
ACTION_FN_5,
|
||||
ACTION_FN_6,
|
||||
ACTION_FN_7,
|
||||
ACTION_FN_8,
|
||||
ACTION_FN_9,
|
||||
ACTION_FN_10,
|
||||
RESERVED_1,
|
||||
RESERVED_2,
|
||||
RESERVED_3,
|
||||
RESERVED_4,
|
||||
RESERVED_5,
|
||||
RESERVED_6,
|
||||
RESERVED_7,
|
||||
RESERVED_8,
|
||||
RESERVED_9,
|
||||
RESERVED_10,
|
||||
RESERVED_11,
|
||||
RESERVED_12,
|
||||
RESERVED_13,
|
||||
RESERVED_14,
|
||||
RESERVED_15,
|
||||
RESERVED_16,
|
||||
} action_t;
|
||||
|
||||
|
||||
// PROCEDURE: asdf_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: initialize the keyboard state and debounce counters
|
||||
void asdf_init(void);
|
||||
|
||||
// PROCEDURE: asdf_keyscan
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Scans the key matrix. For each row, read the columns and compare
|
||||
// with last stable state. For each changed key, call a key-change handler
|
||||
// function. For each stable pressed key, call a "continued press" handler
|
||||
// function.
|
||||
void asdf_keyscan(void);
|
||||
|
||||
// PROCEDURE: asdf_put_code
|
||||
// INPUTS: (asdf_keycode_t) code: code to be buffered for output
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Takes a keycode argument and buffers for output.
|
||||
// NOTES: If buffer is full, silently drop the code.
|
||||
void asdf_put_code(asdf_keycode_t code);
|
||||
|
||||
// PROCEDURE: asdf_putc
|
||||
// INPUTS: (char) c: character to be buffered for output
|
||||
// (FILE*) stream: only for prototype matching
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Takes a character generated by the system and buffers for
|
||||
// output.
|
||||
// NOTES: If buffer is full, silently drop the code.
|
||||
int asdf_putc(char c, FILE *stream);
|
||||
|
||||
// PROCEDURE: asdf_next_code
|
||||
// INPUTS: none
|
||||
// OUTPUTS: (asdf_keycode_t) returns next value in buffer. If both buffers are
|
||||
// empty, the code ASDF_INVALID_CODE is returned.
|
||||
// DESCRIPTION: Checks the message buffer, and returns a character
|
||||
// if present. Otherwise, return the next code in the keycode
|
||||
// buffer.
|
||||
// NOTES: A delay is enforced for system messages, to reduce the risk of dropped
|
||||
// characters with unbuffered polling hosts. No delay is needed for typed
|
||||
// keycodes, as these are generated at human speeds.
|
||||
asdf_keycode_t asdf_next_code(void);
|
||||
|
||||
// PROCEDURE: asdf_set_print_delay
|
||||
// INPUTS: (uint8_t) delay_ms
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: sets the delay to be used by the system print buffer
|
||||
// NOTES: A delay is enforced for system messages, to reduce the risk of dropped
|
||||
// characters with unbuffered polling hosts. No delay is needed for typed
|
||||
// keycodes, as these are generated at human speeds.
|
||||
void asdf_set_print_delay(uint8_t delay_ms);
|
||||
|
||||
#endif // !defined (ASDF_H)
|
||||
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,121 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_ascii.h
|
||||
//
|
||||
// This file contains definitions of ASCII control codes and certain symbols for
|
||||
// keymap definitions. The purpose is to improve readability and consistency of
|
||||
// the keymap matrices, and avoid escaping special characters in the keymap
|
||||
// definitions.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_ASCII_H)
|
||||
#define ASDF_ASCII_H
|
||||
|
||||
// List of all ASCII control codes
|
||||
typedef enum {
|
||||
ASCII_NULL = 0x00,
|
||||
ASCII_CTRL_A = 0x01,
|
||||
ASCII_CTRL_B = 0x02,
|
||||
ASCII_CTRL_C = 0x03,
|
||||
ASCII_CTRL_D = 0x04,
|
||||
ASCII_CTRL_E = 0x05,
|
||||
ASCII_CTRL_F = 0x06,
|
||||
ASCII_CTRL_G = 0x07,
|
||||
ASCII_CTRL_H = 0x08,
|
||||
ASCII_CTRL_I = 0x09,
|
||||
ASCII_CTRL_J = 0x0a,
|
||||
ASCII_CTRL_K = 0x0b,
|
||||
ASCII_CTRL_L = 0x0c,
|
||||
ASCII_CTRL_M = 0x0d,
|
||||
ASCII_CTRL_N = 0x0e,
|
||||
ASCII_CTRL_O = 0x0f,
|
||||
ASCII_CTRL_P = 0x10,
|
||||
ASCII_CTRL_Q = 0x11,
|
||||
ASCII_CTRL_R = 0x12,
|
||||
ASCII_CTRL_S = 0x13,
|
||||
ASCII_CTRL_T = 0x14,
|
||||
ASCII_CTRL_U = 0x15,
|
||||
ASCII_CTRL_V = 0x16,
|
||||
ASCII_CTRL_W = 0x17,
|
||||
ASCII_CTRL_X = 0x18,
|
||||
ASCII_CTRL_Y = 0x19,
|
||||
ASCII_CTRL_Z = 0x1a,
|
||||
ASCII_ESC = 0x1b,
|
||||
ASCII_FS = 0x1c, // File Separator
|
||||
ASCII_GS = 0x1d, // Group Separator
|
||||
ASCII_RS = 0x1e, // Record Separator
|
||||
ASCII_US = 0x1f, // Unit Separator
|
||||
ASCII_SPACE = 0x20,
|
||||
ASCII_DOUBLE_QUOTE = 0x22,
|
||||
ASCII_SINGLE_QUOTE = 0x27,
|
||||
ASCII_LT_PAREN = 0x28,
|
||||
ASCII_RT_PAREN = 0x29,
|
||||
ASCII_COMMA = 0x2C,
|
||||
ASCII_PERIOD = 0x2e,
|
||||
ASCII_ZERO = 0x30,
|
||||
ASCII_AT = 0x40,
|
||||
ASCII_LT_SQUARE_BRACE = 0x5b,
|
||||
ASCII_RT_SQUARE_BRACE = 0x5d,
|
||||
ASCII_UNDERSCORE = 0x5f,
|
||||
ASCII_BACKSLASH = 0x5c,
|
||||
ASCII_GRAVE_ACCENT = 0x60,
|
||||
ASCII_LT_CURLY_BRACE = 0x7b,
|
||||
ASCII_RT_CURLY_BRACE = 0x7d,
|
||||
ASCII_TILDE = 0x7e,
|
||||
ASCII_VERT_BAR = 0x7c,
|
||||
ASCII_DEL = 0x7f
|
||||
} ascii_defs_t;
|
||||
|
||||
#define ASCII_NULL 0
|
||||
#define ASCII_SOH ASCII_CTRL_A // Start of Heading
|
||||
#define ASCII_STX ASCII_CTRL_B // Start of Text
|
||||
#define ASCII_ETX ASCII_CTRL_C // End of Text
|
||||
#define ASCII_EOT ASCII_CTRL_D // End of Transmission
|
||||
#define ASCII_ENQ ASCII_CTRL_E // Enquiry
|
||||
#define ASCII_ACK ASCII_CTRL_F // Acknlowledge
|
||||
#define ASCII_BEL ASCII_CTRL_G // Bell
|
||||
#define ASCII_BS ASCII_CTRL_H // Backspace
|
||||
#define ASCII_TAB ASCII_CTRL_I // Horizontal Tab
|
||||
#define ASCII_LF ASCII_CTRL_J // Line Feed
|
||||
#define ASCII_VT ASCII_CTRL_K // Vertical Tab
|
||||
#define ASCII_FF ASCII_CTRL_L // Form Feed
|
||||
#define ASCII_CR ASCII_CTRL_M // Carriage Return
|
||||
#define ASCII_SO ASCII_CTRL_N // Shift Out
|
||||
#define ASCII_SI ASCII_CTRL_O // Shift In
|
||||
#define ASCII_DLE ASCII_CTRL_P // Data Link Escape
|
||||
#define ASCII_DC1 ASCII_CTRL_Q // Device Control 1
|
||||
#define ASCII_DC2 ASCII_CTRL_R // Device Control 2
|
||||
#define ASCII_DC3 ASCII_CTRL_S // Device Control 3
|
||||
#define ASCII_DC4 ASCII_CTRL_T // Device Control 4
|
||||
#define ASCII_NAK ASCII_CTRL_U // Negative Acknlowledge
|
||||
#define ASCII_SYN ASCII_CTRL_V // Synchronous Idle
|
||||
#define ASCII_ETB ASCII_CTRL_W // End of Transmission Block
|
||||
#define ASCII_CAN ASCII_CTRL_X // Cancel
|
||||
#define ASCII_EM ASCII_CTRL_Y // End of Medium
|
||||
#define ASCII_SUB ASCII_CTRL_Z // Substitute
|
||||
#define ASCII_ESC 0x1b
|
||||
|
||||
|
||||
#define ASCII_
|
||||
#endif // !defined (ASDF_ASCII_H)
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,205 +0,0 @@
|
|||
// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_buffer.c
|
||||
//
|
||||
// This is a circular buffer module that can be used by any part of the code
|
||||
// that requires buffering. Buffering provides an interface between the
|
||||
// generation of keycodes and the hardware-level keycode transmission, which may
|
||||
// occur at different rates.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "asdf.h"
|
||||
#include "asdf_buffer.h"
|
||||
|
||||
// Implementation Notes:
|
||||
//
|
||||
// 1) Note that this implementation does not support dynamic allocation and
|
||||
// freeing of buffers. Each buffer is allocated at startup and is stable forever
|
||||
// afterwards.
|
||||
//
|
||||
// 2) Buffer handles are indices into an array of buffer-tracking structures.
|
||||
// Using indices rather than pointers incurs a small performance penalty for the
|
||||
// extra level of indirection, but affords the advantage of testing the buffer
|
||||
// handle for validity.
|
||||
|
||||
|
||||
// Define the low-level details for each buffer.
|
||||
typedef struct {
|
||||
asdf_keycode_t *buf;
|
||||
int16_t size;
|
||||
uint8_t head;
|
||||
uint8_t tail;
|
||||
uint8_t count;
|
||||
} asdf_buffer_t;
|
||||
|
||||
// This is the pool of codes available for buffering. This pool is divided among
|
||||
// the allocated buffers.
|
||||
static asdf_keycode_t buffer_pool[ASDF_BUFFER_POOL_SIZE];
|
||||
|
||||
// This array stores the buffering details for each allocated buffer. The number
|
||||
// of available buffers is defined in the header file.
|
||||
static asdf_buffer_t buffers[ASDF_BUFFER_NUM_HANDLES];
|
||||
|
||||
// Index of the beginning of unallocated part of the buffer pool.
|
||||
static int16_t buffer_pool_next_available;
|
||||
|
||||
// Index of the next available buffer handle
|
||||
static asdf_buffer_handle_t next_handle;
|
||||
|
||||
|
||||
// PROCEDURE: asdf_buffer_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
//
|
||||
// DESCRIPTION: Initialize the buffer pool and handles
|
||||
//
|
||||
// SIDE EFFECTS: See description
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
void asdf_buffer_init(void)
|
||||
{
|
||||
buffer_pool_next_available = 0;
|
||||
next_handle = 0;
|
||||
}
|
||||
|
||||
// PROCEDURE: buffer_handle_valid
|
||||
// INPUTS: (uint8_t) handle - handle to be checked
|
||||
// OUTPUTS: returns TRUE if the handle is a valid allocated handle.
|
||||
//
|
||||
// DESCRIPTION: Returns TRUE if the handle is one that has been allocated.
|
||||
//
|
||||
// SIDE EFFECTS: none
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// SCOPE: private
|
||||
//
|
||||
// COMPLEXITY: 1
|
||||
//
|
||||
uint8_t buffer_handle_valid(asdf_buffer_handle_t handle)
|
||||
{
|
||||
return ((handle >= 0) && (handle < next_handle));
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_buffer_new
|
||||
// INPUTS: (uint16_t) size: size of the buffer to allocate.
|
||||
//
|
||||
// OUTPUTS: returns a uint8_t handle to identify the buffer allocated from the
|
||||
// pool.
|
||||
//
|
||||
// DESCRIPTION: Receives a request to allocate a fixed-size buffer from the
|
||||
// pool. If there is enough room in the buffer pool, and if a buffer handle is
|
||||
// available, then allocate space from the pool, initialize the next available
|
||||
// buffer struct, and return the handle.
|
||||
//
|
||||
// SIDE EFFECTS: see above
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
asdf_buffer_handle_t asdf_buffer_new(int16_t size)
|
||||
{
|
||||
asdf_buffer_handle_t handle = ASDF_BUFFER_INVALID;
|
||||
|
||||
if (next_handle < ASDF_BUFFER_NUM_HANDLES) {
|
||||
if (size <= (ASDF_BUFFER_POOL_SIZE - buffer_pool_next_available)) {
|
||||
handle = next_handle++;
|
||||
|
||||
buffers[handle].size = size;
|
||||
buffers[handle].buf = &buffer_pool[buffer_pool_next_available];
|
||||
buffers[handle].head = 0;
|
||||
buffers[handle].tail = 0;
|
||||
buffers[handle].count = 0;
|
||||
|
||||
buffer_pool_next_available += size;
|
||||
}
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
// PROCEDURE: asdf_buffer_put
|
||||
//
|
||||
// INPUTS:(asdf_buffer_t) buffer_handle: pointer to the buffer struct.
|
||||
// (asdf_keycode_t) code: code to be added to the queue.
|
||||
//
|
||||
// OUTPUTS: None
|
||||
//
|
||||
// DESCRIPTION: Add the keycode to the head of the output buffer. If the buffer
|
||||
// is full, quietly drop the keycode.
|
||||
//
|
||||
// SIDE EFFECTS: See DESCRIPTION
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// COMPLEXITY: 3
|
||||
//
|
||||
// SCOPE: public
|
||||
//
|
||||
void asdf_buffer_put(asdf_buffer_handle_t handle, asdf_keycode_t code)
|
||||
{
|
||||
if (buffer_handle_valid(handle)) {
|
||||
if (buffers[handle].count < buffers[handle].size) {
|
||||
buffers[handle].buf[buffers[handle].head] = code;
|
||||
buffers[handle].head = (buffers[handle].head + 1) % buffers[handle].size;
|
||||
buffers[handle].count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROCEDURE: asdf_buffer_get
|
||||
//
|
||||
// INPUTS: None
|
||||
//
|
||||
// OUTPUTS: returns next code in the buffer.
|
||||
//
|
||||
// DESCRIPTION: Gets the next queued code in the output buffer and return the
|
||||
// value.
|
||||
//
|
||||
// SIDE EFFECTS: Removes a code from the queue.
|
||||
//
|
||||
// NOTES: If the buffer is empty, the code ASDF_INVALID_CODE is returned.
|
||||
//
|
||||
// COMPLEXITY: 2
|
||||
//
|
||||
// SCOPE: Public
|
||||
//
|
||||
asdf_keycode_t asdf_buffer_get(asdf_buffer_handle_t handle)
|
||||
{
|
||||
asdf_keycode_t code = ASDF_INVALID_CODE;
|
||||
if (buffer_handle_valid(handle) && buffers[handle].count) {
|
||||
code = buffers[handle].buf[buffers[handle].tail];
|
||||
buffers[handle].tail = (buffers[handle].tail + 1) % buffers[handle].size;
|
||||
buffers[handle].count--;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,78 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Unified Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_buffer.h
|
||||
//
|
||||
// Contains definitions and prototypes for the asdf keycode output buffer.
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined(ASDF_BUFFER_H)
|
||||
#define ASDF_BUFFER_H
|
||||
|
||||
// ASDF_BUFFER_POOL_SIZE is defined in asdf_config.h
|
||||
#include "asdf_config.h"
|
||||
|
||||
// Used to designate an invalid buffer.
|
||||
#define ASDF_BUFFER_INVALID -1
|
||||
|
||||
// Setting the number of handles to 1 will work if only one buffer is requrired,
|
||||
// and will save a few bytes of RAM. But the test code needs at least 2 buffer
|
||||
// handles to test the module, so we leave it at 2.
|
||||
#define ASDF_BUFFER_NUM_HANDLES 4
|
||||
|
||||
|
||||
// The buffer handle type should be able to handle the expected number of buffers.
|
||||
typedef int8_t asdf_buffer_handle_t;
|
||||
|
||||
// PROCEDURE: asdf_buffer_init
|
||||
// INPUTS: none
|
||||
// OUTPUTS: none
|
||||
// DESCRIPTION: Initialize the buffer pool and handles
|
||||
void asdf_buffer_init(void);
|
||||
|
||||
// PROCEDURE: asdf_buffer_new
|
||||
// INPUTS: (uint16_t) size: size of the buffer to allocate.
|
||||
// OUTPUTS: returns (asdf_buffer_handle_t) handle to identify the buffer allocated from the
|
||||
// pool.
|
||||
// DESCRIPTION: Receives a request to allocate a fixed-size buffer from the
|
||||
// pool. If there is enough room in the buffer pool, and if a buffer handle is
|
||||
// available, then allocate space from the pool, initialize the next available
|
||||
// buffer struct, and return the handle.
|
||||
asdf_buffer_handle_t asdf_buffer_new(int16_t size);
|
||||
|
||||
// PROCEDURE: asdf_buffer_put
|
||||
// INPUTS:(asdf_buffer_t) buffer_handle: pointer to the buffer struct.
|
||||
// (asdf_keycode_t) code: code to be added to the queue.
|
||||
// OUTPUTS: None
|
||||
// DESCRIPTION: Add the keycode to the head of the output buffer. If the buffer
|
||||
// is full, quietly drop the keycode.
|
||||
void asdf_buffer_put(asdf_buffer_handle_t handle, asdf_keycode_t code);
|
||||
|
||||
// PROCEDURE: asdf_buffer_get
|
||||
// INPUTS: None
|
||||
// OUTPUTS: returns next code in the buffer.
|
||||
// DESCRIPTION: Gets the next queued code in the output buffer and return the
|
||||
// value.
|
||||
asdf_keycode_t asdf_buffer_get(asdf_buffer_handle_t handle);
|
||||
|
||||
#endif // !defined (ASDF_BUFFER_H)
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
|
@ -1,89 +0,0 @@
|
|||
// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// Universal Keyboard Project
|
||||
// ASDF keyboard firmware
|
||||
//
|
||||
// asdf_config.h
|
||||
//
|
||||
// This file gathers configuration parameters related to the user-detectable
|
||||
// keyboard experience. For example, put key debounce times, repeat rates,
|
||||
// buffer sized, baud rates, etc. here. Details such as processor clock speed,
|
||||
// etc. should go in the architecture-dependent files. System details such as
|
||||
// number of buffer handles, etc. should go with the appropriate module, but
|
||||
// certain buffer sized may go here if they can affect the user experience (such
|
||||
// as how long a macro can be).
|
||||
//
|
||||
// Copyright 2019 David Fenyes
|
||||
// This program is free software: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#if !defined(CONFIG_H)
|
||||
#define CONFIG_H
|
||||
|
||||
#define ASDF_POSITIVE_POLARITY 0
|
||||
#define ASDF_NEGATIVE_POLARITY (~ASDF_POSITIVE_POLARITY)
|
||||
|
||||
// data polarity is positive (inactive is low, active is high)
|
||||
#define ASDF_DEFAULT_DATA_POLARITY ASDF_POSITIVE_POLARITY
|
||||
|
||||
// Strobe polarity is positive (inactive is low, active is high)
|
||||
#define ASDF_DEFAULT_STROBE_POLARITY ASDF_POSITIVE_POLARITY
|
||||
|
||||
// RESET output polarity is negative (inactive is high, active is low)
|
||||
#define ASDF_DEFAULT_RESET_POLARITY ASDF_NEGATIVE_POLARITY
|
||||
|
||||
// SCREEN_CLEAR output polarity is positive (inactive is low, active is high)
|
||||
#define ASDF_DEFAULT_SCREEN_CLEAR_POLARITY ASDF_POSITIVE_POLARITY
|
||||
|
||||
|
||||
// Data structure sizes:
|
||||
|
||||
// size of the keycode output buffer.
|
||||
#define ASDF_KEYCODE_BUFFER_SIZE 16
|
||||
|
||||
#define ASDF_MESSAGE_BUFFER_SIZE 128
|
||||
|
||||
#define ASDF_BUFFER_POOL_SIZE (ASDF_MESSAGE_BUFFER_SIZE + ASDF_KEYCODE_BUFFER_SIZE)
|
||||
|
||||
// key debounce period (in msec)
|
||||
#define ASDF_DEBOUNCE_TIME_MS 10
|
||||
|
||||
// Autorepeat default behavior. Set to REPEAT_AUTO for default autorepeat.
|
||||
// Set to REPEAT_OFF for default no autorepeat by default.
|
||||
#define ASDF_DEFAULT_REPEAT_STATE REPEAT_AUTO
|
||||
|
||||
// time to wait before sending consecutive message characters to the host, to
|
||||
// ensure that messages are intact on hosts that poll the port without
|
||||
// buffering. (in msec)
|
||||
#define ASDF_MESSAGE_CHARACTER_DELAY 16 //msec
|
||||
|
||||
// time to hold down a key in milliseconds before autorepeat starts
|
||||
#define ASDF_AUTOREPEAT_TIME_MS 525 // 525 msec.
|
||||
|
||||
// time between repeats of a character with repeat key held, or in autorepeat (milliseconds)
|
||||
#define ASDF_REPEAT_TIME_MS (1000 / 15) // l5 characters per sec.
|
||||
|
||||
// duration of keyboard output pulses (RESET, SCREEN CLEAR, BREAK, etc.)
|
||||
#define ASDF_PULSE_DELAY_SHORT_US 10
|
||||
|
||||
// duration of keyboard output pulses (RESET, SCREEN CLEAR, BREAK, etc.)
|
||||
#define ASDF_PULSE_DELAY_LONG_MS 50
|
||||
|
||||
// DEFAULT value of keyboard outputs
|
||||
#define ASDF_VIRTUAL_OUT_DEFAULT_VALUE 1 // High if not used.
|
||||
|
||||
#endif /* !defined (CONFIG_H) */
|
||||
|
||||
//-------|---------|---------+---------+---------+---------+---------+---------+
|
||||
// Above line is 80 columns, and should display completely in the editor.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue