Compare commits

...

1065 Commits

Author SHA1 Message Date
Pascal Langer
f3838ae4b0 Prepare for release of a stable version 2017-12-20 12:48:53 +01:00
Ben Lye
b3eccf55ba Multi Module Board Definition Updates (#133) 2017-12-20 11:31:20 +00:00
Pascal Langer
835cc3d0a2 Removed some dependencies to the SPI library 2017-12-19 22:44:20 +01:00
Ben Lye
b49584ec16 Add force tuning setting for CC2500 protocols (#124) 2017-12-19 20:14:49 +01:00
Pascal Langer
334e49c4ca STM32 final timer fix 2017-12-19 14:27:39 +01:00
Pascal Langer
3fc5be111b STM32 fix timer issues 2017-12-18 21:10:21 +01:00
Arne Schwabe
1bc2dd2964 Fix multi status (#132) 2017-12-18 16:45:09 +01:00
Ben Lye
68dcc75949 Roll back to older STM32 core files (#128) 2017-12-17 00:44:29 +00:00
Pascal Langer
dc9f738f30 STM32 timer hack 2017-12-17 01:13:43 +01:00
Ben Lye
4171d2f93b Fix board definitions version script to handle spaces in the paths (#127) 2017-12-16 19:14:32 +00:00
Arne Schwabe
64fb90960b Fix Sport polling bytes send without multi header and introduce sport polling header for multi (#126) 2017-12-16 09:14:59 +01:00
Pascal Langer
93e277bb0f Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-12-15 17:31:28 +01:00
Pascal Langer
337216efac Fix for STM32 2017-12-15 17:31:25 +01:00
pascallanger
f1f5b68821 Update Troubleshooting.md 2017-12-14 23:08:33 +01:00
pascallanger
8f941e6d12 Update Troubleshooting.md 2017-12-14 23:08:14 +01:00
pascallanger
6a4dcbd6e1 Update Troubleshooting.md 2017-12-13 15:43:28 +01:00
Ben Lye
7e773dfe1b Doc updates for OrangeRX module (#123) 2017-12-12 20:20:42 +00:00
pascallanger
465ae75ffc Update Protocols_Details.md 2017-12-12 20:37:54 +01:00
Pascal Langer
8da03940e8 OrangeRX TX modifications 2017-12-12 10:19:50 +01:00
pascallanger
f280779528 Typo 2017-12-12 08:33:07 +01:00
Ben Lye
5c568da125 Board Definition Updates (#121) 2017-12-11 20:55:24 +00:00
Pascal Langer
f46b8366b0 Small mods 2017-12-11 18:49:50 +01:00
Pascal Langer
1d9c052c01 FrSkyX failsafe 2017-12-11 13:33:42 +01:00
Pascal Langer
544927b9b7 Fix typos 2017-12-11 13:00:08 +01:00
Pascal Langer
8b5bb0d358 Fix compilation errors based on config def 2017-12-10 15:41:50 +01:00
Pascal Langer
6031f1e3b8 FrSkyX failsafe 2017-12-10 11:04:03 +01:00
Ben Lye
c297df76ef Update Compiling_STM32.md
Added IRX4 images and a note about the need to burn the USB bootloader on Banggood modules.
2017-12-10 09:07:54 +00:00
Ben Lye
122e9f4fca Add IRX4 boot0 image 2017-12-10 09:05:50 +00:00
Ben Lye
748ed01252 Add IRX programmer image 2017-12-10 08:54:44 +00:00
Pascal Langer
56188328fb Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-12-10 09:48:24 +01:00
Pascal Langer
880e463b01 FrSkyX failsafe 2017-12-10 09:48:20 +01:00
Ben Lye
a53046bf12 Update Compiling_STM32.md 2017-12-09 10:20:29 +00:00
Ben Lye
a8050fd8a1 Doc Updates for STM32 (#120)
* Update Compiling_STM32.md
* Add images
2017-12-09 10:12:23 +00:00
Pascal Langer
6ae819e8d5 Failsafe 2017-12-08 19:41:58 +01:00
Pascal Langer
79c73444ab Failsafe 2017-12-07 21:42:23 +01:00
Pascal Langer
8cc1b07456 Failsafe version 2017-12-07 18:16:16 +01:00
Pascal Langer
0d43614ac3 Failsafe 2017-12-07 17:38:06 +01:00
Pascal Langer
19f879da7f Failsafe 2017-12-07 17:28:01 +01:00
Pascal Langer
ed42bf311f Failsafe 2017-12-07 17:14:14 +01:00
Pascal Langer
fd4346cb64 Changed throttle failsafe value format 2017-12-07 17:02:35 +01:00
Pascal Langer
6e458ebd4a Disable _MyConfig by default 2017-12-07 16:06:45 +01:00
Pascal Langer
0f0be60245 remove _MyConfig.h... 2017-12-07 16:04:59 +01:00
Pascal Langer
27783677c2 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-12-07 16:02:21 +01:00
Pascal Langer
4418cab3a5 Failsafe: default for PPM and set on radio for Serial 2017-12-07 16:02:18 +01:00
Ben Lye
b3cddfe2d4 Update Validate.h (#119)
Add `#undef` for new  esky150 and H8_3D protocols if `NRF24L01_INSTALLED` is not defined.
2017-12-07 15:40:59 +01:00
pascallanger
a19ac87a04 Update README.md 2017-12-07 08:57:35 +01:00
pascallanger
3ba951fd91 Update README.md 2017-12-07 08:54:12 +01:00
pascallanger
824f23c3d6 Update Transmitters.md 2017-12-07 08:47:35 +01:00
Ben Lye
fc49a32008 Documentation updates (#118) 2017-12-06 19:58:22 +00:00
Ben Lye
5ca0d31606 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module into benlye-multi-new 2017-12-06 12:47:46 +00:00
Pascal Langer
ebd44d9628 Sport polling fix 2017-12-02 11:54:15 +01:00
Ben Lye
329fa1c2a5 Enable USE_MY_CONFIG 2017-12-01 19:13:32 +00:00
Ben Lye
9a5bf7999b Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-12-01 17:21:41 +00:00
Pascal Langer
7debad6c67 SPORT polling 2017-12-01 17:55:24 +01:00
Pascal Langer
dc9b84ea8b _MyConfig.h 2017-12-01 16:46:42 +01:00
Pascal Langer
199c254838 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-12-01 15:02:29 +01:00
Pascal Langer
7ff482dafe Rates in Bayang and MJXQ 2017-12-01 15:02:24 +01:00
pascallanger
9376019198 Update README.md 2017-12-01 14:19:19 +01:00
Dennis
cec654a75b Update Protocol Details for CABELL protocol (#117)
* Added CABELL Protocol

* Added additional disclaimer to license.

* Revert "Added additional disclaimer to license."

This reverts commit a00bc9956a.

* Added additional disclaimer

* Added CABELL_NRF24L01_INO define to config

* Updated available protocol list

Added CABELL protocol

* Removed unused variables

* Changed changel range to 45 channels that comply with USA FCC part 97 rules.

This change allows licenced HAMs to operate under part 97 rules instead
of part 15.  These channels are still in the ISM band, but overlap with
the part 97 amateur portion of the band.

* Changed protocol number to 33

Was previously 30, but the main branch has now allocated up to 32, so
changing to 33

* Corrected permutation calculation

* Added sub-protocol for setting failsafe values

* Opened up a free bit in the option byte for future use

* Fixed packet errors when trying to unbind when in bind mode

This use case didn't really make any sense, but it should not cause
packet errors, so fixed it.

* RSSI Telemetry for CABELL protocol

* Pins back to stock configuration

* Split checksum into MSB and LSB fields to avoid endian issue

* struct change for checksum

* Added analog values to telemetry packet that could be used for LIPO voltage

* Added MODE_CABELL to frsk_link_frame

* Updated packet layout comments

* Fixed telemetry conditional compiles in CABELL protocol

* Telemetry working; moved power override bit

* Changed telemetry to 250 kbps and adjustable packet period - imporves reliability/range

* Changed CABELL protocol number to 34

* Fixed typos in comments

* Fix ATMEGA BASH_SERIAL buffer overrun

Changed the compare to TXBUFFER_SIZE to >=
If next wasn't set to zero until > TXBUFFER_SIZE then the next time the
routines get called the the array index references outside the buffer
(e.g tail+1)

* Revert "Fix ATMEGA BASH_SERIAL buffer overrun"

This reverts commit ba4526ee89.

* Updated documentation for CABELL V3 Protocol

* Updated Documentation for the CABELL V3 Protocol
2017-12-01 14:13:06 +01:00
Pascal Langer
e10dc6dcec Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-30 20:12:27 +01:00
Pascal Langer
e4f4d278a8 Hubsan protocol
Added subprotocol H107 (0)
Added subprotocol H301 (1)
Added subprotocol H501 (2)
2017-11-30 20:12:23 +01:00
Ben Lye
3dd9df558e Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-30 13:07:38 +00:00
pascallanger
87c2216d0f Update Advanced_Topics.md 2017-11-30 14:01:37 +01:00
pascallanger
8cd5ff6bd6 Update Advanced_Topics.md 2017-11-30 14:00:44 +01:00
Pascal Langer
28868e4c78 _MyConfig.h 2017-11-30 13:00:10 +01:00
Pascal Langer
01bef23ac9 CG023 & H8_3D protocols
- Removed sub_protcol H8_3D under protocol CG023
 - Added protocol H8_3D (36)
 - Added sub_protocols H8_3D/H8_3D (0)
 - Added sub_protocols H8_3D/H20H (1)
 - Added sub_protocols H8_3D/H20Mini (2)
 - Added sub_protocols H8_3D/H30Mini (3)
2017-11-29 14:13:12 +01:00
pascallanger
9379bd1792 Update Compiling_STM32.md 2017-11-29 10:30:11 +01:00
Ben Lye
63a479b6b6 Update Compiling_STM32.md
Fix typos and links
2017-11-28 22:19:26 +00:00
Ben Lye
49b0d92c75 Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-28 21:44:07 +00:00
Ben Lye
277402a25d Update STM32 documentation for Boards Definition (#116)
Updating the compiling for STM32 documentation to take advantage of the boards definition.
2017-11-28 20:56:42 +00:00
Pascal Langer
cc83177542 Protocol DM002: add 1 more TX ID/RF set
Total of 3 known TX IDs & RFs sets.
2017-11-28 17:24:24 +01:00
Pascal Langer
5a342cf8e6 Protocol Bayang: new subprotocol IRDRONE
Protocol Bayang (14)
new subprotocol IRDRONE (3)
2017-11-28 17:17:02 +01:00
Ben Lye
7d5dabde82 Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-28 14:17:03 +00:00
pascallanger
e3917226cc Merge pull request #115 from benlye/flash-method-warning
Warn if CHECK_FOR_BOOTLOADER is enabled but a NO_BOOT board is selected
2017-11-28 13:58:47 +01:00
Ben Lye
4e3c1edd52 Add error if CHECK_FOR_BOOTLOADER is not enabled but 'Flash from TX' is
Error rather than silently enabling CHECK_FOR_BOOTLOADER.
2017-11-28 10:13:52 +00:00
Ben Lye
e52b7ea7ff Warn if CHECK_FOR_BOOTLOADER is enabled but a NO_BOOT board is selected
Rather than silently disabling CHECK_FOR_BOOTLOADER  lets throw an error
prompting the user to make the correct selection.
2017-11-28 09:21:03 +00:00
pascallanger
6f60d87f85 Corrected files url 2017-11-28 08:56:08 +01:00
pascallanger
049db615e3 Merge pull request #114 from benlye/stm32-board-1
Initial check-in for STM32 board
2017-11-28 08:40:32 +01:00
Ben Lye
e557155b17 Initial check-in for STM32 board 2017-11-27 21:19:49 +00:00
Pascal Langer
9bf5b0c9a7 ESKY 150: new protocol
New protocol number 35
No sub protocols
option=0->4 channels, option=1->7 channels
2017-11-27 11:20:57 +01:00
Pascal Langer
ea860f24a1 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-26 22:07:37 +01:00
Pascal Langer
5e89d49bd9 Serial debug 2017-11-26 22:07:34 +01:00
pascallanger
cb1ba0e00c Update Compiling_STM32.md 2017-11-26 21:51:40 +01:00
pascallanger
0f965b6800 Update Compiling_STM32.md 2017-11-26 21:49:29 +01:00
pascallanger
486c2170cd Update Compiling_STM32.md 2017-11-26 21:49:02 +01:00
pascallanger
83641a4f54 Update Compiling_STM32.md 2017-11-26 21:45:17 +01:00
Pascal Langer
5cb2326ea7 Using Serial for debug 2017-11-26 20:58:36 +01:00
Pascal Langer
84d7986353 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-26 20:38:38 +01:00
Pascal Langer
a3c2628359 Replaced debug serial routines 2017-11-26 20:38:30 +01:00
pascallanger
8ae34bdd9d Update Compiling_STM32.md 2017-11-26 20:30:54 +01:00
Ben Lye
4a9374936d Re-enable MJXQ 2017-11-26 15:00:58 +00:00
Pascal Langer
110378e3b4 Cabell protocol change 2017-11-26 15:36:33 +01:00
Ben Lye
bd60feff60 Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-26 12:45:20 +00:00
Pascal Langer
2181d0b33c Final bit bashing fix? 2017-11-26 08:41:55 +01:00
Ben Lye
2afa7ea691 Merge pull request #112 from benlye/update-avr-board
Update Atmega328 board definition
2017-11-25 22:00:20 +00:00
Ben Lye
d0f76117cd Update Atmega328 board definition
- Tweak to AVR board menu entry
- Exported binary will be named 'multifw.hex'
- Updated zip and JSON files
2017-11-25 21:58:57 +00:00
Ben Lye
e25060a16e Update Compiling.md
Made it clear that burning bootloader etc. isn't needed after the first upload.
2017-11-25 21:30:33 +00:00
Ben Lye
5e6da326f6 Merge pull request #111 from pascallanger/benlye-doc-updates-1
Documentation updates
2017-11-25 20:52:42 +00:00
Ben Lye
981a8f8d2c Create Flash_from_Tx.md 2017-11-25 20:50:25 +00:00
Ben Lye
5c7e592e1e Update Compiling.md 2017-11-25 20:49:09 +00:00
Pascal Langer
2a25f76b56 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-25 09:32:03 +01:00
Pascal Langer
41d579dc23 Invert serial atmega bug correction 2017-11-25 09:32:00 +01:00
Pascal Langer
7d41017850 Updates
Implemented debug output on uart1 for stm32
Replaced hardcoded eeprom offsets with documented constats
Fixed a bug affecting telemetry on Atmega328p using the invert_telemetry flag.
2017-11-24 23:01:47 +01:00
pascallanger
daeba0d43a Update Compiling_STM32.md 2017-11-24 19:50:36 +01:00
Pascal Langer
24fd5ba361 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-24 13:39:54 +01:00
Pascal Langer
3353637c8f S-FHSS update 2017-11-24 13:39:50 +01:00
pascallanger
9601e6942d Merge pull request #91 from ScottJD/patch-1
Update BOM_DIY_STM32 & Schematic.md
2017-11-23 19:27:21 +01:00
pascallanger
4b32a93f27 Update Protocols_Details.md 2017-11-23 18:49:21 +01:00
Pascal Langer
9e8978166e New CABELL protocol
Protocol number: 34
sub_protocols:
0 CABELL_V3
1 CABELL_V3_TELEMETRY
6 CABELL_SET_FAIL_SAFE
7 CABELL_UNBIND
2017-11-23 18:44:31 +01:00
Pascal Langer
6bf873f4db timing 2017-11-23 15:53:15 +01:00
Pascal Langer
1318f1a29b S-FHSS failsafe again... 2017-11-23 15:51:07 +01:00
Pascal Langer
d9282ac750 Boards correction 2017-11-22 18:04:40 +01:00
Pascal Langer
205d728798 S-FHSS Failsafe: SFHSS_FAILSAFE_THROTTLE 2017-11-22 15:21:36 +01:00
Pascal Langer
bd9c772a52 S-FHSS: fix failsafe 2017-11-22 14:51:45 +01:00
Pascal Langer
76e9002995 S-FHSS failsafe 2017-11-22 13:56:42 +01:00
Ben Lye
e990d44bb6 Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-22 08:04:38 +00:00
pascallanger
2ffa2d7b73 Update Protocols_Details.md 2017-11-21 22:03:28 +01:00
pascallanger
0e4583f8e2 Update Protocols_Details.md 2017-11-21 21:47:08 +01:00
Pascal Langer
3802722bb1 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-21 21:45:12 +01:00
Pascal Langer
41f0a712fd S-FHSS improvements 2017-11-21 21:45:03 +01:00
pascallanger
4633c37380 Update Models.md 2017-11-21 17:22:20 +01:00
Ben Lye
b779becf8c Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new 2017-11-20 21:54:49 +00:00
Pascal Langer
35089febab SFHSS subprotocols 2017-11-20 22:02:14 +01:00
Pascal Langer
a95fd1e1d8 SFHSS sub protocols 2017-11-20 21:58:01 +01:00
Pascal Langer
6535f64699 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-20 19:12:40 +01:00
Pascal Langer
b15a5d4a45 Flysky and Assan output map 2017-11-20 19:12:37 +01:00
pascallanger
65a5c37ffb Update Compiling_STM32.md 2017-11-20 18:26:46 +01:00
Pascal Langer
6cf58c032c Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-11-20 18:24:31 +01:00
Pascal Langer
e0365df6dd StmMultiUSB bootloader 2017-11-20 18:24:28 +01:00
Ben Lye
40ae0c7257 Add my configuration 2017-11-20 16:34:57 +00:00
pascallanger
aecd4c5266 Update Compiling_STM32.md 2017-11-20 17:18:48 +01:00
Pascal Langer
113caf4970 AVR Boards: auto bootloader setting 2017-11-20 17:04:38 +01:00
Pascal Langer
da2d57c8e9 AVR Boards 2017-11-20 16:52:30 +01:00
Pascal Langer
3aed8b8479 json 2017-11-20 16:27:23 +01:00
pascallanger
ff58a826b1 Delete package_multi_4in1_board_v1.0.0.zip 2017-11-20 16:21:38 +01:00
pascallanger
9a0873e404 Update package_multi_4in1_board_index.json 2017-11-20 16:18:41 +01:00
pascallanger
7d9133793c Update package_multi_4in1_board_index.json 2017-11-20 16:08:23 +01:00
pascallanger
f43d9883cf Update package_multi_4in1_board_index.json 2017-11-20 16:07:02 +01:00
pascallanger
067842818e Update README.md 2017-11-20 16:04:56 +01:00
Pascal Langer
8ea70a1b77 Tons of updates 2017-11-20 16:01:12 +01:00
pascallanger
47207dcead Delete Compiling_STM32.md 2017-11-20 15:58:19 +01:00
pascallanger
235876a4d8 Delete Models.md 2017-11-20 15:58:06 +01:00
pascallanger
af88abb13f Delete FrSkyX_cc2500.ino 2017-11-20 15:53:00 +01:00
pascallanger
dd3f8b4717 Merge pull request #92 from hexfet/frskyx_seq
Improve FrskyX extended telemetry error recovery
2017-07-23 10:07:08 +02:00
hexfet
a1fb4a0ac5 Revert terminating newline. 2017-07-22 22:41:34 -04:00
hexfet
ebf0c4fae6 Change spaces to tabs. 2017-07-22 22:39:26 -04:00
hexfet
44a086a27b Revert terminating newline. 2017-07-22 22:35:43 -04:00
hexfet
4624075112 Update sequence number logic to send invalid sequence indicator when invalid sequence detected. Works to resync telemetry stream as tested with EU firmware version. 2017-07-22 22:07:42 -04:00
midelic
97a3c8dca1 added more info on flashing USB module. 2017-07-01 15:52:34 +01:00
ScottJD
c50b5d93d7 Update BOM_DIY_STM32 & Schematic.md
Added Digi-Key shared carts for latest build BOM. 
Need to confirm if SV202,SV203, and SV204 each need a strip of 40 header pins for a total of 120 pins as currently since each S1011EC-40-ND part has 40  pins?
2017-06-27 17:58:43 -04:00
midelic
08f9176f3f Update Compiling_STM32.md 2017-06-27 13:00:38 +01:00
midelic
f95ca6eac6 info on compiling firmware for USB version 2017-06-27 11:42:32 +01:00
pascallanger
34165c0d90 Merge pull request #88 from LapinFou/patch-1
Fixed broken link
2017-06-16 14:26:38 +02:00
pascallanger
1f87cf09d7 Merge pull request #89 from LapinFou/patch-2
Fixed broken link
2017-06-16 14:26:20 +02:00
Sebastien Charpentier
005c7b9cb0 Typo 2017-06-16 14:25:32 +02:00
Sebastien Charpentier
2b265bd1de Fixed broken link
Fixed broken link. Bad idea to use space and ampersand... ;)
2017-06-16 14:24:33 +02:00
Sebastien Charpentier
3e83216384 Fixed broken link
A extra space was breaking the link to the Hardware.md file.
2017-06-16 14:01:20 +02:00
pascallanger
a9889b5b79 Merge pull request #84 from schwabe/patch-5
Remove paragraph resulting from the 125% bug in earlier OpenTX versions
2017-05-02 18:03:24 +02:00
Arne Schwabe
2aa5b7917f Remove paragraph resulting from the 125% bug in earlier OpenTX versions 2017-05-02 17:28:49 +02:00
pascallanger
bd46f6d25f Merge pull request #83 from LapinFou/master
More fixes in the documentation.
2017-04-20 13:46:37 +02:00
Sebastien Charpentier
7e801269af Update Protocol_Details_old.md
Fixed MarkDown.
2017-04-19 21:24:42 +02:00
Sebastien Charpentier
2586e2e661 Update Documentation_To_Do_List.md
Fixed MarkDown
2017-04-19 21:19:57 +02:00
Sebastien Charpentier
fb2a5c2378 Update Tx-erSky9X.md
Fixed MarkDown and broken links.
2017-04-19 21:16:36 +02:00
Sebastien Charpentier
f490fa6e7d Update Tx-FlyskyTH9X.md
Fixed broken link & MarkDown sections.
2017-04-19 21:14:41 +02:00
Sebastien Charpentier
df347be672 Update Bind_Timing.md
MarkDown correction.
2017-04-19 21:10:19 +02:00
Sebastien Charpentier
4e518bf70c Update Tx-Taranis.md
Corrected explanation.
2017-04-19 21:09:29 +02:00
Sebastien Charpentier
29e90246d2 Update Tx-Taranis.md
Fixed list and pictures alignment.
2017-04-19 21:07:14 +02:00
Sebastien Charpentier
1e62c0d836 Update Compiling.md
Fixed broken link.
2017-04-19 21:00:06 +02:00
pascallanger
278ebf4ff2 Merge pull request #81 from LapinFou/master
Align pictures in Compiling.md
2017-04-19 15:21:01 +02:00
Sebastien Charpentier
edc58a3496 Update Compiling.md
Align pictures int section **Connect the programmer**
2017-04-19 15:17:11 +02:00
pascallanger
7c96862b19 Merge pull request #80 from LapinFou/master
Few more corrections.
2017-04-19 15:11:18 +02:00
Sebastien Charpentier
11b18f7468 Update Troubleshooting.md
Cosmetic amelioration.
2017-04-19 15:08:36 +02:00
Sebastien Charpentier
86787b6099 Update README.md
Change formatting of **_Config.h**
2017-04-19 15:04:32 +02:00
Sebastien Charpentier
12645c19aa Update Compiling_STM32.md
Cosmetic fix.
2017-04-19 15:01:24 +02:00
Sebastien Charpentier
7e06a57fd9 Update Compiling_STM32.md
Cosmetic fix.
2017-04-19 15:00:19 +02:00
Sebastien Charpentier
4d7c31cfa1 Update Compiling.md
Fixed **Boards.txt** alignment.
Fixed **On Mac OSX** section.
2017-04-19 14:56:48 +02:00
Sebastien Charpentier
f5e4fc5a3d Update README.md
Correct typo.
2017-04-19 14:51:49 +02:00
Sebastien Charpentier
1c4174431e Update README-old.md
Fixed broken links.
2017-04-19 14:48:46 +02:00
Sebastien Charpentier
60d4f2d6c7 Update PPM_Setup.md
Fixed Markdown.
Fixed link.
2017-04-19 14:44:38 +02:00
pascallanger
5a30a96c0c Merge pull request #79 from LapinFou/master
More fixes
2017-04-19 13:27:51 +02:00
Sebastien Charpentier
09b454ba6a Update Module_Build_yourself_PCB.md
Relative path is better.
2017-04-19 12:07:53 +02:00
Sebastien Charpentier
8ea06e84a6 Update Module_Build_yourself_PCB.md 2017-04-19 12:06:26 +02:00
Sebastien Charpentier
ebaf56d964 Update Advanced_Manually_Setting_ATmega328_Fuses.md
Changed hard-coded links to relative links.
2017-04-19 11:59:16 +02:00
Sebastien Charpentier
517d2bb1ec Update Advanced_ATmega_Serial_Uploader.md 2017-04-19 11:45:57 +02:00
Sebastien Charpentier
706d43ee41 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-04-19 11:45:00 +02:00
Sebastien Charpentier
e537d27e28 Update Compiling_STM32.md
Fixed **Prepare the Arduino IDE:** section.
2017-04-19 11:40:28 +02:00
Sebastien Charpentier
948f28b0af Update Compiling.md
Fixed **On Windows** section.
2017-04-19 11:34:20 +02:00
Sebastien Charpentier
70f7c6a25e Update Compiling.md 2017-04-19 11:33:14 +02:00
Sebastien Charpentier
a0a0cd4f57 Update Compiling.md 2017-04-19 11:32:19 +02:00
Sebastien Charpentier
dfa120339c Update BOM_DIY_STM32 & Schematic.md 2017-04-19 11:30:21 +02:00
Sebastien Charpentier
36f194b9bd Update BOM_DIY_ATmega.md
Fixed **BOM for the DIY STM32** link.
2017-04-19 11:29:54 +02:00
Sebastien Charpentier
12dd851fc3 Update BOM_DIY_ATmega.md 2017-04-19 11:16:07 +02:00
Sebastien Charpentier
cc9a5893de Update BOM_DIY_ATmega.md 2017-04-19 11:15:17 +02:00
Sebastien Charpentier
9d2ac3f2c4 Update README-old.md
Fixed Markdown.
2017-04-19 11:13:33 +02:00
pascallanger
9cda61de3d Merge pull request #78 from LapinFou/LapinFou/FixMarkdownTypo
Fixed markdown typo
2017-04-19 11:04:22 +02:00
Sebastien Charpentier
060d93d68b Merge pull request #1 from LapinFou/LapinFou/FixMarkdownTypo
Fix Markdown typo
2017-04-19 10:58:17 +02:00
Sebastien Charpentier
8d1e8c6699 Merge branch 'master' into LapinFou/FixMarkdownTypo 2017-04-19 10:52:32 +02:00
Sebastien Charpentier
f4865c5206 Update Hardware.md
Highlighted the "more information when clicking on the pictures".
2017-04-19 10:46:53 +02:00
Sebastien Charpentier
2d44c89149 Update Models.md
Fixed **CH6 and CH7** section.
2017-04-19 10:43:59 +02:00
Sebastien Charpentier
c2050d4314 Update Compiling_STM32.md 2017-04-19 10:41:32 +02:00
Sebastien Charpentier
7991605106 Update Compiling_STM32.md 2017-04-19 10:39:45 +02:00
LapinFou
adeea85c9a Cosmetic. 2017-04-19 10:12:01 +02:00
Sebastien Charpentier
c32e390184 Update Compiling.md 2017-04-19 10:07:28 +02:00
LapinFou
154f61fb11 Fixed "Material you need to upload the firmware" section. 2017-04-19 09:56:08 +02:00
LapinFou
b08bcf041b Fixed compiling page. 2017-04-19 09:53:15 +02:00
LapinFou
e51f6e1e86 More corrections. 2017-04-18 20:37:40 +02:00
LapinFou
62e2a0211f Fix categories. 2017-04-18 20:20:27 +02:00
LapinFou
5286e7f89c Typo. 2017-04-18 20:19:35 +02:00
LapinFou
e81ba55967 Test image 2017-04-18 20:12:08 +02:00
LapinFou
25a2689bd0 Test image 2017-04-18 18:42:03 +02:00
LapinFou
c949eb5491 Test image 2017-04-18 18:40:02 +02:00
LapinFou
709c5cbd71 Typo !! 2017-04-18 18:34:55 +02:00
LapinFou
3ac59a5bc0 Typo again... =) 2017-04-18 18:32:49 +02:00
LapinFou
6894228a63 Fixed typo. 2017-04-18 18:28:18 +02:00
LapinFou
a7b914b84e Fixed more typos. 2017-04-18 18:24:20 +02:00
LapinFou
84922e84a3 Fixed Markdown typos. 2017-04-18 18:09:50 +02:00
LapinFou
7ee0b2b0a3 Try to fix again the table. 2017-04-18 17:52:12 +02:00
LapinFou
5c06a241ac Try to fix table. 2017-04-18 17:48:04 +02:00
LapinFou
0cb0128caf Test 2017-04-18 17:46:11 +02:00
midelic
8661b8074c added useful info regarding compiling 2017-04-18 16:22:33 +01:00
midelic
fa52a1a81e fix sintax errors 2017-04-18 16:05:52 +01:00
pascallanger
680fa7a350 Merge pull request #74 from schwabe/patch-4
DSM: Remove special bind stick positions
2017-04-14 12:37:49 +02:00
Arne Schwabe
3850ce88d3 DSM: Remove special bind stick positionsD
Spektrum own remotes transmit normal values during bind and actually use this (e.g. Nano CP X) to select the transmitter mode (e.g. computer vs non-computer radio, so always end normal output
2017-04-12 16:10:18 +02:00
pascallanger
a800f1efc7 Merge pull request #73 from John-RB/master
Missing comma in STM32 V1.1 BOM
2017-04-10 18:28:18 +02:00
John-RB
514bbbe8a3 Missing comma in STM32 V1.1 BOM 2017-04-10 09:44:51 -04:00
pascallanger
700b922350 Fix AFHDS2A power issue 2017-04-10 11:33:26 +02:00
pascallanger
bdfeeb9a41 Fix STM32 issue and OrangeTX compilation 2017-04-10 11:24:21 +02:00
pascallanger
2b80d1a6d8 Merge pull request #70 from John-RB/master
Add V1.1 design to STM32 BOM
2017-04-10 11:07:05 +02:00
John-RB
fa6f2061e7 Add V1.1 design to BOM 2017-04-09 11:48:44 -04:00
John-RB
ff5f12e4d2 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	docs/BOM_DIY_STM32 & Schematic.md
2017-04-09 11:45:47 -04:00
midelic
9ad6e8142d Update BOM_DIY_STM32 & Schematic.md 2017-04-08 20:37:18 +01:00
midelic
49e3534738 Add PCB _STM32_USB_V1.1 board files 2017-04-08 20:27:45 +01:00
John-RB
4cb7ba83e9 Add V1.1 design to BOM 2017-04-07 11:17:51 -04:00
midelic
9282828ffc Add updated multi_STM32 board V1.1 2017-04-03 08:16:14 +01:00
pascallanger
2f2a2d4bee Merge pull request #66 from schwabe/patch-2
Fix formatting and add companion screen
2017-03-31 19:29:09 +02:00
Arne Schwabe
b904e6a889 Highlight the option in the screenshot 2017-03-31 16:33:56 +02:00
Arne Schwabe
804d5723c2 Add image 2017-03-31 16:09:24 +02:00
Arne Schwabe
681e3a6865 Fix formatting, add multimodule companion option 2017-03-31 16:07:28 +02:00
midelic
dd75c56404 typo error fix/cosmetics 2017-03-31 14:14:08 +01:00
pascallanger
86cee1e339 Merge pull request #62 from spectrenoir06/patch-1
fix markdown in Transmitters.md
2017-03-28 09:18:42 +02:00
Spectre
063edc032a Update Transmitters.md 2017-03-27 15:59:38 +02:00
pascallanger
32c59cb583 DM002 2017-03-23 20:48:34 +01:00
pascallanger
0242f88d26 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-03-23 18:05:06 +01:00
pascallanger
940a89fa38 DM002: 2 TX ID/RF & features addition 2017-03-23 18:05:00 +01:00
pascallanger
364a66ad0b Update Protocols_Details.md 2017-03-23 18:03:43 +01:00
pascallanger
f714315b0d DM002 update 2017-03-23 18:03:11 +01:00
pascallanger
ed83471a13 Update Protocols_Details.md 2017-03-22 16:45:54 +01:00
pascallanger
1263aa7884 Update Protocols_Details.md 2017-03-22 16:41:51 +01:00
pascallanger
c21afc3f8a Update Protocols_Details.md 2017-03-22 16:36:51 +01:00
pascallanger
59af0594dc DM002: correct channels 2017-03-22 16:17:12 +01:00
pascallanger
8cf6d4f7d8 add DM002 2017-03-22 14:58:59 +01:00
pascallanger
61ceeb44fb Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-03-22 14:56:00 +01:00
pascallanger
995bb921c1 DM002 protocol
protocol number 33
sub_protocol none=0
ch5=flip
ch6=led
ch7=headless
2017-03-22 14:55:55 +01:00
pascallanger
e7cab78aad Update package_MULTI_index.json 2017-03-07 22:48:07 +01:00
pascallanger
1c06bd45ef Update package_MULTI_index.json 2017-03-07 22:46:43 +01:00
pascallanger
85a3e112e0 Update package_MULTI_index.json 2017-03-07 22:41:39 +01:00
pascallanger
9c5e054dda Boards 2017-03-07 22:25:41 +01:00
pascallanger
86932e6da4 Update BOM_DIY_STM32 & Schematic.md 2017-03-05 21:09:30 +01:00
pascallanger
5f94fdfc93 Update BOM_DIY_STM32 & Schematic.md 2017-03-05 21:08:29 +01:00
midelic
74584dd39e Add eagle CAD files for Multi_STM32_V0.1 2017-03-04 23:00:53 +02:00
pascallanger
18ed5d51a9 STM32 BOM: capacitor polarity added on silkscreen 2017-02-28 13:25:04 +01:00
pascallanger
d7076f5295 PPM: add MIN_PPM_CHANNELS and MAX_PPM_CHANNELS 2017-02-28 10:36:35 +01:00
pascallanger
29a5397491 SLT: revert to previous version 2017-02-28 10:33:43 +01:00
pascallanger
47a4261631 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-24 20:22:33 +01:00
pascallanger
a3927218a6 Futaba middle value 1520 2017-02-24 20:22:28 +01:00
midelic
7d846a3d0d Update BOM_DIY_STM32 & Schematic.md 2017-02-24 18:09:56 +01:00
pascallanger
8db1f6d1e2 Update Module_Build_yourself_PCB.md 2017-02-24 17:29:53 +01:00
pascallanger
9cb679d545 Update BOM_DIY_STM32 & Schematic.md 2017-02-24 17:17:36 +01:00
pascallanger
006d705cbd v0.1 schematic 2017-02-24 17:16:12 +01:00
pascallanger
a19a14665f GW008 Autobind protocol 2017-02-24 13:41:32 +01:00
pascallanger
55bc6f9a00 FrSkyX telemetry RSSI and LQi 2017-02-24 13:27:19 +01:00
pascallanger
997d31addd FrSkyX add telemetry TX_RSSI, RX_LQI, TX_LQI 2017-02-24 11:48:25 +01:00
pascallanger
548390b0d7 GW008 protocol addition
Protocol number: 32
No sub_protocol
2017-02-24 11:00:10 +01:00
pascallanger
bd64bdedc3 GW008 protocol 2017-02-24 10:57:53 +01:00
pascallanger
846e09c7cb Disable low power by default 2017-02-23 11:23:25 +01:00
pascallanger
2ba3552578 AFHDS2A: prevent TX inbound swamping during bind 2017-02-23 10:07:09 +01:00
pascallanger
943bb6d15b SFHSS reverse channels direction 2017-02-23 09:15:12 +01:00
pascallanger
af53e75ae4 Update Protocols_Details.md 2017-02-23 09:13:45 +01:00
pascallanger
14ca63571d Fix OrangeTX compilation 2017-02-21 14:20:25 +01:00
pascallanger
10c5ce68f5 Update Protocols_Details.md 2017-02-21 01:03:58 +01:00
pascallanger
d9fb856eb8 Fix Multi OrangeTX build 2017-02-21 00:29:48 +01:00
pascallanger
f5c08158cb Update Compiling.md 2017-02-20 23:26:43 +01:00
pascallanger
9ee0311ea9 FrSkyD compilation issue without telemetry 2017-02-11 11:40:40 +01:00
pascallanger
69ed2d2428 Update Troubleshooting.md 2017-02-10 17:40:47 +01:00
pascallanger
0c5fae01b5 WAIT_FOR_BIND feature
This feature will not activate the selected protocol unless a bind is
requested using bind from channel or the GUI "Bind" button. It is only
enabled if bind from channel and autobind are set since I think they are
working well together.
The goal is to prevent binding other people's model when powering up the
TX, changing model or scanning through protocols.
There is a new blinking pattern associated to it as well as a new status
"Waiting for bind".
This feature is enabled by default in _config.h .
2017-02-10 17:38:07 +01:00
pascallanger
72052925a6 Update Compiling.md 2017-02-10 15:59:47 +01:00
pascallanger
dc2d02bf32 Update Compiling_STM32.md 2017-02-10 15:59:19 +01:00
pascallanger
ee267ea086 Update Compiling_STM32.md 2017-02-10 13:32:53 +01:00
pascallanger
1e730f3376 Update Compiling_STM32.md 2017-02-09 10:24:27 +01:00
pascallanger
c230c52af6 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-08 22:42:44 +01:00
pascallanger
219beb4a0e Fix Multi_status bind flag when invalid protocol selected 2017-02-08 22:42:39 +01:00
pascallanger
c4807c44f3 Add protocol/sub_protocol numbers 2017-02-08 12:26:35 +01:00
pascallanger
7dafd14644 Merge pull request #49 from John-RB/master
BOM_DIY_STM32 & Schematic
2017-02-07 17:59:24 +01:00
John-RB
57c3e8c51d BOM_DIY_STM32 & Schematic
Correct Reference ID and Part Number Red LED
2017-02-07 11:55:19 -05:00
midelic
da71eca978 Update Compiling_STM32.md 2017-02-07 17:37:23 +01:00
midelic
7a47af14be Update Compiling_STM32.md 2017-02-07 17:31:18 +01:00
midelic
f67adc53ab Update Compiling_STM32.md 2017-02-07 17:18:54 +01:00
pascallanger
68e9948493 . 2017-02-07 12:09:13 +01:00
pascallanger
894416c719 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-07 12:08:57 +01:00
pascallanger
11650450c8 Chip select based on pin definition 2017-02-07 12:08:11 +01:00
midelic
6973d85b10 info STM32 support in arduino IDE 2017-02-07 09:11:01 +01:00
pascallanger
bf5598515e Removed board option in _config.h 2017-02-06 21:51:03 +01:00
midelic
cc03c27d17 info regarding flashing multiSTM32 via USB port 2017-02-06 19:54:09 +01:00
pascallanger
9cd729df71 Update Module_BG_4-in-1.md 2017-02-06 19:06:28 +01:00
pascallanger
d6ee9fbfac Update Module_BG_4-in-1.md 2017-02-06 19:05:02 +01:00
pascallanger
b6999f5c67 Update Hardware.md 2017-02-06 19:03:49 +01:00
pascallanger
c02f273d57 New feature: end bind
This new feature is available:
- in serial mode and when binding from the GUI. As soon as the Bind
window is closed = serial bind bit was set and cleared, the current bind
operation will be terminated.
- if the bind was initiated from the Bind on channel feature (bind
channel goes high) then as soon as the bind channel goes low the current
bind operation will be terminated.
Tested on ersky9x which does open a bind window, not sure about
OpenTX...

Some protocols (Hubsan, Assan, FY326, Shenqi...) which are waiting for
model/RX to reply will stay in bind mode.
2017-02-06 18:46:34 +01:00
pascallanger
8d87bfb4a3 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-06 15:50:48 +01:00
pascallanger
0a7cd3d6e9 Reset invert serial when switching protocol 2017-02-06 15:50:43 +01:00
pascallanger
235699b3b9 Update README.md 2017-02-06 15:40:48 +01:00
pascallanger
1aebfbecc1 Update Hardware.md 2017-02-06 15:37:14 +01:00
pascallanger
00e47b9afb MultiOrange: add Walkera protocol 2017-02-06 10:39:58 +01:00
pascallanger
68b94cfcaa FrSkyD small change 2017-02-06 10:32:15 +01:00
pascallanger
0068f21a2d MultiOrange build fix 2017-02-06 10:32:15 +01:00
pascallanger
7a7e639490 Update BOM_DIY_STM32 & Schematic.md 2017-02-06 10:26:25 +01:00
pascallanger
81bae1441e Update BOM_DIY_STM32 & Schematic.md 2017-02-06 10:25:11 +01:00
pascallanger
3516e5ae8a FrSkyD telemetry fix 2017-02-04 10:11:25 +01:00
pascallanger
04bbe3187f FrSky telemetry 2017-02-03 22:02:35 +01:00
pascallanger
877cdec4ea Config.h 2017-02-03 21:08:10 +01:00
pascallanger
21ab94c512 FrSkyD and X telemetry 2017-02-03 21:06:21 +01:00
pascallanger
70f52afb3d Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-03 16:49:23 +01:00
pascallanger
85f4dbd670 FrSkyD telemetry and serial TX buffer 2017-02-03 16:49:19 +01:00
pascallanger
bee70e67bc Merge pull request #46 from John-RB/master
STM32 BOM Updates
2017-02-02 22:06:27 +01:00
John-RB
7e137f17a5 STM32 BOM Updates
V1.0t BOM
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
V0.8 BOM
- Quantity for Diode
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
First Version BOM
- Part number for Red LED
- Dual Input-XOR Part Number with proper part footprint.
2017-02-02 15:10:10 -05:00
John-RB
c576f62ca3 V1.0t BOM
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
V0.8 BOM
- Quantity for Diode
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
First Version BOM
- Part number for Red LED
- Dual Input-XOR Part Number with proper part footprint.
2017-02-02 14:57:35 -05:00
John-RB
9c8499e6cd Changes for 3 STM32 BOM's
V1.0t BOM
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
V0.8 BOM
- Quantity for Diode
- Separate line and Part number for each LED
- Dual Input-XOR Part Number with proper part footprint.
First Version BOM
- Part number for Red LED
- Dual Input-XOR Part Number with proper part footprint.
2017-02-02 14:43:26 -05:00
pascallanger
f81e7cb78a FrSkyD telemetry 2017-02-02 18:07:46 +01:00
pascallanger
773f3048f7 Devo: extended range 2017-02-02 18:07:36 +01:00
pascallanger
40faaea7f8 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-02-02 14:31:05 +01:00
pascallanger
47b4409f3e FrSkyD telemetry 2017-02-02 14:30:56 +01:00
pascallanger
9ce23c3d61 Protocol change: make sure that main loop is aware 2017-02-02 14:30:46 +01:00
pascallanger
f40ffed069 Merge pull request #44 from schwabe/patch-1
add no_multi_telemetry as indicator of crashed
2017-02-02 10:52:24 +01:00
Arne Schwabe
0b223170d9 Update Tx-Taranis.md 2017-02-02 10:09:38 +01:00
pascallanger
e61f8a512c Merge pull request #43 from schwabe/patch-3
Add X7, add multi telemetry section OpenTX/Taranis document
2017-02-02 08:44:53 +01:00
Arne Schwabe
65b43c39ed Explain multi telemetry examples 2017-02-01 22:56:29 +01:00
Arne Schwabe
131645f31e Update Tx-Taranis.md 2017-02-01 22:50:16 +01:00
Arne Schwabe
ca8fc14d36 add x7 screenshots 2017-02-01 22:42:03 +01:00
Arne Schwabe
efe693c0c0 Add Horus and X7 in the overview. 2017-02-01 22:16:13 +01:00
pascallanger
4eb2d073ac SFHSS channels mapping 2017-02-01 17:51:04 +01:00
pascallanger
fd49c02e18 Update BOM_DIY_STM32 & Schematic.md 2017-02-01 14:13:24 +01:00
pascallanger
f0e3d492d3 Update BOM_DIY_STM32 & Schematic.md 2017-02-01 14:12:19 +01:00
pascallanger
3f8ba6be9d Update BOM_DIY_STM32 & Schematic.md 2017-02-01 13:52:57 +01:00
pascallanger
df4563379d Update BOM_DIY_STM32 & Schematic.md 2017-02-01 13:49:24 +01:00
pascallanger
f0f9d8faa7 Update BOM_DIY_STM32 & Schematic.md 2017-02-01 13:39:02 +01:00
pascallanger
031b4b637a Update BOM_DIY_STM32 & Schematic.md 2017-02-01 13:10:25 +01:00
pascallanger
e206ae3403 Update Module_Build_yourself_PCB.md 2017-02-01 13:04:08 +01:00
pascallanger
021c463d80 FrSkyD telemetry 2017-02-01 12:47:28 +01:00
pascallanger
41d75da33f FrSkyD telemetry
- rewritten the handling of the incoming over the air telemetry packet
- rewritten the TX_RSSI calculation (link frame[4])
- added RX LQI and TX_LQI information in the link frame (frame[5] and
frame[6])
2017-02-01 09:28:35 +01:00
pascallanger
c7e7a559a6 FrSkyD Telemetry update 2017-01-31 15:26:49 +01:00
pascallanger
4f5dfcc65b Few comments tweak 2017-01-31 09:12:06 +01:00
pascallanger
e85208110f FrSky D/X telemetry update 2017-01-31 08:46:58 +01:00
midelic
17bb2f11e4 added STM32 module diagrams links 2017-01-31 02:44:04 +02:00
midelic
124db5f11f Rename BOM_DIY_STM32.md to BOM_DIY_STM32 & Schematic.md 2017-01-31 01:24:12 +02:00
midelic
6b099d7298 Added schematic for V1.0 version(USB) 2017-01-31 01:23:09 +02:00
pascallanger
7ac2e227b1 FrSkyD: telemetry fix?
Added CRC check on incoming telemetry packet.
2017-01-30 21:09:27 +01:00
pascallanger
868c1aa251 Update Protocols_Details.md 2017-01-30 21:00:37 +01:00
pascallanger
7283fc89a5 Update Protocols_Details.md 2017-01-30 20:33:12 +01:00
pascallanger
f933560934 Update Protocols_Details.md 2017-01-30 17:35:15 +01:00
pascallanger
7ee918ad49 Multiprotocol status
Along with the latest ersky9x version, display the module version and if
a specific protocol is available or not.
2017-01-30 16:11:46 +01:00
pascallanger
e30ebd39fd FrSkyX LBT EU addition
Add support for LBT EU 16/8 channels accessible through sub protocols
EU_16 and EU_8
Also includes modification of FrSkyV, D, X CC2500 initialization
2017-01-30 16:11:45 +01:00
pascallanger
7ac6ff828c Q303: reverse A&R channels 2017-01-30 16:11:45 +01:00
midelic
017f5f8e74 Added Multi_STM32_V0.8_t board 2017-01-26 18:17:35 +02:00
midelic
2c46feb8f8 Added Multi_STM32_V0.8_t board 2017-01-26 18:14:19 +02:00
midelic
f5171f3f47 move risky flashing methods to advanced topics 2017-01-26 18:04:19 +02:00
midelic
1a2c28435a move risky flashing methods to advanced topics 2017-01-26 18:04:04 +02:00
midelic
7221fc2060 added more compiling info 2017-01-26 15:09:54 +02:00
pascallanger
e17e7ab4ec Update README.md 2017-01-25 21:38:12 +01:00
midelic
46eb0bc474 added more info 2017-01-25 20:50:29 +02:00
pascallanger
b03227ea9f Update README.md 2017-01-25 19:15:27 +01:00
pascallanger
a1de5e15c5 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 19:12:58 +01:00
pascallanger
7f2322ba60 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 19:10:00 +01:00
pascallanger
5c04844461 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 19:09:16 +01:00
pascallanger
591a185fc2 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 19:08:46 +01:00
pascallanger
fbc0b60b68 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 19:06:43 +01:00
pascallanger
325ce8824e Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-01-25 19:01:17 +01:00
pascallanger
d54e25bb44 Image 2017-01-25 19:01:13 +01:00
pascallanger
740943aee2 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 18:42:53 +01:00
pascallanger
73ee93335b Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 18:37:53 +01:00
pascallanger
c69c3361ac Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-25 18:36:11 +01:00
pascallanger
a91d019738 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-01-25 18:32:03 +01:00
pascallanger
dc272a472d Images 2017-01-25 18:31:58 +01:00
pascallanger
b265108322 Update Compiling.md 2017-01-25 17:55:04 +01:00
pascallanger
6cab6a9646 Update Module_BG_4-in-1.md 2017-01-25 17:28:53 +01:00
pascallanger
3baf237fa8 Update Module_BG_4-in-1.md 2017-01-25 17:27:55 +01:00
pascallanger
fa8503546e Update Protocols_Details.md 2017-01-25 17:21:17 +01:00
pascallanger
b9d988c712 Update Troubleshooting.md 2017-01-25 17:18:45 +01:00
pascallanger
2bbf672094 Update Troubleshooting.md 2017-01-25 15:50:07 +01:00
pascallanger
a6f8fe4c95 Update README.md 2017-01-25 15:33:02 +01:00
pascallanger
6d7415880a Update Module_Build_From_Scratch.md 2017-01-25 15:31:56 +01:00
pascallanger
479e4588f3 Update Module_Build_From_Scratch.md 2017-01-25 15:31:25 +01:00
pascallanger
821f1bdc2b Update Module_Build_yourself_PCB.md 2017-01-25 15:29:45 +01:00
pascallanger
5cdd672e84 Update Module_Build_yourself_PCB.md 2017-01-25 15:28:59 +01:00
pascallanger
48fb8d0b92 Update Transmitters.md 2017-01-25 15:24:12 +01:00
pascallanger
52fae655ba Update Module_BG_4-in-1.md 2017-01-25 15:22:46 +01:00
pascallanger
3ab6e84275 Update Transmitters.md 2017-01-25 15:21:43 +01:00
pascallanger
2b5ab6db11 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-01-25 15:20:20 +01:00
pascallanger
a0f6d47153 Image 2017-01-25 15:20:16 +01:00
pascallanger
787901ba73 Update Transmitters.md 2017-01-25 15:16:34 +01:00
pascallanger
37c7167128 Update Module_BG_4-in-1.md 2017-01-25 15:09:44 +01:00
pascallanger
35e1ddc578 Update README.md 2017-01-25 15:07:05 +01:00
pascallanger
d61e7b8729 Update README.md 2017-01-25 14:58:28 +01:00
pascallanger
8ef73f9dd2 Update Module_BG_4-in-1.md 2017-01-25 14:40:15 +01:00
pascallanger
f7448cc2e4 Fix Hopping_table[47]=0 2017-01-25 14:35:38 +01:00
pascallanger
6af35b5ec5 Images 2017-01-25 14:14:51 +01:00
pascallanger
8f4e5c6064 Update Module_BG_4-in-1.md 2017-01-25 14:14:37 +01:00
pascallanger
2d76775e40 Update Module_BG_4-in-1.md 2017-01-25 14:13:52 +01:00
pascallanger
8eb71cbe74 Update Module_BG_4-in-1.md 2017-01-25 14:10:56 +01:00
pascallanger
9146a8bb21 Update Module_BG_4-in-1.md 2017-01-25 14:08:48 +01:00
pascallanger
445bca7333 Update Module_BG_4-in-1.md 2017-01-25 14:07:57 +01:00
pascallanger
6286551ef5 Image 2017-01-25 14:05:21 +01:00
pascallanger
1ae6a69c7a Update Module_BG_4-in-1.md 2017-01-25 13:52:10 +01:00
pascallanger
34851b772f Update Module_BG_4-in-1.md 2017-01-25 13:49:15 +01:00
pascallanger
4823aa378e Update Module_BG_4-in-1.md 2017-01-25 13:48:42 +01:00
pascallanger
40a42e86ee Update Module_BG_4-in-1.md 2017-01-25 13:47:56 +01:00
pascallanger
c518b52243 Merge pull request #40 from schwabe/patch-3
Update Module_BG_4-in-1.md
2017-01-25 13:42:16 +01:00
pascallanger
abccc3c3cd Update Module_BG_4-in-1.md 2017-01-25 13:38:59 +01:00
pascallanger
9786b7139e Update Module_BG_4-in-1.md 2017-01-25 13:37:56 +01:00
pascallanger
28e8e3434e Images 2017-01-25 13:33:58 +01:00
pascallanger
cdf59fba10 Update Compiling.md 2017-01-25 13:02:58 +01:00
midelic
be8571cb56 Multi_STM32 flashing info 2017-01-25 13:52:52 +02:00
midelic
857715e55c Multi_STM32 flashing info. 2017-01-25 13:30:08 +02:00
midelic
5ccc815a47 Multi_STM32 flashing info 2017-01-25 02:36:32 +02:00
midelic
d77c04109b Multi_STM32 module- connection example 2017-01-25 02:27:05 +02:00
midelic
1ba8b8b1b1 added flashing info for Multi_STM32 module 2017-01-25 02:19:42 +02:00
midelic
caa349b59b add Multi_STM32 flashing diagram. 2017-01-25 02:15:43 +02:00
pascallanger
9a7350149d Update Protocols_Details.md 2017-01-24 22:55:55 +01:00
pascallanger
7f435363f7 Update Protocols_Details.md 2017-01-24 22:48:43 +01:00
pascallanger
832cb79f88 New protocol Q303
Q303 protocol number: 31
Sub ptotocols:
-  Q303 = 0
-  CX35 = 1
- CX10D = 2
- CX10WD = 3
2017-01-24 22:46:11 +01:00
pascallanger
ba7290fdda New protocol Q303
Q303 protocol number: 31
Sub ptotocols:
-  Q303 = 0
-  CX35 = 1
- CX10D = 2
- CX10WD = 3
2017-01-24 16:58:48 +01:00
pascallanger
85ee4a95ec Simplification of chanskip usage 2017-01-24 16:58:48 +01:00
pascallanger
eb164c511f Update end points and map function 2017-01-24 16:58:47 +01:00
pascallanger
26e3119ef3 Use define 2017-01-24 16:58:47 +01:00
pascallanger
6c38b54f7d Update Compiling.md 2017-01-24 09:22:30 +01:00
pascallanger
7e6badaf5d Update Compiling.md 2017-01-24 08:40:09 +01:00
pascallanger
c104e8e1f0 Update Compiling.md 2017-01-23 21:41:29 +01:00
pascallanger
c8d04f3373 Images 2017-01-23 21:40:50 +01:00
pascallanger
f64f417711 Update Compiling.md 2017-01-23 21:38:38 +01:00
pascallanger
92fe975e3d Update Compiling.md 2017-01-23 21:37:46 +01:00
pascallanger
e00731ef8f Images 2017-01-23 21:35:17 +01:00
pascallanger
0d7d0664f6 Update BOM_DIY_STM32.md 2017-01-23 21:09:02 +01:00
pascallanger
b59b0ef041 Update Compiling.md 2017-01-23 18:52:32 +01:00
pascallanger
964aa0ecce Update Compiling.md 2017-01-23 18:51:02 +01:00
pascallanger
a9ecf06cd4 Update README.md 2017-01-23 18:45:59 +01:00
pascallanger
76da6857e7 Update README.md 2017-01-23 18:45:16 +01:00
pascallanger
9eef60c93d Update README.md 2017-01-23 18:41:49 +01:00
pascallanger
df412bbef7 Update Compiling.md 2017-01-23 18:38:03 +01:00
pascallanger
b4c6632162 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2017-01-23 18:36:06 +01:00
pascallanger
5f2eb6bd32 Update Compiling.md 2017-01-23 18:34:02 +01:00
pascallanger
ea532b15fc Update Compiling.md 2017-01-23 18:30:26 +01:00
pascallanger
01bd1fde39 Update Compiling.md 2017-01-23 18:29:56 +01:00
pascallanger
c6c1c61ff6 Update Compiling.md 2017-01-23 18:29:21 +01:00
pascallanger
bbd33c70c1 Update Compiling.md 2017-01-23 18:28:31 +01:00
pascallanger
a2592342fe Update Compiling.md 2017-01-23 18:26:11 +01:00
pascallanger
db06e12337 Update Compiling.md 2017-01-23 18:24:56 +01:00
pascallanger
22139c9650 Image 2017-01-23 18:10:49 +01:00
pascallanger
3b1e2e38fb Image 2017-01-23 16:43:19 +01:00
pascallanger
6f6da47ebe Update Compiling.md 2017-01-23 15:33:03 +01:00
pascallanger
f3237172f3 Iamge 2017-01-23 15:30:52 +01:00
pascallanger
45dc64af5a Image 2017-01-23 15:22:20 +01:00
pascallanger
4df71bff7f Update Compiling.md 2017-01-23 14:35:23 +01:00
pascallanger
f5003d3505 Images 2017-01-23 14:33:27 +01:00
pascallanger
f2f3fab3e2 More images 2017-01-23 14:07:57 +01:00
pascallanger
2357e139f0 Update Module_Build_yourself_PCB.md 2017-01-23 13:15:12 +01:00
midelic
c74eaa47a3 Added OSH Park link for USB board 2017-01-23 14:14:56 +02:00
pascallanger
591f9fa4c2 Added old STM32 PCB version 0.8t 2017-01-23 13:14:07 +01:00
pascallanger
766ffa3e65 STM32 1.0t board + schematic 2017-01-23 13:03:01 +01:00
pascallanger
78d2c7beaa Update Module_Build_yourself_PCB.md 2017-01-23 13:02:19 +01:00
pascallanger
f11c38238a Update BOM_DIY_STM32.md 2017-01-23 11:11:49 +01:00
pascallanger
6d388d50ee Update BOM_DIY_STM32.md 2017-01-23 11:10:24 +01:00
pascallanger
9479254562 Update BOM_DIY_STM32.md 2017-01-23 11:09:42 +01:00
pascallanger
9c9fdaf35d Update BOM_DIY_STM32.md 2017-01-23 11:09:07 +01:00
pascallanger
a4767591ae Update Module_Build_yourself_PCB.md 2017-01-23 11:06:40 +01:00
pascallanger
ecbc50b990 Update Module_Build_yourself_PCB.md 2017-01-23 10:02:48 +01:00
pascallanger
dde9cc27d0 Update Module_Build_yourself_PCB.md 2017-01-23 09:18:11 +01:00
Arne Schwabe
703c03e84b Update Module_BG_4-in-1.md 2017-01-19 16:59:22 +01:00
pascallanger
2f831b3e6f Update Module_Build_yourself_PCB.md 2017-01-12 20:50:29 +01:00
pascallanger
d54eec0b87 Update BOM_DIY_ATmega.md 2017-01-12 20:48:06 +01:00
pascallanger
bc80554cd3 YD717: possible fix for old CX10 2017-01-07 13:18:18 +01:00
pascallanger
a696d330e5 Update Protocols_Details.md 2017-01-04 11:49:44 +01:00
pascallanger
b1479ab3c5 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2017-01-04 11:35:43 +01:00
pascallanger
e51fb06ceb WK2x01: added fixed id mode for WK2801 2017-01-04 11:35:38 +01:00
pascallanger
dc0f2bde6b Add WK2X01 protocol and sub protocols 2017-01-03 20:19:57 +01:00
pascallanger
eb13f267fe New Bind from channel feature 2017-01-03 20:09:28 +01:00
pascallanger
8677e73d75 WK2x01: subprotocols addition
WK2801 number 0, 8 channels, fixed id is not supported
WK2401 number 1, 4 channels
W6_5_1 number 2, 6 channels
W6_6_1 number 3, 7 channels
W6_HEL number 4, 6 channels, option is used to limit COL
W6_HEL_I number 5, 6 channels, COL inverted, option is used to limit COL
2017-01-03 19:56:20 +01:00
pascallanger
fbb919d767 New protocol WK2x01
Protocol WK2x01 number 30
Sub protocols:
- WK2801 number 0, 8 channels, fixed id not supported
- WK2601 number 1, 6/7 channels, option is used see doc for details
- WK2401 number 2, 4 channels
Extended limits supported
Autobind protocol
Most receivers support WK2801 so always start trying this sub protocol
first.
2017-01-03 19:19:53 +01:00
pascallanger
1f0f9a2eae DSM function name change for uniqness 2017-01-03 19:07:10 +01:00
pascallanger
282b2a0a43 Bind from channel: Cosmetic code change 2017-01-03 12:00:25 +01:00
pascallanger
6d0e4d5a38 Fix Bind channel 2017-01-02 18:22:03 +01:00
pascallanger
43956bbf2c Bind channel fix 2017-01-02 17:45:08 +01:00
pascallanger
18e31b3821 Bind channel: configurable channel number
Bind channel can be configured between 5 and 16.
2017-01-02 17:26:35 +01:00
pascallanger
0d0acb9d10 Bind function on channel 16
Toggling channel 16 (-100%->+100%->-100%) will execute a bind only if
the loaded protocol is an autobind protocol or autobind is set AND
throttle is low (below -95%).
2017-01-02 17:04:50 +01:00
pascallanger
6a792ce6a0 FrSky D and X hopping table fix
All RXs using these protocols must be rebinded.
2017-01-02 15:56:32 +01:00
pascallanger
917cea5052 STM32: use manuf ID as global ID 2017-01-01 12:31:13 +01:00
pascallanger
c98f0d3c81 FrSkyX: don't change ID when RX_Num changes 2016-12-29 12:24:38 +01:00
pascallanger
88d650e638 Multi.txt: add missing Q222 2016-12-29 12:22:15 +01:00
pascallanger
72ebe937fb Multi Telemetry: fixed DSM 2016-12-23 09:48:13 +01:00
pascallanger
8efa5bc1dc Multi Telemetry: update version 2016-12-22 10:31:00 +01:00
pascallanger
9b6d2bce58 Multi Telemetry: fix patch level 2016-12-21 20:26:31 +01:00
pascallanger
7bb26a7f07 FrSkyD and FrSkyX: random frequencies 2016-12-21 18:06:03 +01:00
pascallanger
9585b3919a Update Protocols_Details.md 2016-12-20 17:16:56 +01:00
pascallanger
f56c9deb00 MULTI_TELEMETRY: couple of additions 2016-12-19 17:33:30 +01:00
pascallanger
c6221fc60f Merge pull request #35 from schwabe/multi_telemetry
Multi telemetry
2016-12-19 17:09:58 +01:00
pascallanger
acfe3e912e Batch to build for OrangeTX typo 2016-12-19 17:05:13 +01:00
pascallanger
50be0ebe3c Update Protocols_Details.md 2016-12-19 16:12:44 +01:00
pascallanger
704dc803b8 MJXQ/E010: Added 1 more TXID/Freqs 2016-12-19 15:43:25 +01:00
pascallanger
e2d64e9140 ASSAN update 2016-12-19 15:43:25 +01:00
Arne Schwabe
bdef0612f7 Keep old AFHDS2A format for ersky9x 2016-12-18 16:54:44 +01:00
Arne Schwabe
a196b71d36 Implement Multiprotocol Telemetry
This allows the multi module to tell the TX software (e.g. OpenTX) which telemetry protocol is in use. Also Status of the module and signaling binding/invalid protocol
2016-12-18 15:40:05 +01:00
Arne Schwabe
fff8116430 Describe multi telemetry protocol 2016-12-18 15:38:44 +01:00
pascallanger
2be6fb13d2 Merge pull request #34 from acklenx/patch-2
Update Compiling.md
2016-12-18 11:59:15 +01:00
Quincy Acklen
faa6d7f148 Update Compiling.md 2016-12-17 20:16:41 -05:00
gerrievanzyl
982fc2838d Update Compiling_STM32.md 2016-12-14 18:26:06 -05:00
pascallanger
a8351319f8 Update Protocols_Details.md 2016-12-14 09:17:08 +01:00
pascallanger
5b1901708c Update Protocols_Details.md 2016-12-14 09:15:33 +01:00
pascallanger
fa8d4f511f Core: PPM not setting ID properly for some protocols 2016-12-13 20:29:21 +01:00
pascallanger
b4215afe82 Update Protocols_Details.md 2016-12-13 18:20:32 +01:00
pascallanger
2ad25e8fbc Update Protocols_Details.md 2016-12-13 17:41:32 +01:00
pascallanger
67d0e9d2c2 MJXQ: Fixed E010 and added H26WH
Protocol: 18
Sub_protocol for H26WH: 5
2016-12-13 14:58:02 +01:00
pascallanger
f69aae550f Hontai: new sub_protocol FQ777_951
Protocol: 26
Sub protocol: 3
2016-12-12 18:07:43 +01:00
pascallanger
2d26acd991 Hontai -> FQ777_951 2016-12-12 18:04:12 +01:00
pascallanger
8dec1453c4 FY326: new sub protocol FY319
Protocol: 20
Sub_protocol: 1
Untested
2016-12-12 15:47:58 +01:00
pascallanger
241d1e181f H3D: more channels 2016-12-12 14:45:36 +01:00
pascallanger
f267c597e0 H83D more flags 2016-12-12 14:45:43 +01:00
pascallanger
192437896d NRF24L01 updates 2016-12-12 14:07:46 +01:00
pascallanger
d59ae7fce1 Update Protocols_Details.md 2016-12-12 13:49:04 +01:00
pascallanger
18b21005f1 Q222 flags 2016-12-12 13:45:40 +01:00
pascallanger
94ac91cce3 Add more E010 TXID/Freq
Total 14
2016-12-12 11:20:33 +01:00
pascallanger
46e255bccc Bayang telemetry: remove startup warning 2016-12-12 11:20:33 +01:00
pascallanger
87de5b5305 V2X2: new subprotocol JXD506
Protocol number: 5
Subprotocol: 1
2016-12-12 11:20:33 +01:00
pascallanger
1ddc923631 Q222: flags 2016-12-12 11:20:33 +01:00
pascallanger
03f65606fd Sub protocol JXD506 2016-12-12 11:06:12 +01:00
pascallanger
148cf9552b Update Protocols_Details.md 2016-12-09 17:18:40 +01:00
pascallanger
bf230322d0 Bayang: change back A1/A2 to max resolution 2016-12-09 16:56:00 +01:00
pascallanger
758779a8f5 MJXQ/E010: TX IDs vs Freq 2016-12-09 16:54:24 +01:00
pascallanger
55eb39c51d Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-12-09 16:51:59 +01:00
pascallanger
13b8475c54 Add FY805 in Multi.txt for ersky9x 2016-12-09 16:51:55 +01:00
pascallanger
d3d52b44ee Revert "Bayang: change A1 and A2 back to maximum resolution"
This reverts commit d2886432b7.
2016-12-09 16:51:17 +01:00
pascallanger
d2886432b7 Bayang: change A1 and A2 back to maximum resolution 2016-12-09 16:50:56 +01:00
pascallanger
7bb8737ff9 MT99xx/FY805: new protocol addition 2016-12-09 10:30:51 +01:00
pascallanger
3904c36a6e New MT99xx subprotocol FY805
Protocol: MT99xx (number 17)
Subprotocol: FY805 (number 4)
Supports headless and flip. For flip I'm not sure of the flag since it
was missing from the dumps.
Untested protocol...
2016-12-09 10:19:35 +01:00
pascallanger
c2577df6f7 Bayang telemetry : sending volt/4
Change for Taranis
2016-12-09 08:24:51 +01:00
pascallanger
36cb0fb4cd Bad _config.h file pushed... 2016-12-08 15:11:06 +01:00
pascallanger
ec79793f3d Update Protocols_Details.md 2016-12-07 19:23:27 +01:00
pascallanger
188bf76ed1 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-12-07 19:16:13 +01:00
pascallanger
e4e909737c CX10/Q2x2 protocol update 2016-12-07 19:16:09 +01:00
pascallanger
d32421c583 Bayang telemetry 2016-12-06 23:00:16 +01:00
pascallanger
63cbcdc3ea FQ777-124 2016-12-06 22:49:17 +01:00
pascallanger
dfd8d0fa3d Added: Bayang telemetry
Changed telemetry configuration and validation for AFHDS2A and HUBSAN
Added default Bayang telemetry from Silverxxx:
- Option=1 to activate telemetry (option=0 -> standard Bayang protocol)
- Value returned to the TX: RX RSSI, TX RSSI, A1=uncompensated battery
voltage, A2=compensated battery voltage
2016-12-06 22:30:48 +01:00
pascallanger
7d7ca11c81 Telemetry: volatile 2016-12-05 21:51:27 +01:00
pascallanger
ee50a31bba Merge pull request #29 from benlye/patch-1
Added CX-20 details
2016-12-05 21:25:48 +01:00
benlye
179930ad80 Fixed the stock flight modes 2016-12-05 20:20:51 +00:00
benlye
fdb02da5ed Added CX-20 details 2016-12-05 17:41:25 +00:00
pascallanger
5499beb510 Update Module_BG_4-in-1.md 2016-12-05 18:07:47 +01:00
pascallanger
96046d2ee2 V2c image 2016-12-05 18:07:03 +01:00
pascallanger
a35a209066 Update Module_BG_4-in-1.md 2016-12-05 17:48:56 +01:00
pascallanger
8139c33b86 V2a and V2b pictures 2016-12-05 17:47:21 +01:00
pascallanger
da40562ee3 V2 Pictures 2016-12-05 17:43:33 +01:00
pascallanger
ce478583ab 4-in-1 Board v2a 2016-12-05 17:38:54 +01:00
pascallanger
6215af0e5a Added Flysky/CX20 protocol 2016-12-04 21:36:59 +01:00
pascallanger
8f0ecac842 Core: stop transmitting if serial or ppm signal disappears 2016-12-04 18:58:29 +01:00
pascallanger
54dd562d88 Flysky/CX20 fully reversed 2016-12-04 18:56:03 +01:00
pascallanger
c24f7a86d4 Flysky/CX20 reversed elevator channel 2016-12-02 20:28:47 +01:00
pascallanger
d6b4437664 Latest protocol file for ersky9X
To be placed on the SD Card.
2016-12-02 18:20:35 +01:00
pascallanger
68e74b9830 Update Protocols_Details.md 2016-12-02 16:11:34 +01:00
pascallanger
3fa40b2303 Bayang: add sub_protocol H8S3D
Protocol: 14
Sub_protocol: 1
2016-12-02 10:19:42 +01:00
pascallanger
5feb73c65b New Bayang/H8S3D sub_protocol 2016-12-02 10:17:34 +01:00
pascallanger
33d676e1fe Core: option to reverse input channels 2016-12-01 22:30:27 +01:00
pascallanger
afb7af287b Flysky->CX20: hopping frequency based on any TXID 2016-11-30 18:28:56 +01:00
pascallanger
d6291a4c47 Flysky/CX20 fix 2016-11-30 17:02:09 +01:00
pascallanger
7228b84bf8 Flysky CX20 mods 2016-11-30 12:18:39 +01:00
pascallanger
2dbf8ebb65 Flysky: typos... 2016-11-30 07:55:07 +01:00
pascallanger
2d90844239 Flysky: addition of sub_protocol CX20
sub_protocol=4
7 channels
supports bind and extended channels
Only 1 TXID supported for now
2016-11-29 22:30:13 +01:00
pascallanger
bf6e66ea47 Update Protocols_Details.md 2016-11-28 10:37:42 +01:00
pascallanger
5edaa6ec29 SLT: fix 2016-11-25 22:44:17 +01:00
pascallanger
881ca67f80 Update README.md 2016-11-25 14:41:50 +01:00
pascallanger
1c0ed2a2c1 Q222 some channels direction reverse 2016-11-25 11:44:32 +01:00
pascallanger
245d27ea71 CX10 channel modifications 2016-11-25 10:28:18 +01:00
pascallanger
f14d4b8ac3 SLT 2016-11-24 20:28:42 +01:00
pascallanger
fdc867b9d5 Q222 2016-11-24 20:22:52 +01:00
pascallanger
8e876d6a99 Q222: arming 2016-11-24 19:06:33 +01:00
pascallanger
c9de0b4cf2 Q2X2 protocol addition for Q222/Q242/Q282
Q2X2 protocol : 29
Sub-protocols:
- Q222 : 0
- Q242 : 1
- Q282 : 2
2016-11-23 21:56:00 +01:00
pascallanger
27b3a86155 SLT Vista format 2016-11-23 15:35:27 +01:00
pascallanger
683bdc838d SLT 2016-11-18 16:51:52 +01:00
pascallanger
4f9f10ddf2 Core: blinking pattern for PPM signal detection 2016-11-18 16:51:52 +01:00
gerrievanzyl
6fe3f90a26 Update Module_BG_4-in-1.md 2016-11-17 16:00:26 +02:00
gerrievanzyl
5bdb7eee85 Update Module_BG_4-in-1.md 2016-11-17 15:59:31 +02:00
pascallanger
34262a45ca Blinking patterns 2016-11-17 12:55:30 +01:00
pascallanger
7c22110c96 SLT Fix? 2016-11-16 21:17:03 +00:00
pascallanger
6ad9fb8f27 AFHDS2A sub protocols and validation 2016-11-06 16:36:44 +01:00
pascallanger
4348f4b0d4 STM32: USART init changed 2016-11-06 16:34:40 +01:00
pascallanger
22529e28d8 Fixed compilation issue if telemetry is not enabled 2016-11-06 16:32:43 +01:00
pascallanger
aa52bcee8c Apply J6Pro modifications from Vlad 2016-11-06 15:47:40 +01:00
pascallanger
d731ab3682 Merge pull request #23 from schwabe/opentx_flysky_telemetry
Allow TX to request forwarding of FlySky telemetry data
2016-11-06 15:16:45 +01:00
Arne Schwabe
7840438bfc Allow TX to request forwarding of FlySky telemetry data 2016-11-05 01:21:26 +01:00
gerrievanzyl
455a2dba8a Note about the bootloader reducing memory 2016-11-03 13:21:44 -04:00
gerrievanzyl
01c310c913 clarifications 2016-11-03 13:19:19 -04:00
gerrievanzyl
a679d6f2e1 Updated instructions to set fuses before uploading fw 2016-11-03 13:14:03 -04:00
gerrievanzyl
e8af56bdbe Add files via upload 2016-11-03 11:40:49 -04:00
gerrievanzyl
efa099ac5b Jumper on new STM V1.0 board 2016-11-03 11:40:29 -04:00
gerrievanzyl
81181aa7e6 Formatting for clarity 2016-11-03 11:33:11 -04:00
gerrievanzyl
1ab6640983 Emphasised channel order 2016-11-03 11:27:34 -04:00
gerrievanzyl
e5636cde05 emphasised channel order 2016-11-03 11:26:28 -04:00
gerrievanzyl
0a0d00b26e Emphasised channel order 2016-11-03 11:25:18 -04:00
gerrievanzyl
6c9afcff81 Emphasised channel order 2016-11-03 11:23:39 -04:00
gerrievanzyl
b7933b282b USB flashing and updated firmware 2016-11-01 20:52:38 -04:00
gerrievanzyl
653c34758b Updated for USB board and latest firmware 2016-11-01 20:51:24 -04:00
gerrievanzyl
9d18ab795e Added link to OShpark for V0.8 board 2016-11-01 20:29:40 -04:00
gerrievanzyl
a5c06c67bc Update BOM_DIY_STM32.md
Added BOM for Midelic's new board
2016-11-01 20:12:15 -04:00
gerrievanzyl
db2f790bf7 Update BOM_DIY_STM32.md 2016-11-01 17:52:47 -04:00
gerrievanzyl
5cbc6b5f6a Update BOM_DIY_STM32.md 2016-11-01 17:51:59 -04:00
gerrievanzyl
f7ecf40633 MULTI_STM32 USB images 2016-11-01 17:12:33 -04:00
gerrievanzyl
6cd83c60ef Merge pull request #21 from schwabe/patch-2
Fine tune Taranis docu to include Horus
2016-11-01 16:52:19 -04:00
gerrievanzyl
90ffce63e5 Merge pull request #20 from schwabe/patch-1
Move multi specific compiler flags to multi board definition
2016-11-01 16:51:57 -04:00
Arne Schwabe
2910ebc0fd More corrections 2016-11-01 14:50:24 +01:00
Arne Schwabe
02fab95637 Add images for OpenTX 2016-11-01 14:45:54 +01:00
Arne Schwabe
22d2209a1b Update Tx-Taranis.md 2016-11-01 14:45:20 +01:00
Arne Schwabe
e2bea81c64 Add files via upload 2016-11-01 14:41:59 +01:00
Arne Schwabe
466b8bd1cc horus-settings.png 2016-11-01 14:35:51 +01:00
Arne Schwabe
c5287d2869 Add horus to supported platforms 2016-11-01 14:24:23 +01:00
Arne Schwabe
010502ed9d Also update Windows section 2016-10-31 19:06:49 +01:00
Arne Schwabe
be06e74d94 Move multi specific compiler flags to multi board definition
This has the advantage not modifying the other boards and the user needs to only edit one file instead of two.
2016-10-31 19:04:47 +01:00
gerrievanzyl
199d2cf851 Merge pull request #18 from schwabe/patch-1
Add Inductrix details
2016-10-31 11:09:30 -04:00
gerrievanzyl
deab1b4962 Add files via upload 2016-10-31 11:06:09 -04:00
gerrievanzyl
d04411e4a8 Update Models.md 2016-10-31 11:04:09 -04:00
gerrievanzyl
ce52b57a52 Update Models.md 2016-10-31 10:36:29 -04:00
Arne Schwabe
c760c19056 Add Inductrix details 2016-10-31 13:36:33 +01:00
gerrievanzyl
6b5e469b19 Update Compiling.md 2016-10-28 18:19:26 -04:00
gerrievanzyl
8663489ae4 Update Module_Build_yourself_PCB.md 2016-10-27 17:24:04 -04:00
gerrievanzyl
877ef1d7ed Update Module_BG_4-in-1.md 2016-10-27 17:22:58 -04:00
gerrievanzyl
6a81035f10 Update Module_Build_From_Scratch.md 2016-10-27 17:21:53 -04:00
gerrievanzyl
1f7276bbfd Update Module_Build_From_Scratch.md 2016-10-27 17:20:50 -04:00
gerrievanzyl
90e8490a85 Update Module_Build_From_Scratch.md 2016-10-27 17:19:43 -04:00
gerrievanzyl
38d51988d9 Update Module_Build_yourself_PCB.md 2016-10-27 17:18:49 -04:00
gerrievanzyl
b8fccd1bac Update Module_BG_4-in-1.md 2016-10-27 17:17:44 -04:00
pascallanger
ded8e7b916 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-10-27 11:15:31 +02:00
pascallanger
f56ca6318a STM32: align STM32 code with other platforms for tx_pause/tx_resume 2016-10-27 11:15:25 +02:00
pascallanger
5bd6ba4f36 Update Protocols_Details.md 2016-10-26 18:57:23 +02:00
pascallanger
909fb2eb2b AFHDS2A: working version
- Wait for transmit completion before switching to RX (no more fixed
delays...)
- Verify if data has been received before processing it (better handling
of telemetry)
- Added TX_RSSI (along with the existing RX_RSSI)
Known issue: RX_RSSI value needs to be looked at. I'm seeing only values
between 157 (bad) and 196 (good). Is this normal for this protocol?
2016-10-26 13:51:54 +02:00
pascallanger
b2209eaad0 AFHDS2A fix 2016-10-24 23:14:42 +02:00
pascallanger
dcae3c4acb Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-10-22 13:36:19 +02:00
pascallanger
3a3a2ec76d AFHDS2A 2016-10-22 13:36:07 +02:00
gerrievanzyl
5e2ba192c1 Update Compiling.md 2016-10-22 07:11:48 -04:00
gerrievanzyl
6d4452bf94 Update README.md 2016-10-22 07:08:44 -04:00
gerrievanzyl
998f9491f6 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2016-10-22 07:06:43 -04:00
gerrievanzyl
fa7efeb283 Update README.md 2016-10-22 06:25:46 -04:00
gerrievanzyl
22206b6a99 Update README.md 2016-10-22 06:21:16 -04:00
gerrievanzyl
34036ee355 Update Module_Build_yourself_PCB.md 2016-10-22 06:17:49 -04:00
gerrievanzyl
2eb2d555ad Update Module_BG_4-in-1.md 2016-10-22 06:14:22 -04:00
gerrievanzyl
722abf9cab Update Transmitters.md 2016-10-22 06:13:16 -04:00
pascallanger
357d3b8140 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-10-22 12:06:49 +02:00
pascallanger
01ef79ac33 AFHDS2A again 2016-10-22 12:06:44 +02:00
gerrievanzyl
8d2456f238 Update Transmitters.md 2016-10-22 05:59:22 -04:00
gerrievanzyl
bb164edb55 Update README.md 2016-10-22 05:48:59 -04:00
gerrievanzyl
21117eaa17 Add files via upload 2016-10-22 05:32:14 -04:00
gerrievanzyl
573f823f48 Delete DIY_Multiprotocol_Module_Overview.png 2016-10-22 05:31:13 -04:00
gerrievanzyl
47ca3b5d33 Add files via upload 2016-10-22 05:30:43 -04:00
pascallanger
7334134b45 Update README.md 2016-10-21 21:31:08 +02:00
pascallanger
e6be594395 Update README.md 2016-10-21 21:29:57 +02:00
pascallanger
e2b6697362 AFHDS2A addition 2016-10-21 21:28:17 +02:00
pascallanger
f78e11057d ... 2016-10-21 19:57:48 +02:00
pascallanger
314ee96525 AFHDS2A: another trial 2016-10-21 19:39:59 +02:00
pascallanger
efc1223d45 AFHDS2A: again... 2016-10-21 18:37:27 +02:00
pascallanger
38d9aa4997 AFHDS2A: another trial... 2016-10-21 18:10:25 +02:00
pascallanger
42c7431416 AFHDS2A: changes 2016-10-21 10:55:55 +02:00
pascallanger
d1e40ee71c AFHDS2A cosmetic changes 2016-10-20 22:55:50 +02:00
pascallanger
43169d8bab AFHDS2A: few changes 2016-10-20 22:33:37 +02:00
pascallanger
8cbbb52b95 Fixed compilation issues due to AFHDS2A introduction 2016-10-20 21:55:02 +02:00
pascallanger
807a55fcdc AFHDS2A: option value changed
Option value should be between 0 and 70 which gives a value between 50
and 400Hz (value in Hz = 50 + 5*option)
2016-10-20 21:21:10 +02:00
pascallanger
8c5351445b AFHDS2A: Missing static... 2016-10-20 20:35:36 +02:00
pascallanger
999c630c5a AFHDS2A protocol addition: UNTESTED
Protocol number: 28
Sub protocols:  PWM_IBUS = 0, PPM_IBUS = 1, PWM_SBUS = 2, PPM_SBUS = 3
Option value =0->50Hz, =1->400Hz, =2->5Hz
Extended channel range supported
Telemetry supported for voltage and RSSI (RX RSSI)
2016-10-20 19:29:52 +02:00
pascallanger
a0186ce8e4 MJXQ enhancements 2016-10-20 19:29:52 +02:00
gerrievanzyl
9fe336d564 Update Module_Build_yourself_PCB.md 2016-10-18 13:07:52 -04:00
gerrievanzyl
34a1d4e6b9 Update Documentation_To_Do_List.md 2016-10-18 12:54:27 -04:00
gerrievanzyl
bafa548f2f Update Transmitters.md 2016-10-18 12:41:10 -04:00
gerrievanzyl
fa709a9bdc Update Advanced_Topics.md 2016-10-18 12:35:23 -04:00
pascallanger
2a1cc7e3ea Update Protocols_Details.md 2016-10-18 14:38:40 +02:00
pascallanger
68648b9920 Typos... 2016-10-18 09:27:14 +02:00
pascallanger
b9f297935b Added batch file to help compiling OrangeTX 2016-10-17 09:06:21 +02:00
pascallanger
eb6fc4f8cf Fix for STM32 board 2016-10-17 08:37:09 +02:00
pascallanger
8a177c34fa Added Arduino.h for stm32 board 2016-10-16 23:25:52 +02:00
pascallanger
22a5f411d0 Move map redefinition to arduino.ino 2016-10-16 23:12:28 +02:00
pascallanger
f557609e9e STM32 board & DSM fixes
Loads of changes:
STM32 board introduction: NOT TESTED
XMEGA renamed to ORANGE_TX to be more explicit
DSM: added reset if cyrf freezed
Validate: added a validate file to verify the different compilation
options
2016-10-16 19:51:52 +02:00
pascallanger
cde8deaf4b Update Compiling_STM32.md 2016-10-14 11:44:21 -04:00
gerrievanzyl
48eb1c6d67 Update Module_Build_yourself_PCB.md 2016-10-05 17:24:00 -04:00
gerrievanzyl
4db741a87c Update README.md 2016-10-05 17:14:48 -04:00
gerrievanzyl
3188ca6884 Update README.md 2016-10-05 17:14:26 -04:00
gerrievanzyl
bb9cd171bf Delete Protocol_Details.md 2016-10-05 17:12:43 -04:00
gerrievanzyl
7a81638258 Update Compiling_STM32.md 2016-10-05 17:12:19 -04:00
gerrievanzyl
6519db1fe8 Update README.md 2016-10-05 17:11:40 -04:00
gerrievanzyl
f313d319d4 Update README.md 2016-10-05 17:09:55 -04:00
gerrievanzyl
a8c4e6fedc Update Protocols_Details.md 2016-10-05 17:07:29 -04:00
gerrievanzyl
db16458cf5 Update Protocols_Details.md 2016-10-05 17:06:51 -04:00
gerrievanzyl
38a9562eaf Delete Protocols_Details_old.md 2016-10-05 17:06:11 -04:00
gerrievanzyl
b2327e8bf7 Create Protocol_Details_old.md 2016-10-05 17:05:55 -04:00
gerrievanzyl
aafef107ec Create Protocols_Details_old.md 2016-10-05 17:05:25 -04:00
gerrievanzyl
4b442e75f7 Update Protocols_Details.md 2016-10-05 17:04:32 -04:00
gerrievanzyl
e8f103799b Update Compiling.md 2016-10-05 17:04:03 -04:00
gerrievanzyl
618685dc05 Update Compiling.md 2016-10-05 17:01:52 -04:00
gerrievanzyl
f0d50e53fa Update Compiling.md 2016-10-05 17:00:29 -04:00
gerrievanzyl
1b4828f4fa Update Compiling.md 2016-10-05 16:59:03 -04:00
gerrievanzyl
56730d67a2 Update Protocols_Details.md 2016-10-05 16:58:22 -04:00
gerrievanzyl
b02516b0b3 Update Compiling.md 2016-10-05 16:57:23 -04:00
gerrievanzyl
1eb32f86bd Update Protocol_Details.md 2016-10-05 16:53:43 -04:00
gerrievanzyl
3b669e64e2 Update Protocol_Details.md 2016-10-05 16:16:03 -04:00
gerrievanzyl
fbccd70f7d Update Models.md 2016-10-05 16:09:40 -04:00
gerrievanzyl
61e5231d99 Update Models.md 2016-10-05 16:01:01 -04:00
gerrievanzyl
5c101c5a85 Update Models.md 2016-10-05 14:24:37 -04:00
gerrievanzyl
a6e991923e Update Module_Build_yourself_PCB.md 2016-10-05 09:31:14 -04:00
gerrievanzyl
f0c494ecea Update Advanced_ATmega_Serial_Uploader.md 2016-10-05 09:03:42 -04:00
gerrievanzyl
40dfdf9bb1 Update Advanced_Manually_Setting_ATmega328_Fuses.md 2016-10-05 09:01:45 -04:00
gerrievanzyl
770e0f01f1 Update README.md 2016-10-05 08:05:32 -04:00
gerrievanzyl
8448d3e516 Update Tx-erSky9X.md 2016-10-04 20:41:38 -04:00
gerrievanzyl
292a11f942 Update Tx-FlyskyTH9X.md 2016-10-04 20:39:37 -04:00
gerrievanzyl
6099986f5b Update Tx-Taranis.md 2016-10-04 20:37:20 -04:00
gerrievanzyl
53d18d8947 Update Hardware.md 2016-10-04 20:30:58 -04:00
gerrievanzyl
f77bdd233b Update Transmitters.md 2016-10-04 20:29:14 -04:00
gerrievanzyl
dc25a1294c Update README.md 2016-10-04 20:27:33 -04:00
gerrievanzyl
8f4bffa950 Update Tx-Taranis.md 2016-10-04 14:08:45 -04:00
gerrievanzyl
96195fa16a Update Tx-Taranis.md 2016-10-04 14:06:35 -04:00
gerrievanzyl
4e8a59ad4e Update README.md 2016-10-04 14:04:31 -04:00
gerrievanzyl
e42ee6d6be Update README.md 2016-10-04 13:35:23 -04:00
gerrievanzyl
f6a04a8b36 Update Hardware.md 2016-10-04 13:32:32 -04:00
gerrievanzyl
36b94b81ce Update Hardware.md 2016-10-04 13:31:58 -04:00
gerrievanzyl
d66e782152 Update Compiling_STM32.md 2016-10-04 13:04:07 -04:00
gerrievanzyl
d122d39d3a Update Compiling_STM32.md 2016-10-04 13:03:07 -04:00
gerrievanzyl
7c3053e8cd Update Compiling_STM32.md 2016-10-04 13:01:41 -04:00
gerrievanzyl
ecdfa61755 Update Module_OrangeRx.md 2016-10-04 12:43:53 -04:00
gerrievanzyl
7321117c99 Update Module_OrangeRx.md 2016-10-04 12:27:14 -04:00
gerrievanzyl
b50560eadf Update Module_OrangeRx.md 2016-10-04 12:26:51 -04:00
gerrievanzyl
60841e6312 Update Tx-Taranis.md 2016-10-04 11:46:09 -04:00
gerrievanzyl
66cc61f967 Update README.md 2016-10-04 10:19:08 -04:00
gerrievanzyl
1933f4bcc8 Update Transmitters.md 2016-10-03 15:31:26 -04:00
gerrievanzyl
977f5ca9ce Update Transmitters.md 2016-10-03 15:30:23 -04:00
gerrievanzyl
e5e529d3d2 Update Transmitters.md 2016-10-03 15:17:33 -04:00
gerrievanzyl
e1f9d6091c Update Tx-erSky9X.md 2016-10-03 13:40:12 -04:00
gerrievanzyl
a83d8064f2 Create Tx-erSky9X.md 2016-10-03 13:36:16 -04:00
gerrievanzyl
9afb5e7272 Update Transmitters.md
Removed links to firmware - should be on the individual tx pages
updated links to Tx-ersky9X.md
2016-10-03 09:22:57 -04:00
gerrievanzyl
4c7c2ccc74 Update Tx-FlyskyTH9X.md 2016-10-03 09:08:51 -04:00
gerrievanzyl
a6d5686c1c Update Module_Build_yourself_PCB.md 2016-10-02 08:17:32 -04:00
gerrievanzyl
8fa1b92deb Update Tx-FlyskyTH9X.md 2016-10-02 08:11:19 -04:00
gerrievanzyl
f06e3643b6 Update Hardware.md 2016-10-02 08:05:46 -04:00
gerrievanzyl
cd8e59bc9c Update Models.md 2016-09-30 10:40:55 -04:00
gerrievanzyl
b6eeeea1ea Update Module_Build_yourself_PCB.md 2016-09-28 17:26:19 -04:00
gerrievanzyl
aea642fcde Create BOM_DIY_ATmega.md 2016-09-28 17:25:12 -04:00
gerrievanzyl
27bec7ad05 Update BOM_DIY_STM32.md 2016-09-28 17:18:10 -04:00
gerrievanzyl
80cb3458de Update BOM_DIY_STM32.md 2016-09-28 16:55:14 -04:00
gerrievanzyl
615048df04 Update BOM_DIY_STM32.md 2016-09-28 16:54:41 -04:00
gerrievanzyl
4e07b56f3e Update BOM_DIY_STM32.md 2016-09-28 16:54:19 -04:00
gerrievanzyl
7d18da13a1 Update BOM_DIY_STM32.md 2016-09-28 16:44:55 -04:00
gerrievanzyl
a49e9e346f Update BOM_DIY_STM32.md 2016-09-28 16:13:35 -04:00
gerrievanzyl
87fd267183 Update Module_Build_yourself_PCB.md 2016-09-28 15:04:04 -04:00
gerrievanzyl
c61fefb55f Update Module_Build_yourself_PCB.md 2016-09-28 15:03:24 -04:00
gerrievanzyl
c644031041 Update BOM_DIY_STM32.md 2016-09-28 15:02:36 -04:00
gerrievanzyl
79f0f52825 Create BOM_DIY_STM32.md 2016-09-28 14:49:18 -04:00
gerrievanzyl
03ac62044b Update Documentation_To_Do_List.md 2016-09-28 06:13:12 -04:00
gerrievanzyl
531bc0f887 Update Models.md 2016-09-25 09:14:11 -04:00
gerrievanzyl
af8b60ca29 Update Documentation_To_Do_List.md 2016-09-25 08:16:51 -04:00
gerrievanzyl
80c14e9ebd Update Module_Build_yourself_PCB.md 2016-09-25 08:05:11 -04:00
gerrievanzyl
3d658eff29 Update README.md 2016-09-25 08:01:54 -04:00
gerrievanzyl
8a8a75aa79 Update README.md 2016-09-25 08:01:23 -04:00
gerrievanzyl
ea3fe06613 Update Module_BG_4-in-1.md 2016-09-25 07:33:52 -04:00
gerrievanzyl
92e7f6bd68 Update Hardware.md 2016-09-25 07:32:03 -04:00
gerrievanzyl
96b22a00ff Update Hardware.md 2016-09-25 07:25:36 -04:00
gerrievanzyl
cfddbc5b3f Update Hardware.md 2016-09-25 07:23:37 -04:00
gerrievanzyl
725009d719 Update Documentation_To_Do_List.md 2016-09-25 07:19:00 -04:00
gerrievanzyl
7f7370f6db Update Documentation_To_Do_List.md 2016-09-25 07:04:41 -04:00
pascallanger
0fcc1316b2 DSM: 11ms max 10ch after switch to 22ms map 2016-09-25 10:08:29 +02:00
pascallanger
e9933bebe7 DSM: 11ms channel mapping 2016-09-24 13:58:06 +02:00
pascallanger
9810081b11 DSM: cleaned init_vals and data_vals 2016-09-23 21:27:44 +02:00
gerrievanzyl
6522d252cb Update Compiling.md 2016-09-23 11:24:57 -04:00
gerrievanzyl
a2867cffb7 Update Compiling.md 2016-09-23 11:19:48 -04:00
gerrievanzyl
e92c1b53a1 Add files via upload 2016-09-23 17:14:26 +02:00
gerrievanzyl
52aecb47e7 Update Compiling.md 2016-09-23 11:08:58 -04:00
gerrievanzyl
c4652d39fa Update Compiling.md 2016-09-23 11:08:21 -04:00
pascallanger
c7b155ccac Fix OrangeTX pins... 2016-09-23 16:55:28 +02:00
pascallanger
96d18535f8 DSM changes 2016-09-23 16:50:23 +02:00
gerrievanzyl
98471e39e1 Add files via upload 2016-09-23 16:36:17 +02:00
pascallanger
f55fc5776e DSM: Fix Orange RX
Removed Col8 completely from the equation since there are too many
issues with it.
Code cleaning.
2016-09-23 16:01:26 +02:00
gerrievanzyl
f9a8d1cc40 Update Compiling.md 2016-09-23 15:38:59 +02:00
gerrievanzyl
e55a210cf9 Update Tx-FlyskyTH9X.md 2016-09-23 15:34:25 +02:00
gerrievanzyl
d19d4406f6 Update Tx-FlyskyTH9X.md 2016-09-22 23:00:35 +02:00
gerrievanzyl
9697331abb Update Transmitters.md 2016-09-22 22:48:16 +02:00
gerrievanzyl
91db02f2da Update Transmitters.md 2016-09-22 22:39:31 +02:00
gerrievanzyl
b933b30e0a Update Advanced_Bluetooth_Telemetry.md 2016-09-22 22:29:53 +02:00
gerrievanzyl
2cb9a7c199 Update PPM_Setup.md 2016-09-22 22:25:22 +02:00
gerrievanzyl
06ff17ebb2 Update README.md 2016-09-22 22:16:59 +02:00
gerrievanzyl
44a573ecd5 Update README.md 2016-09-22 22:15:43 +02:00
gerrievanzyl
ffa7952fc1 Update Advanced_Bluetooth_Telemetry.md 2016-09-22 22:05:58 +02:00
gerrievanzyl
701514a168 Update Advanced_Topics.md 2016-09-22 22:03:23 +02:00
gerrievanzyl
1565bc9e1a Update Advanced_Topics.md 2016-09-22 22:02:20 +02:00
gerrievanzyl
0681bad8e6 Update Advanced_ATmega_Serial_Uploader.md 2016-09-22 22:01:46 +02:00
gerrievanzyl
23a21bb39f Add files via upload 2016-09-22 21:57:43 +02:00
gerrievanzyl
9aabb575c1 Update Advanced_Topics.md 2016-09-22 21:56:49 +02:00
pascallanger
cf607e892b OrangeTX Cyrf reset pin 2016-09-22 08:29:29 +02:00
pascallanger
6bf906f2a7 Added Multiplex TX end points 2016-09-21 22:07:13 +02:00
pascallanger
7e897d604c Removing unecessary Resets... 2016-09-21 15:05:26 +02:00
pascallanger
39887df3ec OrangeTX code cleanning 2016-09-21 15:00:39 +02:00
pascallanger
fbb7a684bf Fixed OrangeTX compilation 2016-09-21 14:45:17 +02:00
pascallanger
449ad6cd0d DSM2 random channels 2016-09-21 14:29:09 +02:00
pascallanger
cfcd6e5f93 Code cleanup 2016-09-21 14:28:37 +02:00
pascallanger
73aab88109 Some cleanning 2016-09-20 18:27:09 +02:00
pascallanger
beb692a3c4 Fix pins again... 2016-09-20 01:04:25 +02:00
pascallanger
fe8385e759 Update README.md 2016-09-19 23:55:46 +02:00
pascallanger
58fb331019 Update README.md 2016-09-19 23:52:25 +02:00
pascallanger
e4986a6a47 New documentation 2016-09-19 23:48:14 +02:00
pascallanger
fcd47ecec6 Correct pins... 2016-09-19 23:43:14 +02:00
pascallanger
174e6ad637 Merge pull request #15 from bikemike/configurable_pins
made pins configurable and added support for nano
2016-09-19 21:12:08 +02:00
pascallanger
2ac4097e32 Update Protocols_Details.md 2016-09-19 19:23:40 +02:00
pascallanger
dd13ac5cbb Update Protocols_Details.md 2016-09-19 19:18:56 +02:00
pascallanger
9c55a898f7 New DSM protocol
DSM sub_protocols are now:
- DSM2/1024@22ms
- DSM2/2048@11ms
- DSMX/2048@22ms
- DSMX/2048@11ms
Option=number of channels from 4 to 12 for normal receivers or -4 to -12
fro OrangeRX. An invalid option value will end up with 6 channels.
2016-09-19 18:58:09 +02:00
Mike Morrison
bb9018c094 made pins configurable and added support for nano 2016-09-16 20:34:28 -07:00
pascallanger
b09b4183bb DSM revert changes due to issues 2016-09-16 17:59:57 +02:00
pascallanger
3d7bc6583d Fix LED blink in PPM mode 2016-09-16 16:56:46 +02:00
pascallanger
99e8be227e PPM Telemetry: added serial speeds
Only supported for none invert telemetry:
FrSkyD (Incl Hubsan): 9600bps
FrSkyX: 57600bps
DSM: 125000bps
2016-09-16 10:39:44 +02:00
pascallanger
b1c38cc793 Typo... 2016-09-15 16:02:36 +02:00
pascallanger
26e4e70fc8 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-09-15 12:38:58 +02:00
pascallanger
04bdf3f26a Multi core extended to support up to 63 protocols
Compatible with ersky9x at this time.
2016-09-15 12:38:49 +02:00
pascallanger
cafeacf69f Update README.md 2016-09-14 18:29:31 +02:00
pascallanger
4c2d6d78ea E010 now supports multi IDs 2016-09-13 17:21:35 +02:00
pascallanger
ea7d0cdef5 E010 semi arbitrary transmitter ID 2016-09-13 16:38:04 +02:00
pascallanger
47bae63548 Orange TX module compilation fixes 2016-09-12 21:44:30 +02:00
pascallanger
8470f4f7fb DSM: fixed BIND_TEST... 2016-09-12 21:42:55 +02:00
pascallanger
242f9d55ed DSM: loads of changes... 2016-09-12 16:42:13 +02:00
pascallanger
236ac52925 Fix global ID random 2016-09-12 16:41:40 +02:00
pascallanger
baab9a9c89 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-09-12 16:40:51 +02:00
pascallanger
3d26e6e340 Hontai/X5C1 fix 2016-09-12 16:40:45 +02:00
pascallanger
c34ab48972 Update Protocols_Details.md 2016-09-10 10:06:50 +02:00
pascallanger
cf0abf21db Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-09-10 09:42:47 +02:00
pascallanger
7918b392e8 Hontai fix 2016-09-10 09:42:39 +02:00
pascallanger
f0ced15e6a Update Protocols_Details.md 2016-09-10 09:39:33 +02:00
pascallanger
c0204cb725 Update Protocols_Details.md 2016-09-10 09:27:53 +02:00
pascallanger
eb3905447f Hontai channels fix 2016-09-10 09:25:36 +02:00
pascallanger
16c7459906 Merge pull request #14 from klks/master
Fix hontai code for X5C1
2016-09-10 09:12:04 +02:00
klks
eae5f87eed Fix hontai code for X5C1 2016-09-10 11:28:53 +08:00
pascallanger
d4b85e3b1c Hontai protocol & Bit bashing pause/resume 2016-09-09 18:34:29 +02:00
pascallanger
a989c3b7d0 HONTAI protocol addition 2016-09-09 12:15:16 +02:00
pascallanger
d96ba9fa46 Flysky Flash space optimization 2016-09-04 16:49:00 +02:00
pascallanger
2261d655ea DEVO/J6pro Flash space optimization 2016-09-04 16:49:00 +02:00
pascallanger
8b67049863 Added NRF24L01_ReadPayloadLength 2016-09-04 16:49:00 +02:00
pascallanger
48258dd9dd Renamed FrSky protocols 2016-09-03 11:57:40 +02:00
pascallanger
e04c573726 Renamed FrSky protocols 2016-09-03 11:56:39 +02:00
pascallanger
4daec3794e Renamed FrSky protocols to match with receivers 2016-09-03 11:49:25 +02:00
pascallanger
f0646dde32 FrSky1 Fix 2016-09-03 10:12:30 +02:00
pascallanger
ec2086e0f7 Fixed invert serial compilation 2016-09-01 20:12:17 +02:00
pascallanger
2ac704178c FRSKY1 2016-09-01 18:12:35 +02:00
pascallanger
7c43c38e28 FRSKY1 2016-09-01 18:09:35 +02:00
pascallanger
043a8336e5 Code cleaning (XMEGA) 2016-09-01 17:41:38 +02:00
pascallanger
ee27535b82 Update README.md 2016-09-01 14:42:56 +02:00
pascallanger
89e6ae2475 Update Protocols_Details.md 2016-09-01 14:40:17 +02:00
pascallanger
e51615f520 DSM2 renamed to DSM 2016-09-01 14:00:49 +02:00
pascallanger
6e59897587 Update Protocols_Details.md 2016-09-01 13:53:48 +02:00
pascallanger
bd0644a261 Update Protocols_Details.md 2016-09-01 13:53:10 +02:00
pascallanger
d7825e1bf8 Update README.md 2016-09-01 13:47:42 +02:00
pascallanger
97956b6c5e FrSky1 CRC messed up... 2016-09-01 13:42:33 +02:00
pascallanger
8150504ea0 NRF CE 2016-09-01 13:05:56 +02:00
pascallanger
942dec81c7 Typo 2016-09-01 08:08:00 +02:00
pascallanger
dcbc377c62 FrSky1 optim 2016-08-31 15:54:24 +02:00
pascallanger
7b65233699 FrSky 1way protocol + cosmetic 2016-08-31 15:43:45 +02:00
pascallanger
eabfd8b5c4 Important changes of the scheduler and interrupts 2016-08-31 10:26:27 +02:00
pascallanger
b7b2799611 FrSky option applied live 2016-08-31 10:22:36 +02:00
pascallanger
ece59ac374 FrSky ppm option value default 40 2016-08-31 10:20:56 +02:00
pascallanger
83cc8b772c Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-08-31 10:19:59 +02:00
pascallanger
8b5bc18142 YD717 4-in-1 V2 compatibility 2016-08-31 10:19:55 +02:00
pascallanger
e1413baa9a Update Protocols_Details.md 2016-08-30 23:30:18 +02:00
pascallanger
03640e6d37 Changed update_serial_data 2016-08-29 17:32:21 +02:00
pascallanger
2588011524 Orange DSM module update 2016-08-29 09:51:34 +02:00
pascallanger
0c16a6804a E010 2016-08-29 08:29:57 +02:00
pascallanger
e2021fdf5d Update README.md 2016-08-29 08:24:52 +02:00
pascallanger
33b5694d35 MJXQ/E010 mod 2016-08-29 08:23:17 +02:00
pascallanger
af7d04fef6 Added E010 2016-08-28 14:05:21 +02:00
pascallanger
14e3419e4c Added MJXQ / E010 2016-08-28 14:03:22 +02:00
pascallanger
f6c5252376 DEVO PPM fixed id mode 2016-08-27 11:38:07 +02:00
pascallanger
78ee77444f Update README.md 2016-08-27 08:26:05 +02:00
pascallanger
fb022970b5 Update Protocols_Details.md 2016-08-26 21:02:50 +02:00
pascallanger
e5d378dc93 Update Protocols_Details.md 2016-08-26 18:46:03 +02:00
pascallanger
5969902263 MJXQ fix 2016-08-26 17:21:21 +02:00
pascallanger
d5894de142 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-08-26 16:18:58 +02:00
pascallanger
059c6baa4e FrSkyX/SFHSS rfcal & second channel ASSAN 2016-08-26 16:18:50 +02:00
pascallanger
bbf9331baf Update README.md 2016-08-26 10:56:27 +02:00
pascallanger
a5b084f506 Update README.md 2016-08-26 10:55:13 +02:00
pascallanger
3b5471b97c Update Protocols_Details.md 2016-08-25 21:22:33 +02:00
pascallanger
fae37fe67d Update Protocols_Details.md 2016-08-25 19:39:08 +02:00
pascallanger
1f975efda1 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2016-08-25 15:44:11 +02:00
pascallanger
3b3b61f52c DEVO channel order 2016-08-25 15:44:02 +02:00
pascallanger
1c1f6e21c5 Update Protocols_Details.md 2016-08-25 15:40:01 +02:00
pascallanger
8b60c7cc09 Update Protocols_Details.md 2016-08-25 15:30:57 +02:00
pascallanger
d4f9752cd4 Update Protocols_Details.md 2016-08-25 15:29:14 +02:00
pascallanger
6332a37f5b DEVO bind procedure 2016-08-25 15:28:57 +02:00
pascallanger
840a583a0b Devo fix 2016-08-25 14:48:48 +02:00
pascallanger
e7ed80d3e0 Devo fix 2016-08-25 13:42:21 +02:00
pascallanger
c2b9376313 Removed duplicate Telemetry defines 2016-08-25 11:40:38 +02:00
pascallanger
7a8b291189 Couples of fixes and improvements 2016-08-25 11:26:08 +02:00
pascallanger
e63f71d3a7 . 2016-08-24 15:05:31 +02:00
pascallanger
061c97caca New _Config.h file, MJXQ fix, 16 bit regs 2016-08-24 15:05:31 +02:00
pascallanger
988d28f2fd Update README.md 2016-08-23 13:39:10 +02:00
pascallanger
af8a0ea9c0 Update Protocols_Details.md 2016-08-23 13:07:37 +02:00
pascallanger
c78e8d8358 ASSAN protocol and FRSKY/FRSKYX/SFHSS option 2016-08-23 13:06:14 +02:00
pascallanger
392f7098bc ASSAN protocol addition 2016-08-23 12:56:04 +02:00
pascallanger
195f918543 DSM2 bind improvement? 2016-08-22 18:17:14 +02:00
pascallanger
b2579538fa Fix Cyrf reset... 2016-08-21 19:23:41 +02:00
pascallanger
35b97c4f45 Fixed disable telemetry compilation issue 2016-08-21 18:05:16 +02:00
pascallanger
adaa89a963 ASSAN protocol, FQ777 compilation fix on older Arduino 2016-08-21 17:54:12 +02:00
pascallanger
fc1429fae5 FQ777 fixed 2016-08-20 09:13:47 +02:00
pascallanger
4090f95098 Update Protocols_Details.md 2016-08-18 22:01:24 +02:00
pascallanger
3189d8d43e FQ777 2016-08-18 14:15:15 +02:00
pascallanger
cd6d10e428 SFHSS finally fixed 2016-08-17 15:50:59 +02:00
pascallanger
7d37236d78 SFHSS again 2016-08-17 14:28:25 +02:00
pascallanger
7c127acf17 Another SFHSS trial... 2016-08-17 13:44:20 +02:00
pascallanger
0a4ce2350a SFHSS fix? 2016-08-16 16:27:53 +02:00
pascallanger
181a70cb1f SFHSS fix? 2016-08-16 11:06:24 +02:00
pascallanger
7438545a16 Invert serial, optimization and SFHSS 2016-08-15 11:52:43 +02:00
pascallanger
9e902a5dd4 FQ777 Mod and FrSkyX optimization 2016-08-07 18:47:26 +02:00
pascallanger
91e395884f MT99xx->LS: more channels 2016-08-03 23:08:57 +02:00
pascallanger
7107c68a41 MT99xx->LS: more channels 2016-08-03 22:50:37 +02:00
pascallanger
86728b79e3 Fixed FQ777 2016-08-03 17:32:50 +02:00
pascallanger
e04f901590 LS protocol features 2016-08-03 10:12:08 +02:00
pascallanger
47ad2b5cfa MT99xx fix 2016-08-03 09:05:31 +02:00
pascallanger
cea0f1766f Update Protocols_Details.md 2016-08-03 09:05:10 +02:00
pascallanger
407e57d334 Update Protocols_Details.md 2016-08-02 20:55:29 +02:00
pascallanger
c4e66d0c9c Revert throttle on MT99xx... 2016-08-02 20:34:07 +02:00
pascallanger
c54f1ca9b0 Update README.md 2016-08-01 22:08:53 +02:00
pascallanger
f9fdc36d0d Arduino 1.6.10 and extra optimization 2016-08-01 22:06:29 +02:00
pascallanger
6d546094ef New protocols and optimizations
New protocols:
- FQ777 for FQ777-124
- MT99xx -> "LS" for 114/124
2016-08-01 21:57:27 +02:00
pascallanger
8dc5ae4f86 Add FQ777 2016-07-29 23:03:49 +02:00
pascallanger
fd7b81af10 Add FQ777 2016-07-29 22:54:30 +02:00
pascallanger
3abd859664 Update Protocols_Details.md 2016-07-29 11:33:48 +02:00
pascallanger
6134ce39d4 Update README.md 2016-07-29 11:31:12 +02:00
pascallanger
8ea42ea432 Couple of optimizations 2016-07-28 20:58:12 +02:00
pascallanger
fd4ff00ee2 J6Pro channel remapping 2016-07-28 15:01:32 +02:00
pascallanger
9d981b09ca Add J6Pro channels 2016-07-28 14:56:48 +02:00
pascallanger
ed807e0fe5 Add J6Pro in protocol list 2016-07-28 13:02:48 +02:00
pascallanger
32b962b036 J6Pro protocol addition 2016-07-27 22:24:58 +02:00
pascallanger
8ac476b6bd Update README.md 2016-07-27 22:06:13 +02:00
pascallanger
9ab8b84d81 Fixed Frsky telemetry 2016-07-27 20:55:53 +02:00
pascallanger
05cc4b4bd1 Update README.md 2016-07-27 20:22:24 +02:00
pascallanger
b28cf30f47 Update README.md 2016-07-27 20:21:17 +02:00
pascallanger
5bf8b0a2b6 Update README.md 2016-07-27 20:06:51 +02:00
pascallanger
d2891a49fc Update README.md 2016-07-27 20:03:39 +02:00
pascallanger
bec8ba6c2f BG board might need a resistor change to fix bind. 2016-07-27 19:58:50 +02:00
pascallanger
9e097be657 BG module needs to be flashed. 2016-07-27 19:51:19 +02:00
pascallanger
b008f55847 New BG board 2016-07-27 19:46:36 +02:00
pascallanger
487d90f260 Update README.md 2016-05-10 13:32:02 +02:00
pascallanger
671a745acc Update README.md 2016-05-09 15:43:50 +02:00
pascallanger
80880f4d2a Update README.md 2016-05-09 15:37:46 +02:00
pascallanger
109fba828b Update README.md 2016-04-20 19:44:34 +02:00
pascallanger
0a845fdfa6 Update README.md 2016-04-20 19:29:05 +02:00
pascallanger
5a5b8464fc 4in1 module addition 2016-04-20 19:27:56 +02:00
pascallanger
86d0b92a66 MultiOrange one more fix... 2016-04-20 17:53:59 +02:00
pascallanger
9f75234dac Fix xmega compile issue when devo is added 2016-04-20 17:34:28 +02:00
pascallanger
a58b129503 Orange module TAER order and Devo option 2016-04-19 14:29:47 +02:00
pascallanger
6d752acb28 Fixed xn297 scramble mode affecting cx-10a and probably other xn297 based protocols... 2016-04-18 19:43:12 +02:00
pascallanger
4486582006 LT8900 emulator address convention changed, updated Shenqi protocol accordingly. 2016-04-15 15:46:32 +02:00
pascallanger
ed027fd3ce SFHSS change 2016-04-12 15:00:06 +02:00
pascallanger
a92cb848c0 SFHSS change 2016-04-12 08:21:06 +02:00
pascallanger
e573e36aa6 SFHSS change 2016-04-11 21:17:46 +02:00
pascallanger
fc61753953 DSM2/X pncodes fix and FrSky RSSI&TSSI swap fix 2016-04-10 20:04:20 +02:00
pascallanger
9b74e19a99 Update README.md 2016-04-06 15:41:42 +02:00
pascallanger
e9e39cb985 Added all CC2500 power settings 2016-04-06 14:58:06 +02:00
pascallanger
d938f2ea50 Multi core fixes, DSM2/X fixes and telemetry, SFHSS addition, Flysky fixes, FrSkyX full telemetry and sub protocols
Many things since last commit...
2016-04-06 12:57:42 +02:00
pascallanger
6c3535951f Added SFHSS, DSM telemetry, FrSkyX telemetry and sub_protocols 2016-04-06 12:44:04 +02:00
pascallanger
cee78b4ae3 Update README.md 2016-04-06 12:33:43 +02:00
pascallanger
1ee646e1ce Update README.md 2016-04-06 12:32:14 +02:00
pascallanger
6199dec82f Update README.md 2016-03-18 17:20:15 +01:00
pascallanger
59f307bdb3 Update Protocols_Details.md 2016-03-18 17:16:39 +01:00
pascallanger
24747355ce Update README.md 2016-03-18 17:13:20 +01:00
pascallanger
3d287a2827 New FY326 protocol 2016-03-18 17:11:37 +01:00
pascallanger
def28df4dd Update README.md 2016-03-15 13:36:51 +01:00
pascallanger
d90e698a15 Update Protocols_Details.md 2016-03-13 09:39:34 +01:00
pascallanger
f4d6f88e5c Update Protocols_Details.md 2016-03-13 09:30:30 +01:00
pascallanger
799dce4b13 DSM2: Option enables the selection of the number of channels
- 0 : 4 channels @22ms
- 1 : 5 channels @22ms
- 2 : 6 channels @22ms
- 3 : 7 channels @22ms

- 4 : 4 channels @11ms
- 5 : 5 channels @11ms
- 6 : 6 channels @11ms
- 7 : 7 channels @11ms

- 8 : 8 channels @22ms
- 9 : 9 channels @22ms
- 10 : 10 channels @22ms
- 11 : 11 channels @22ms
- 12 : 12 channels @22ms
2016-03-13 09:29:25 +01:00
pascallanger
a025d028d4 Capital 'M' 2016-03-08 22:20:49 +01:00
pascallanger
8cfa9a891d Delete multiprotocol.h 2016-03-08 22:18:44 +01:00
pascallanger
5b44439dd2 Update README.md 2016-03-03 17:10:40 +01:00
pascallanger
44fb7dcdaa Add Arduino Mini has a supported platform. 2016-03-03 16:34:57 +01:00
pascallanger
4f5d1ba26b Correct serial init 2016-03-03 16:26:43 +01:00
pascallanger
0a08b09d70 Update Protocols_Details.md 2016-02-26 19:40:34 +01:00
pascallanger
35eedda352 Update README.md 2016-02-26 19:32:11 +01:00
pascallanger
05fb8bc742 Added Shenqi protocol and LT8910 emulation layer 2016-02-26 19:02:26 +01:00
pascallanger
795df2937e Space and ram optimization on FrSky & FrSkyX 2016-02-15 21:15:09 +01:00
pascallanger
5607740e77 Update Protocols_Details.md 2016-02-13 09:06:58 +01:00
pascallanger
d4287d3046 Update README.md 2016-02-11 23:01:39 +01:00
pascallanger
71ef72bae3 Update README.md 2016-02-11 22:56:26 +01:00
pascallanger
c310d698ca Short description on how to compile 2016-02-11 22:52:41 +01:00
pascallanger
13ce3d1c92 Separate MD files for readability 2016-02-11 22:35:38 +01:00
pascallanger
122ed79a98 Create Protocols_Details.md 2016-02-11 22:29:33 +01:00
pascallanger
6d655242a6 Update list of protocols 2016-02-11 22:11:08 +01:00
pascallanger
09cab9d825 Removed some pics 2016-02-10 16:33:12 +01:00
pascallanger
d8bd38c124 OSH Park link 2016-02-10 16:31:20 +01:00
pascallanger
abc8bf0e62 PCB v2.3d details 2016-02-10 11:39:41 +01:00
pascallanger
24106ac3d2 PCB v2.3d pictures 2016-02-10 11:26:57 +01:00
pascallanger
bf506d382f PCB v2.3d 2016-02-10 10:53:13 +01:00
pascallanger
84b1a9bbec PCB v2.3d 2016-02-10 10:45:35 +01:00
pascallanger
d67afd4396 Update README.md 2016-02-09 08:55:56 +01:00
pascallanger
9f2f7eff5b Update README.md 2016-02-08 09:20:35 +01:00
pascallanger
c863d5976b Fix MT99xx... 2016-02-06 11:33:50 +01:00
pascallanger
d6338e9daf Update README.md 2016-02-05 18:44:26 +01:00
pascallanger
b393d2666d Added FrSkyX protocol, Added MT99xx YZ sub protocol, Ram usage optimization 2016-02-05 17:28:09 +01:00
pascallanger
c5b1e73312 Update README.md 2016-02-04 22:08:07 +01:00
pascallanger
fa65222228 Added FrSkyX description and telemetry info 2016-02-04 21:59:49 +01:00
pascallanger
38e57ccd71 Update README.md 2016-02-04 14:19:48 +01:00
pascallanger
86d3d26273 New protocol MJXQ 2016-02-04 13:35:16 +01:00
pascallanger
db8e4a03a8 New protocol MJXQ and FTDI upload method 2016-02-04 13:24:16 +01:00
pascallanger
c90db8594a Update README.md 2016-02-03 18:32:08 +01:00
pascallanger
855ca77194 Update README.md 2016-02-03 18:24:56 +01:00
pascallanger
4f23af070e Update README.md 2016-02-03 17:49:42 +01:00
pascallanger
626613b545 Update README.md 2016-02-02 16:02:16 +01:00
pascallanger
c26de3bd67 Update README.md 2016-02-02 16:00:34 +01:00
pascallanger
c059915bd3 Update README.md 2016-02-01 15:22:58 +01:00
pascallanger
d2d70dcb38 Update README.md 2016-02-01 15:21:14 +01:00
pascallanger
846292442c CX10 sub protocol details 2016-02-01 15:19:12 +01:00
pascallanger
11283a2199 MT99xx protocol for MT99xx, Eachine H7, Yi Zhan i6S 2016-02-01 13:23:41 +01:00
pascallanger
4c8a0b9a63 MT99XX protocol 2016-02-01 12:18:09 +01:00
pascallanger
54accbf21f CG023 small change 2016-02-01 11:49:10 +01:00
pascallanger
08dc0db2e2 Preparation for new protocol MT99XX (includes H7) 2016-02-01 11:41:36 +01:00
pascallanger
38c6330a2a CX-10A bind improvement 2016-02-01 11:39:36 +01:00
pascallanger
2f983f42fe Update README.md 2016-01-31 22:03:43 +01:00
pascallanger
b9e45c4bb0 Fix: Hubsan telemetry packet check function 2016-01-28 19:31:03 +01:00
pascallanger
9d3b1d75d1 Revert "Fix: Hubsan telemetry packet check function & Change: Telemetry variables to static"
This reverts commit ac78ddcc82.
2016-01-28 19:27:56 +01:00
pascallanger
ac78ddcc82 Fix: Hubsan telemetry packet check function & Change: Telemetry variables to static 2016-01-28 18:43:59 +01:00
pascallanger
f912d84ab6 Telemetry display for Hubsan TX RSSI 2016-01-28 17:27:58 +01:00
pascallanger
85548d6e8e Add: Telemetry display for Hubsan TX RSSI 2016-01-28 17:25:15 +01:00
pascallanger
c74de12ceb Fix: small bug in telemetry for Hubsan 2016-01-28 11:42:56 +01:00
pascallanger
017a21c17f Added: Display error messages if wrong board type is selected at compilation time 2016-01-28 11:26:49 +01:00
pascallanger
9a63038a5f Arduino 1.6.7 support 2016-01-28 10:53:14 +01:00
pascallanger
304fc2536b Fix: Arduino 1.6.7 compilation issues 2016-01-28 10:51:11 +01:00
pascallanger
365169a9fb Update README.md 2016-01-28 09:52:44 +01:00
pascallanger
4b82ead18b Improved Toolchain section 2016-01-28 09:48:19 +01:00
pascallanger
141d7cc268 Update README.md 2016-01-28 09:45:00 +01:00
pascallanger
ee8e94cfb0 Telemetry additions 2016-01-27 18:09:20 +01:00
pascallanger
b50bedef39 Hub telemetry and fix compilation warnings/errors if protocols are commented 2016-01-27 17:57:33 +01:00
pascallanger
a689ce4de9 Fix: Update_aux_flags missplaced for PPM input 2016-01-26 22:33:17 +01:00
pascallanger
ae0478a7e9 Frsky telemetry update 2016-01-26 13:46:38 +01:00
pascallanger
ee6eed5ac5 Update README.md 2016-01-25 18:16:20 +01:00
pascallanger
9140c426c4 New protocol CX-10/Q242 2016-01-25 18:14:56 +01:00
pascallanger
a41bfabede HK310: 2 packets per 5ms + Core: reset CC2500 at boot 2016-01-25 17:23:03 +01:00
pascallanger
5d26357025 Couple of edits... 2016-01-25 17:23:01 +01:00
pascallanger
644c10e994 Update README.md 2016-01-25 17:07:37 +01:00
pascallanger
b3ca0beead Fix typo in ESky 2016-01-23 12:59:28 +01:00
pascallanger
93300c6821 Fix: removed reset of nrf24l01 if not previously used... 2016-01-23 09:03:15 +01:00
pascallanger
2bd8d7ee32 Update README.md 2016-01-22 16:34:34 +01:00
pascallanger
95c339ef74 Update README.md 2016-01-22 16:33:46 +01:00
pascallanger
76ad1d5ef7 Default PPM protocols and settings 2016-01-22 16:30:59 +01:00
pascallanger
151e82a2c3 _Config.h file and all protocol settings for PPM mode 2016-01-22 16:23:59 +01:00
pascallanger
3fcaf93788 Update README.md 2016-01-21 17:26:31 +01:00
pascallanger
b8927d66e9 PPM fix 2016-01-20 21:30:37 +01:00
pascallanger
9273f364fc Update README.md 2016-01-20 14:34:29 +01:00
pascallanger
bc42dbf88a Core and all protocols have been updated
Lot of changes in this new master
ChangeLog:
- Core: LED flashing when an invalid protocol has been selected
- Core: Channels 5 to 12 available as switches for all protocols: code
and size optimization
- Documentation (readme.md): fully updated, all protocols/sub
protocols/channels described, models example, many improvements
- All protocols have been updated in some way, here are some highlights:
* Bayang: added picture, video and inverted channels
* CG023->H8_3D: added light and calibration channels
* CX10: added sub protocols Q282, JC3015_1, JC3015_2, MK33041
* ESky: added new protocol - untested
* Hubsan: added compatibility with the new Hubsan Plus protocol
* KN: fully rewritten protocol: added sub protocols WLTOYS and FEILUN,
11 channels support

New version successfully tested on all my models: Flysky RX/F939/V911
protocol Flysky, Frsky RX protocol Frsky, Hubsan X4 protocol Hubsan,
Hisky HCP100/HCP80 protocol Hisky, HK-3000/HK3100 RX protocol
Hisky/HK310, XINXUN X39 protocol YD717/XINXUN, Symax X5C-1 protocol
SymaX/SYMAX, Cheerson CX-10A protocol CX10/BLUE, Eachine 3D-X4 protocol
CG023.

To access new protocols from er9x/ersky9x, you need to build a version
from this github repository https://github.com/pascallanger/mbtx based
on the latest er9x r820 and ersky9x r218.
2016-01-20 10:51:17 +01:00
pascallanger
481d4c15d6 Hubsan Plus protocol compatibility 2016-01-19 19:11:56 +01:00
pascallanger
563030e732 Added one more LED status: flash in case of invalid protocol selected 2016-01-19 18:44:08 +01:00
pascallanger
4f9137d009 KN channels and sub protocols 2016-01-19 00:19:32 +01:00
pascallanger
ed1b4d1885 YD717: corrected sub protocol name 2016-01-18 21:01:02 +01:00
pascallanger
6bbcd9020e V2x2 clarification 2016-01-18 18:56:15 +01:00
pascallanger
0ba916a7d6 Syma X5C protocol clarification 2016-01-18 18:21:04 +01:00
pascallanger
cf498462eb Hubsan Plus protocol addition 2016-01-18 17:02:39 +01:00
pascallanger
e8b8b861a4 CX10 new sub protocols 2016-01-18 15:28:11 +01:00
pascallanger
4afb045234 Update README.md 2016-01-18 13:54:09 +01:00
pascallanger
ef5c876085 Update README.md 2016-01-16 22:48:45 +01:00
pascallanger
7fbcfeec9c Update README.md 2016-01-16 12:05:24 +01:00
pascallanger
2981a8ef83 Update README.md 2016-01-15 11:29:22 +01:00
pascallanger
b1e8bfe2ab Update README.md 2016-01-15 11:14:36 +01:00
pascallanger
623d568eb9 Update README.md 2016-01-15 10:40:57 +01:00
pascallanger
3625834be3 Update README.md 2016-01-12 15:52:51 +01:00
pascallanger
925a4f4a57 H8 3D channels clarifications 2016-01-11 11:17:03 +01:00
pascallanger
0729b21e67 H8_3D protocol addition 2016-01-10 16:10:27 +01:00
pascallanger
393d37a8c6 Add H8_3D description 2016-01-10 16:07:27 +01:00
1152 changed files with 249413 additions and 4129 deletions

View File

@@ -0,0 +1,2 @@
:02000000FFFF00
:00000001FF

View File

@@ -0,0 +1,34 @@
:107E0000112484B714BE9FEF9BB99CE395B991E010
:107E100098B98370A9F08AEF80938500109284004E
:107E200085E08093810096BBB09BFECF10928100CD
:107E300093B186B181709C73892B8D3109F0B3D0D9
:107E400082E08093C00088E18093C10086E0809347
:107E5000C20081E28093C400259AC0E0D0E093E0A4
:107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
:107E7000813481F4A6D08EBBABD08EB3823811F49E
:107E800085E006C08EB3813811F484E001C083E040
:107E900091D086C0823411F484E103C0853419F492
:107EA00085E09DD07DC0853541F48BD0C82F89D029
:107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
:107EC0008ED080E0E5CF843609F03DC07AD079D0FD
:107ED000B82E77D0C11520E7D20718F000E011E0E6
:107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
:107EF0008F01BE12FACFCE01905781159E4018F423
:107F0000FE01F7BEE89564D0C115FEE7DF0708F073
:107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
:107F20009D910C01E7BEE89511243296A03821E01E
:107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
:107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
:107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
:107F6000849128D0A01205C02196BA94CB0DD11DC2
:107F700017C0F801F2CF853739F42AD08EE11AD034
:107F800085E918D08FE084CF813549F421D080E194
:107F900011D08091C00086FFFCCF05D001C018D061
:107FA00080E108D064CFE0E0F0E084918F3F09F0F9
:107FB000099408959091C00095FFFCCF8093C6006E
:107FC00008958091C00087FFFCCF8091C60008957E
:107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
:107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
:0C7FF000E0E6F0E098E1908380830895C3
:0400000300007E007B
:00000001FF

View File

@@ -0,0 +1,504 @@
# Makefile for ATmegaBOOT
# E.Lins, 18.7.2005
# $Id$
#
# Instructions
#
# To make bootloader .hex file:
# make diecimila
# make lilypad
# make ng
# etc...
#
# To burn bootloader .hex file:
# make diecimila_isp
# make lilypad_isp
# make ng_isp
# etc...
# program name should not be changed...
PROGRAM = optiboot
# The default behavior is to build using tools that are in the users
# current path variables, but we can also build using an installed
# Arduino user IDE setup, or the Arduino source tree.
# Uncomment this next lines to build within the arduino environment,
# using the arduino-included avrgcc toolset (mac and pc)
# ENV ?= arduino
# ENV ?= arduinodev
# OS ?= macosx
# OS ?= windows
# enter the parameters for the avrdude isp tool -b19200
#
# These are the parameters for a usb-based STK500v2 programmer.
# Exact type unknown. (historical Makefile values.)
ISPTOOL = stk500v2
ISPPORT = usb
ISPSPEED = -b 57600
#
#
# These are parameters for using an Arduino with the ArduinoISP sketch
# as the programmer. On a mac, for a particular Uno as programmer.
#ISPTOOL = stk500v1 -C /Applications/arduino/arduino-0022/hardware/tools/avr/etc/avrdude.conf
#ISPPORT = /dev/tty.usbmodemfd3141
#ISPSPEED = -b19200
MCU_TARGET = atmega168
LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
# Build environments
# Start of some ugly makefile-isms to allow optiboot to be built
# in several different environments. See the README.TXT file for
# details.
# default
fixpath = $(1)
ifeq ($(ENV), arduino)
# For Arduino, we assume that we're connected to the optiboot directory
# included with the arduino distribution, which means that the full set
# of avr-tools are "right up there" in standard places.
TOOLROOT = ../../../tools
GCCROOT = $(TOOLROOT)/avr/bin/
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
ifeq ($(OS), windows)
# On windows, SOME of the tool paths will need to have backslashes instead
# of forward slashes (because they use windows cmd.exe for execution instead
# of a unix/mingw shell?) We also have to ensure that a consistent shell
# is used even if a unix shell is installed (ie as part of WINAVR)
fixpath = $(subst /,\,$1)
SHELL = cmd.exe
endif
else ifeq ($(ENV), arduinodev)
# Arduino IDE source code environment. Use the unpacked compilers created
# by the build (you'll need to do "ant build" first.)
ifeq ($(OS), macosx)
TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
endif
ifeq ($(OS), windows)
TOOLROOT = ../../../../build/windows/work/hardware/tools
endif
GCCROOT = $(TOOLROOT)/avr/bin/
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
else
GCCROOT =
AVRDUDE_CONF =
endif
#
# End of build environment code.
# the efuse should really be 0xf8; since, however, only the lower
# three bits of that byte are used on the atmega168, avrdude gets
# confused if you specify 1's for the higher bits, see:
# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
#
# similarly, the lock bits should be 0xff instead of 0x3f (to
# unlock the bootloader section) and 0xcf instead of 0x2f (to
# lock it), but since the high two bits of the lock byte are
# unused, avrdude would get confused.
ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
OBJ = $(PROGRAM).o
OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types
# -mshort-calls
DEFS =
LIBS =
CC = $(GCCROOT)avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
OBJCOPY = $(GCCROOT)avr-objcopy
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
SIZE = $(GCCROOT)avr-size
#Voice board test
# ATmega328
#
#atmega328: TARGET = atmega328p
#atmega328: MCU_TARGET = atmega328p
#atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
#atmega328: AVR_FREQ = 12000000L
#atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
#atmega328: $(PROGRAM)_atmega328.hex
#atmega328: $(PROGRAM)_atmega328.lst
atmega328: TARGET = atmega328
atmega328: MCU_TARGET = atmega328p
atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
atmega328: AVR_FREQ = 16000000L
atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
atmega328: $(PROGRAM)_atmega328_16.hex
atmega328: $(PROGRAM)_atmega328_16.lst
xmega32D4: TARGET = atxmega32d4
xmega32D4: MCU_TARGET = atxmega32d4
xmega32D4: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
xmega32D4: AVR_FREQ = 32000000L
xmega32D4: LDSECTIONS = -Wl,--section-start=.text=0x8000
xmega32D4: $(PROGRAM)_xmega32d4.hex
xmega32D4: $(PROGRAM)_xmega32d4.lst
# Test platforms
# Virtual boot block test
virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DVIRTUAL_BOOT'
virboot328: AVR_FREQ = 16000000L
virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
virboot328: $(PROGRAM)_atmega328.hex
virboot328: $(PROGRAM)_atmega328.lst
# 20MHz clocked platforms
#
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
#
pro20: TARGET = pro_20mhz
pro20: MCU_TARGET = atmega168
pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
pro20: AVR_FREQ = 20000000L
pro20: $(PROGRAM)_pro_20mhz.hex
pro20: $(PROGRAM)_pro_20mhz.lst
pro20_isp: pro20
pro20_isp: TARGET = pro_20mhz
# 2.7V brownout
pro20_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
pro20_isp: LFUSE = C6
# 512 byte boot
pro20_isp: EFUSE = 04
pro20_isp: isp
# 16MHz clocked platforms
#
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
#
pro16: TARGET = pro_16MHz
pro16: MCU_TARGET = atmega168
pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
pro16: AVR_FREQ = 16000000L
pro16: $(PROGRAM)_pro_16MHz.hex
pro16: $(PROGRAM)_pro_16MHz.lst
pro16_isp: pro16
pro16_isp: TARGET = pro_16MHz
# 2.7V brownout
pro16_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
pro16_isp: LFUSE = C6
# 512 byte boot
pro16_isp: EFUSE = 04
pro16_isp: isp
# Diecimila, Duemilanove with m168, and NG use identical bootloaders
# Call it "atmega168" for generality and clarity, keep "diecimila" for
# backward compatibility of makefile
#
atmega168: TARGET = atmega168
atmega168: MCU_TARGET = atmega168
atmega168: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
atmega168: AVR_FREQ = 12000000L
atmega168: $(PROGRAM)_atmega168.hex
atmega168: $(PROGRAM)_atmega168.lst
atmega168_isp: atmega168
atmega168_isp: TARGET = atmega168
# 2.7V brownout
atmega168_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega168_isp: LFUSE = FF
# 512 byte boot
atmega168_isp: EFUSE = 04
atmega168_isp: isp
diecimila: TARGET = diecimila
diecimila: MCU_TARGET = atmega168
diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
diecimila: AVR_FREQ = 16000000L
diecimila: $(PROGRAM)_diecimila.hex
diecimila: $(PROGRAM)_diecimila.lst
diecimila_isp: diecimila
diecimila_isp: TARGET = diecimila
# 2.7V brownout
diecimila_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
diecimila_isp: LFUSE = FF
# 512 byte boot
diecimila_isp: EFUSE = 04
diecimila_isp: isp
atmega328_isp: atmega328
atmega328_isp: TARGET = atmega328
atmega328_isp: MCU_TARGET = atmega328p
# 512 byte boot, SPIEN
atmega328_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_isp: LFUSE = FF
# 2.7V brownout
atmega328_isp: EFUSE = FD
atmega328_isp: isp
atmega1284: TARGET = atmega1284p
atmega1284: MCU_TARGET = atmega1284p
atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
atmega1284: AVR_FREQ = 16000000L
atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
atmega1284: $(PROGRAM)_atmega1284p.hex
atmega1284: $(PROGRAM)_atmega1284p.lst
atmega1284_isp: atmega1284
atmega1284_isp: TARGET = atmega1284p
atmega1284_isp: MCU_TARGET = atmega1284p
# 1024 byte boot
atmega1284_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega1284_isp: LFUSE = FF
# 2.7V brownout
atmega1284_isp: EFUSE = FD
atmega1284_isp: isp
# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
#
sanguino: TARGET = atmega644p
sanguino: MCU_TARGET = atmega644p
sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
sanguino: AVR_FREQ = 16000000L
sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
sanguino: $(PROGRAM)_atmega644p.hex
sanguino: $(PROGRAM)_atmega644p.lst
sanguino_isp: sanguino
sanguino_isp: TARGET = atmega644p
sanguino_isp: MCU_TARGET = atmega644p
# 1024 byte boot
sanguino_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
sanguino_isp: LFUSE = FF
# 2.7V brownout
sanguino_isp: EFUSE = FD
sanguino_isp: isp
# Mega has a minimum boot size of 1024 bytes, so enable extra functions
#mega: TARGET = atmega1280
mega1280: MCU_TARGET = atmega1280
mega1280: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
mega1280: AVR_FREQ = 16000000L
mega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
mega1280: $(PROGRAM)_atmega1280.hex
mega1280: $(PROGRAM)_atmega1280.lst
mega1280_isp: mega
mega1280_isp: TARGET = atmega1280
mega1280_isp: MCU_TARGET = atmega1280
# 1024 byte boot
mega1280_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
mega1280_isp: LFUSE = FF
# 2.7V brownout
mega1280_isp: EFUSE = FD
mega1280_isp: isp
# ATmega8
#
atmega8: TARGET = atmega8
atmega8: MCU_TARGET = atmega8
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
atmega8: AVR_FREQ = 16000000L
atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
atmega8: $(PROGRAM)_atmega8.hex
atmega8: $(PROGRAM)_atmega8.lst
atmega8_isp: atmega8
atmega8_isp: TARGET = atmega8
atmega8_isp: MCU_TARGET = atmega8
# SPIEN, CKOPT, Bootsize=512B
atmega8_isp: HFUSE = CC
# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
atmega8_isp: LFUSE = BF
atmega8_isp: isp
# ATmega88
#
atmega88: TARGET = atmega88
atmega88: MCU_TARGET = atmega88
atmega88: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
atmega88: AVR_FREQ = 12000000L
atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
atmega88: $(PROGRAM)_atmega88.hex
atmega88: $(PROGRAM)_atmega88.lst
atmega88_isp: atmega88
atmega88_isp: TARGET = atmega88
atmega88_isp: MCU_TARGET = atmega88
# 2.7V brownout
atmega88_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
atemga88_isp: LFUSE = FF
# 512 byte boot
atmega88_isp: EFUSE = 04
atmega88_isp: isp
# 8MHz clocked platforms
#
# These are capable of 38400 baud
#
lilypad: TARGET = lilypad
lilypad: MCU_TARGET = atmega168
lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
lilypad: AVR_FREQ = 8000000L
lilypad: $(PROGRAM)_lilypad.hex
lilypad: $(PROGRAM)_lilypad.lst
lilypad_isp: lilypad
lilypad_isp: TARGET = lilypad
# 2.7V brownout
lilypad_isp: HFUSE = DD
# Internal 8MHz osc (8MHz) Slow rising power
lilypad_isp: LFUSE = E2
# 512 byte boot
lilypad_isp: EFUSE = 04
lilypad_isp: isp
lilypad_resonator: TARGET = lilypad_resonator
lilypad_resonator: MCU_TARGET = atmega168
lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
lilypad_resonator: AVR_FREQ = 8000000L
lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
lilypad_resonator_isp: lilypad_resonator
lilypad_resonator_isp: TARGET = lilypad_resonator
# 2.7V brownout
lilypad_resonator_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
lilypad_resonator_isp: LFUSE = C6
# 512 byte boot
lilypad_resonator_isp: EFUSE = 04
lilypad_resonator_isp: isp
pro8: TARGET = pro_8MHz
pro8: MCU_TARGET = atmega168
pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
pro8: AVR_FREQ = 8000000L
pro8: $(PROGRAM)_pro_8MHz.hex
pro8: $(PROGRAM)_pro_8MHz.lst
pro8_isp: pro8
pro8_isp: TARGET = pro_8MHz
# 2.7V brownout
pro8_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
pro8_isp: LFUSE = C6
# 512 byte boot
pro8_isp: EFUSE = 04
pro8_isp: isp
atmega328_pro8: TARGET = atmega328_pro_8MHz
atmega328_pro8: MCU_TARGET = atmega328p
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
atmega328_pro8: AVR_FREQ = 8000000L
atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
atmega328_pro8_isp: atmega328_pro8
atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
atmega328_pro8_isp: MCU_TARGET = atmega328p
# 512 byte boot, SPIEN
atmega328_pro8_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_pro8_isp: LFUSE = FF
# 2.7V brownout
atmega328_pro8_isp: EFUSE = DE
atmega328_pro8_isp: isp
# 1MHz clocked platforms
#
# These are capable of 9600 baud
#
luminet: TARGET = luminet
luminet: MCU_TARGET = attiny84
luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
luminet: AVR_FREQ = 1000000L
luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
luminet: $(PROGRAM)_luminet.hex
luminet: $(PROGRAM)_luminet.lst
luminet_isp: luminet
luminet_isp: TARGET = luminet
luminet_isp: MCU_TARGET = attiny84
# Brownout disabled
luminet_isp: HFUSE = DF
# 1MHz internal oscillator, slowly rising power
luminet_isp: LFUSE = 62
# Self-programming enable
luminet_isp: EFUSE = FE
luminet_isp: isp
#
# Generic build instructions
#
#
isp: $(TARGET)
$(ISPFUSES)
$(ISPFLASH)
isp-stk500: $(PROGRAM)_$(TARGET).hex
$(STK500-1)
$(STK500-2)
%.elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
$(SIZE) $@
clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
%.lst: %.elf
$(OBJDUMP) -h -S $< > $@
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
%.srec: %.elf
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@

View File

@@ -0,0 +1,848 @@
/* Modified to use out for SPM access
** Peter Knight, Optiboot project http://optiboot.googlecode.com
**
** Todo: Tidy up
**
** "_short" routines execute 1 cycle faster and use 1 less word of flash
** by using "out" instruction instead of "sts".
**
** Additional elpm variants that trust the value of RAMPZ
*/
/* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Eric B. Weddington
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
/* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */
#ifndef _AVR_BOOT_H_
#define _AVR_BOOT_H_ 1
/** \file */
/** \defgroup avr_boot <avr/boot.h>: Bootloader Support Utilities
\code
#include <avr/io.h>
#include <avr/boot.h>
\endcode
The macros in this module provide a C language interface to the
bootloader support functionality of certain AVR processors. These
macros are designed to work with all sizes of flash memory.
Global interrupts are not automatically disabled for these macros. It
is left up to the programmer to do this. See the code example below.
Also see the processor datasheet for caveats on having global interrupts
enabled during writing of the Flash.
\note Not all AVR processors provide bootloader support. See your
processor datasheet to see if it provides bootloader support.
\todo From email with Marek: On smaller devices (all except ATmega64/128),
__SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
instructions - since the boot loader has a limited size, this could be an
important optimization.
\par API Usage Example
The following code shows typical usage of the boot API.
\code
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
void boot_program_page (uint32_t page, uint8_t *buf)
{
uint16_t i;
uint8_t sreg;
// Disable interrupts.
sreg = SREG;
cli();
eeprom_busy_wait ();
boot_page_erase (page);
boot_spm_busy_wait (); // Wait until the memory is erased.
for (i=0; i<SPM_PAGESIZE; i+=2)
{
// Set up little-endian word.
uint16_t w = *buf++;
w += (*buf++) << 8;
boot_page_fill (page + i, w);
}
boot_page_write (page); // Store buffer in flash page.
boot_spm_busy_wait(); // Wait until the memory is written.
// Reenable RWW-section again. We need this if we want to jump back
// to the application after bootloading.
boot_rww_enable ();
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
}\endcode */
#include <avr/eeprom.h>
#include <avr/io.h>
#include <inttypes.h>
#include <limits.h>
/* Check for SPM Control Register in processor. */
#if defined (SPMCSR)
# define __SPM_REG SPMCSR
#elif defined (SPMCR)
# define __SPM_REG SPMCR
#else
# error AVR processor does not provide bootloader support!
#endif
/* Check for SPM Enable bit. */
#if defined(SPMEN)
# define __SPM_ENABLE SPMEN
#elif defined(SELFPRGEN)
# define __SPM_ENABLE SELFPRGEN
#else
# error Cannot find SPM Enable bit definition!
#endif
/** \ingroup avr_boot
\def BOOTLOADER_SECTION
Used to declare a function or variable to be placed into a
new section called .bootloader. This section and its contents
can then be relocated to any address (such as the bootloader
NRWW area) at link-time. */
#define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))
/* Create common bit definitions. */
#ifdef ASB
#define __COMMON_ASB ASB
#else
#define __COMMON_ASB RWWSB
#endif
#ifdef ASRE
#define __COMMON_ASRE ASRE
#else
#define __COMMON_ASRE RWWSRE
#endif
/* Define the bit positions of the Boot Lock Bits. */
#define BLB12 5
#define BLB11 4
#define BLB02 3
#define BLB01 2
/** \ingroup avr_boot
\def boot_spm_interrupt_enable()
Enable the SPM interrupt. */
#define boot_spm_interrupt_enable() (__SPM_REG |= (uint8_t)_BV(SPMIE))
/** \ingroup avr_boot
\def boot_spm_interrupt_disable()
Disable the SPM interrupt. */
#define boot_spm_interrupt_disable() (__SPM_REG &= (uint8_t)~_BV(SPMIE))
/** \ingroup avr_boot
\def boot_is_spm_interrupt()
Check if the SPM interrupt is enabled. */
#define boot_is_spm_interrupt() (__SPM_REG & (uint8_t)_BV(SPMIE))
/** \ingroup avr_boot
\def boot_rww_busy()
Check if the RWW section is busy. */
#define boot_rww_busy() (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
/** \ingroup avr_boot
\def boot_spm_busy()
Check if the SPM instruction is busy. */
#define boot_spm_busy() (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE))
/** \ingroup avr_boot
\def boot_spm_busy_wait()
Wait while the SPM instruction is busy. */
#define boot_spm_busy_wait() do{}while(boot_spm_busy())
#define __BOOT_PAGE_ERASE (_BV(__SPM_ENABLE) | _BV(PGERS))
#define __BOOT_PAGE_WRITE (_BV(__SPM_ENABLE) | _BV(PGWRT))
#define __BOOT_PAGE_FILL _BV(__SPM_ENABLE)
#define __BOOT_RWW_ENABLE (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE))
#define __BOOT_LOCK_BITS_SET (_BV(__SPM_ENABLE) | _BV(BLBSET))
#define __boot_page_fill_short(address, data) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
"out %0, %1\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"z" ((uint16_t)address), \
"r" ((uint16_t)data) \
: "r0" \
); \
}))
#define __boot_page_fill_normal(address, data) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"z" ((uint16_t)address), \
"r" ((uint16_t)data) \
: "r0" \
); \
}))
#define __boot_page_fill_alternate(address, data)\
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"z" ((uint16_t)address), \
"r" ((uint16_t)data) \
: "r0" \
); \
}))
#define __boot_page_fill_extended(address, data) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r0, %4\n\t" \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"i" (_SFR_MEM_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint32_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
}))
#define __boot_page_fill_extended_short(address, data) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r0, %4\n\t" \
"movw r30, %A3\n\t" \
"out %1, %C3\n\t" \
"out %0, %2\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"i" (_SFR_IO_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint32_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
}))
#define __boot_page_erase_short(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"out %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_erase_normal(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_erase_alternate(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_erase_extended(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"i" (_SFR_MEM_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
}))
#define __boot_page_erase_extended_short(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"out %1, %C3\n\t" \
"out %0, %2\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"i" (_SFR_IO_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
}))
#define __boot_page_write_short(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"out %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_write_normal(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_write_alternate(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
"z" ((uint16_t)address) \
); \
}))
#define __boot_page_write_extended(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"i" (_SFR_MEM_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
}))
#define __boot_page_write_extended_short(address) \
(__extension__({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"out %1, %C3\n\t" \
"out %0, %2\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"i" (_SFR_IO_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
}))
#define __boot_rww_enable_short() \
(__extension__({ \
__asm__ __volatile__ \
( \
"out %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
); \
}))
#define __boot_rww_enable() \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
); \
}))
#define __boot_rww_enable_alternate() \
(__extension__({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
); \
}))
/* From the mega16/mega128 data sheets (maybe others):
Bits by SPM To set the Boot Loader Lock bits, write the desired data to
R0, write "X0001001" to SPMCR and execute SPM within four clock cycles
after writing SPMCR. The only accessible Lock bits are the Boot Lock bits
that may prevent the Application and Boot Loader section from any
software update by the MCU.
If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit
will be programmed if an SPM instruction is executed within four cycles
after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is
don't care during this operation, but for future compatibility it is
recommended to load the Z-pointer with $0001 (same as used for reading the
Lock bits). For future compatibility It is also recommended to set bits 7,
6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the
Lock bits the entire Flash can be read during the operation. */
#define __boot_lock_bits_set_short(lock_bits) \
(__extension__({ \
uint8_t value = (uint8_t)(~(lock_bits)); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"out %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
}))
#define __boot_lock_bits_set(lock_bits) \
(__extension__({ \
uint8_t value = (uint8_t)(~(lock_bits)); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
}))
#define __boot_lock_bits_set_alternate(lock_bits) \
(__extension__({ \
uint8_t value = (uint8_t)(~(lock_bits)); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
}))
/*
Reading lock and fuse bits:
Similarly to writing the lock bits above, set BLBSET and SPMEN (or
SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an
LPM instruction.
Z address: contents:
0x0000 low fuse bits
0x0001 lock bits
0x0002 extended fuse bits
0x0003 high fuse bits
Sounds confusing, doesn't it?
Unlike the macros in pgmspace.h, no need to care for non-enhanced
cores here as these old cores do not provide SPM support anyway.
*/
/** \ingroup avr_boot
\def GET_LOW_FUSE_BITS
address to read the low fuse bits, using boot_lock_fuse_bits_get
*/
#define GET_LOW_FUSE_BITS (0x0000)
/** \ingroup avr_boot
\def GET_LOCK_BITS
address to read the lock bits, using boot_lock_fuse_bits_get
*/
#define GET_LOCK_BITS (0x0001)
/** \ingroup avr_boot
\def GET_EXTENDED_FUSE_BITS
address to read the extended fuse bits, using boot_lock_fuse_bits_get
*/
#define GET_EXTENDED_FUSE_BITS (0x0002)
/** \ingroup avr_boot
\def GET_HIGH_FUSE_BITS
address to read the high fuse bits, using boot_lock_fuse_bits_get
*/
#define GET_HIGH_FUSE_BITS (0x0003)
/** \ingroup avr_boot
\def boot_lock_fuse_bits_get(address)
Read the lock or fuse bits at \c address.
Parameter \c address can be any of GET_LOW_FUSE_BITS,
GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS.
\note The lock and fuse bits returned are the physical values,
i.e. a bit returned as 0 means the corresponding fuse or lock bit
is programmed.
*/
#define boot_lock_fuse_bits_get_short(address) \
(__extension__({ \
uint8_t __result; \
__asm__ __volatile__ \
( \
"ldi r30, %3\n\t" \
"ldi r31, 0\n\t" \
"out %1, %2\n\t" \
"lpm %0, Z\n\t" \
: "=r" (__result) \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"M" (address) \
: "r0", "r30", "r31" \
); \
__result; \
}))
#define boot_lock_fuse_bits_get(address) \
(__extension__({ \
uint8_t __result; \
__asm__ __volatile__ \
( \
"ldi r30, %3\n\t" \
"ldi r31, 0\n\t" \
"sts %1, %2\n\t" \
"lpm %0, Z\n\t" \
: "=r" (__result) \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"M" (address) \
: "r0", "r30", "r31" \
); \
__result; \
}))
/** \ingroup avr_boot
\def boot_signature_byte_get(address)
Read the Signature Row byte at \c address. For some MCU types,
this function can also retrieve the factory-stored oscillator
calibration bytes.
Parameter \c address can be 0-0x1f as documented by the datasheet.
\note The values are MCU type dependent.
*/
#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
#define boot_signature_byte_get_short(addr) \
(__extension__({ \
uint16_t __addr16 = (uint16_t)(addr); \
uint8_t __result; \
__asm__ __volatile__ \
( \
"out %1, %2\n\t" \
"lpm %0, Z" "\n\t" \
: "=r" (__result) \
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
"r" ((uint8_t) __BOOT_SIGROW_READ), \
"z" (__addr16) \
); \
__result; \
}))
#define boot_signature_byte_get(addr) \
(__extension__({ \
uint16_t __addr16 = (uint16_t)(addr); \
uint8_t __result; \
__asm__ __volatile__ \
( \
"sts %1, %2\n\t" \
"lpm %0, Z" "\n\t" \
: "=r" (__result) \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"r" ((uint8_t) __BOOT_SIGROW_READ), \
"z" (__addr16) \
); \
__result; \
}))
/** \ingroup avr_boot
\def boot_page_fill(address, data)
Fill the bootloader temporary page buffer for flash
address with data word.
\note The address is a byte address. The data is a word. The AVR
writes data to the buffer a word at a time, but addresses the buffer
per byte! So, increment your address by 2 between calls, and send 2
data bytes in a word format! The LSB of the data is written to the lower
address; the MSB of the data is written to the higher address.*/
/** \ingroup avr_boot
\def boot_page_erase(address)
Erase the flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_page_write(address)
Write the bootloader temporary page buffer
to flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_rww_enable()
Enable the Read-While-Write memory section. */
/** \ingroup avr_boot
\def boot_lock_bits_set(lock_bits)
Set the bootloader lock bits.
\param lock_bits A mask of which Boot Loader Lock Bits to set.
\note In this context, a 'set bit' will be written to a zero value.
Note also that only BLBxx bits can be programmed by this command.
For example, to disallow the SPM instruction from writing to the Boot
Loader memory section of flash, you would use this macro as such:
\code
boot_lock_bits_set (_BV (BLB11));
\endcode
\note Like any lock bits, the Boot Loader Lock Bits, once set,
cannot be cleared again except by a chip erase which will in turn
also erase the boot loader itself. */
/* Normal versions of the macros use 16-bit addresses.
Extended versions of the macros use 32-bit addresses.
Alternate versions of the macros use 16-bit addresses and require special
instruction sequences after LPM.
FLASHEND is defined in the ioXXXX.h file.
USHRT_MAX is defined in <limits.h>. */
#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
|| defined(__AVR_ATmega323__)
/* Alternate: ATmega161/163/323 and 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
#define boot_page_erase(address) __boot_page_erase_alternate(address)
#define boot_page_write(address) __boot_page_write_alternate(address)
#define boot_rww_enable() __boot_rww_enable_alternate()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
#elif (FLASHEND > USHRT_MAX)
/* Extended: >16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data)
#define boot_page_erase(address) __boot_page_erase_extended_short(address)
#define boot_page_write(address) __boot_page_write_extended_short(address)
#define boot_rww_enable() __boot_rww_enable_short()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
#else
/* Normal: 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_short(address, data)
#define boot_page_erase(address) __boot_page_erase_short(address)
#define boot_page_write(address) __boot_page_write_short(address)
#define boot_rww_enable() __boot_rww_enable_short()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
#endif
/** \ingroup avr_boot
Same as boot_page_fill() except it waits for eeprom and spm operations to
complete before filling the page. */
#define boot_page_fill_safe(address, data) \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
boot_page_fill(address, data); \
} while (0)
/** \ingroup avr_boot
Same as boot_page_erase() except it waits for eeprom and spm operations to
complete before erasing the page. */
#define boot_page_erase_safe(address) \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
boot_page_erase (address); \
} while (0)
/** \ingroup avr_boot
Same as boot_page_write() except it waits for eeprom and spm operations to
complete before writing the page. */
#define boot_page_write_safe(address) \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
boot_page_write (address); \
} while (0)
/** \ingroup avr_boot
Same as boot_rww_enable() except waits for eeprom and spm operations to
complete before enabling the RWW mameory. */
#define boot_rww_enable_safe() \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
boot_rww_enable(); \
} while (0)
/** \ingroup avr_boot
Same as boot_lock_bits_set() except waits for eeprom and spm operations to
complete before setting the lock bits. */
#define boot_lock_bits_set_safe(lock_bits) \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
boot_lock_bits_set (lock_bits); \
} while (0)
#endif /* _AVR_BOOT_H_ */

View File

@@ -0,0 +1,891 @@
/**********************************************************/
/* Optiboot bootloader for Arduino */
/* */
/* http://optiboot.googlecode.com */
/* */
/* Arduino-maintained version : See README.TXT */
/* http://code.google.com/p/arduino/ */
/* It is the intent that changes not relevant to the */
/* Arduino production envionment get moved from the */
/* optiboot project to the arduino project in "lumps." */
/* */
/* Heavily optimised bootloader that is faster and */
/* smaller than the Arduino standard bootloader */
/* */
/* Enhancements: */
/* Fits in 512 bytes, saving 1.5K of code space */
/* Background page erasing speeds up programming */
/* Higher baud rate speeds up programming */
/* Written almost entirely in C */
/* Customisable timeout with accurate timeconstant */
/* Optional virtual UART. No hardware UART required. */
/* Optional virtual boot partition for devices without. */
/* */
/* What you lose: */
/* Implements a skeleton STK500 protocol which is */
/* missing several features including EEPROM */
/* programming and non-page-aligned writes */
/* High baud rate breaks compatibility with standard */
/* Arduino flash settings */
/* */
/* Fully supported: */
/* ATmega168 based devices (Diecimila etc) */
/* ATmega328P based devices (Duemilanove etc) */
/* */
/* Beta test (believed working.) */
/* ATmega8 based devices (Arduino legacy) */
/* ATmega328 non-picopower devices */
/* ATmega644P based devices (Sanguino) */
/* ATmega1284P based devices */
/* */
/* Alpha test */
/* ATmega1280 based devices (Arduino Mega) */
/* */
/* Work in progress: */
/* ATtiny84 based devices (Luminet) */
/* */
/* Does not support: */
/* USB based devices (eg. Teensy) */
/* */
/* Assumptions: */
/* The code makes several assumptions that reduce the */
/* code size. They are all true after a hardware reset, */
/* but may not be true if the bootloader is called by */
/* other means or on other hardware. */
/* No interrupts can occur */
/* UART and Timer 1 are set to their reset state */
/* SP points to RAMEND */
/* */
/* Code builds on code, libraries and optimisations from: */
/* stk500boot.c by Jason P. Kyle */
/* Arduino bootloader http://arduino.cc */
/* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
/* avr-libc project http://nongnu.org/avr-libc */
/* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */
/* AVR305 Atmel Application Note */
/* */
/* 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 2 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, write */
/* to the Free Software Foundation, Inc., */
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* */
/* Licence can be viewed at */
/* http://www.fsf.org/licenses/gpl.txt */
/* */
/**********************************************************/
/**********************************************************/
/* */
/* Optional defines: */
/* */
/**********************************************************/
/* */
/* BIG_BOOT: */
/* Build a 1k bootloader, not 512 bytes. This turns on */
/* extra functionality. */
/* */
/* BAUD_RATE: */
/* Set bootloader baud rate. */
/* */
/* LUDICROUS_SPEED: */
/* 230400 baud :-) */
/* */
/* SOFT_UART: */
/* Use AVR305 soft-UART instead of hardware UART. */
/* */
/* LED_START_FLASHES: */
/* Number of LED flashes on bootup. */
/* */
/* LED_DATA_FLASH: */
/* Flash LED when transferring data. For boards without */
/* TX or RX LEDs, or for people who like blinky lights. */
/* */
/* SUPPORT_EEPROM: */
/* Support reading and writing from EEPROM. This is not */
/* used by Arduino, so off by default. */
/* */
/* TIMEOUT_MS: */
/* Bootloader timeout period, in milliseconds. */
/* 500,1000,2000,4000,8000 supported. */
/* */
/* UART: */
/* UART number (0..n) for devices with more than */
/* one hardware uart (644P, 1284P, etc) */
/* */
/**********************************************************/
/**********************************************************/
/* Version Numbers! */
/* */
/* Arduino Optiboot now includes this Version number in */
/* the source and object code. */
/* */
/* Version 3 was released as zip from the optiboot */
/* repository and was distributed with Arduino 0022. */
/* Version 4 starts with the arduino repository commit */
/* that brought the arduino repository up-to-date with */
/* the optiboot source tree changes since v3. */
/* */
/**********************************************************/
/**********************************************************/
/* Edit History: */
/* */
/* Nov 2012 */
/* Specific version for 9x voice module */
/* by Mike Blandford */
/* Mar 2012 */
/* 4.5 WestfW: add infrastructure for non-zero UARTS. */
/* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
/* Jan 2012: */
/* 4.5 WestfW: fix NRWW value for m1284. */
/* 4.4 WestfW: use attribute OS_main instead of naked for */
/* main(). This allows optimizations that we */
/* count on, which are prohibited in naked */
/* functions due to PR42240. (keeps us less */
/* than 512 bytes when compiler is gcc4.5 */
/* (code from 4.3.2 remains the same.) */
/* 4.4 WestfW and Maniacbug: Add m1284 support. This */
/* does not change the 328 binary, so the */
/* version number didn't change either. (?) */
/* June 2011: */
/* 4.4 WestfW: remove automatic soft_uart detect (didn't */
/* know what it was doing or why.) Added a */
/* check of the calculated BRG value instead. */
/* Version stays 4.4; existing binaries are */
/* not changed. */
/* 4.4 WestfW: add initialization of address to keep */
/* the compiler happy. Change SC'ed targets. */
/* Return the SW version via READ PARAM */
/* 4.3 WestfW: catch framing errors in getch(), so that */
/* AVRISP works without HW kludges. */
/* http://code.google.com/p/arduino/issues/detail?id=368n*/
/* 4.2 WestfW: reduce code size, fix timeouts, change */
/* verifySpace to use WDT instead of appstart */
/* 4.1 WestfW: put version number in binary. */
/**********************************************************/
#define OPTIBOOT_MAJVER 4
#define OPTIBOOT_MINVER 5
#define MULTI_CALLED 1
#define MAKESTR(a) #a
#define MAKEVER(a, b) MAKESTR(a*256+b)
//asm(" .section .version\n"
// "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
// " .section .text\n");
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
// <avr/boot.h> uses sts instructions, but this version uses out instructions
// This saves cycles and program memory.
#include "boot.h"
// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
#include "pin_defs.h"
#include "stk500.h"
#ifndef LED_START_FLASHES
#define LED_START_FLASHES 0
#endif
#ifdef LUDICROUS_SPEED
#define BAUD_RATE 230400L
#endif
/* set the UART baud rate defaults */
#ifndef BAUD_RATE
#if F_CPU >= 8000000L
#define BAUD_RATE 38400L // Highest rate Avrdude win32 will support
#elsif F_CPU >= 1000000L
#define BAUD_RATE 9600L // 19200 also supported, but with significant error
#elsif F_CPU >= 128000L
#define BAUD_RATE 4800L // Good for 128kHz internal RC
#else
#define BAUD_RATE 1200L // Good even at 32768Hz
#endif
#endif
#ifndef UART
#define UART 0
#endif
#if 0
/* Switch in soft UART for hard baud rates */
/*
* I don't understand what this was supposed to accomplish, where the
* constant "280" came from, or why automatically (and perhaps unexpectedly)
* switching to a soft uart is a good thing, so I'm undoing this in favor
* of a range check using the same calc used to config the BRG...
*/
#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
#ifndef SOFT_UART
#define SOFT_UART
#endif
#endif
#else // 0
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
#error Unachievable baud rate (too slow) BAUD_RATE
#endif // baud rate slow check
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
#error Unachievable baud rate (too fast) BAUD_RATE
#endif // baud rate fastn check
#endif
/* Watchdog settings */
#define WATCHDOG_OFF (0)
#define WATCHDOG_16MS (_BV(WDE))
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
#ifndef __AVR_ATmega8__
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
#endif
/* Function Prototypes */
/* The main function is in init9, which removes the interrupt vector table */
/* we don't need. It is also 'naked', which means the compiler does not */
/* generate any entry or exit code itself. */
int main(void) __attribute__ ((OS_main)) __attribute__ ((noreturn)) __attribute__ ((section (".init9")));
void putch(char);
uint8_t getch(void);
static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
void verifySpace();
#if LED_START_FLASHES > 0
static inline void flash_led(uint8_t);
#endif
uint8_t getLen();
//static inline void watchdogReset();
void watchdogConfig(uint8_t x);
#ifdef SOFT_UART
void uartDelay() __attribute__ ((naked));
#endif
static void appStart() ; // __attribute__ ((naked));
/*
* NRWW memory
* Addresses below NRWW (Non-Read-While-Write) can be programmed while
* continuing to run code from flash, slightly speeding up programming
* time. Beware that Atmel data sheets specify this as a WORD address,
* while optiboot will be comparing against a 16-bit byte address. This
* means that on a part with 128kB of memory, the upper part of the lower
* 64k will get NRWW processing as well, even though it doesn't need it.
* That's OK. In fact, you can disable the overlapping processing for
* a part entirely by setting NRWWSTART to zero. This reduces code
* space a bit, at the expense of being slightly slower, overall.
*
* RAMSTART should be self-explanatory. It's bigger on parts with a
* lot of peripheral registers.
*/
#if defined(__AVR_ATmega168__)
#define RAMSTART (0x100)
#define NRWWSTART (0x3800)
#elif defined(__AVR_ATmega328P__)
#define RAMSTART (0x100)
#define NRWWSTART (0x7000)
#elif defined(__AVR_ATmega328__)
#define RAMSTART (0x100)
#define NRWWSTART (0x7000)
#elif defined (__AVR_ATmega644P__)
#define RAMSTART (0x100)
#define NRWWSTART (0xE000)
// correct for a bug in avr-libc
#undef SIGNATURE_2
#define SIGNATURE_2 0x0A
#elif defined (__AVR_ATmega1284P__)
#define RAMSTART (0x100)
#define NRWWSTART (0xE000)
#elif defined(__AVR_ATtiny84__)
#define RAMSTART (0x100)
#define NRWWSTART (0x0000)
#elif defined(__AVR_ATmega1280__)
#define RAMSTART (0x200)
#define NRWWSTART (0xE000)
#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
#define RAMSTART (0x100)
#define NRWWSTART (0x1800)
#endif
/* C zero initialises all global variables. However, that requires */
/* These definitions are NOT zero initialised, but that doesn't matter */
/* This allows us to drop the zero init code, saving us memory */
#define buff ((uint8_t*)(RAMSTART))
#ifdef VIRTUAL_BOOT_PARTITION
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
#endif
/*
* Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly.
* Note that mega8 still needs special handling, because ubrr is handled
* differently.
*/
#if UART == 0
# define UART_SRA UCSR0A
# define UART_SRB UCSR0B
# define UART_SRC UCSR0C
# define UART_SRL UBRR0L
# define UART_UDR UDR0
#elif UART == 1
# define UART_SRA UCSR1A
# define UART_SRB UCSR1B
# define UART_SRC UCSR1C
# define UART_SRL UBRR1L
# define UART_UDR UDR1
#elif UART == 2
# define UART_SRA UCSR2A
# define UART_SRB UCSR2B
# define UART_SRC UCSR2C
# define UART_SRL UBRR2L
# define UART_UDR UDR2
#elif UART == 3
# define UART_SRA UCSR3A
# define UART_SRB UCSR3B
# define UART_SRC UCSR3C
# define UART_SRL UBRR3L
# define UART_UDR UDR3
#endif
/* main program starts here */
int main(void) {
uint8_t ch;
/*
* Making these local and in registers prevents the need for initializing
* them, and also saves space because code no longer stores to memory.
* (initializing address keeps the compiler happy, but isn't really
* necessary, and uses 4 bytes of flash.)
*/
register uint16_t address = 0;
// After the zero init loop, this is the first code to run.
//
// This code makes the following assumptions:
// No interrupts will execute
// SP points to RAMEND
// r1 contains zero
//
// If not, uncomment the following instructions:
// cli();
asm volatile ("clr __zero_reg__");
#ifdef __AVR_ATmega8__
SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod
ch = MCUSR;
MCUSR = 0;
// Here, if power on, wait 0.5 secs, then check for
// serial Rx signal low, if so, stay in bootloader
// else go to application
PORTD = 0xFF ;
PORTB = 0x3C ;
PORTC = 1 ;
if (ch & (_BV(PORF) | (_BV(EXTRF)) ) )
{
#ifdef MULTI_CALLED
#if F_CPU == 12000000L
TCNT1H = 256 - 8 ;
#else
#if F_CPU == 16000000L
TCNT1H = 256 - 6 ;
#else
TCNT1H = 256 - 127 ;
#endif
TCNT1L = 0 ;
#endif
#else
#if F_CPU == 12000000L
TCNT1 = 65535-5859 ;
#else
#if F_CPU == 16000000L
TCNT1 = 65535-7813 ;
#else
TCNT1 = 65535-32767 ;
#endif
#endif
#endif
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
TIFR1 = _BV(TOV1);
while(!(TIFR1 & _BV(TOV1)))
;
TCCR1B = 0 ; // Stop timer
uint8_t x ;
x = PINB & 0x3C ;
x |= PINC & 1 ;
if ( x != 0x1D )
{
appStart() ; // Power on, go to voice application
// if loaded
}
}
#if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
#endif
#ifndef SOFT_UART
UART_SRA = _BV(U2X0); //Double speed mode USART0
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
// UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
// Baudrate of 57600
#if F_CPU == 12000000L
UART_SRL = 25 ;
#else
#if F_CPU == 16000000L
UART_SRL = 33 ;
#else
#ERROR Baud rate not available
#endif
#endif
#endif
// Set up watchdog to trigger after 500ms
// watchdogConfig(WATCHDOG_1S);
/* Set LED pin as output */
LED_DDR |= _BV(LED);
#ifdef SOFT_UART
/* Set TX pin as output */
UART_DDR |= _BV(UART_TX_BIT);
#endif
#if LED_START_FLASHES > 0
/* Flash onboard LED to signal entering of bootloader */
flash_led(LED_START_FLASHES * 2);
#endif
/* Forever loop */
for (;;)
{
/* get character from UART */
ch = getch();
if(ch == STK_GET_PARAMETER)
{
GPIOR0 = getch();
verifySpace();
if (GPIOR0 == 0x82)
{
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
}
else if (GPIOR0 == 0x81)
{
putch(OPTIBOOT_MAJVER);
}
else
{
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
}
}
else if(ch == STK_SET_DEVICE) {
// SET DEVICE is ignored
getNch(20);
}
else if(ch == STK_SET_DEVICE_EXT)
{
// SET DEVICE EXT is ignored
getNch(5);
}
else if(ch == STK_LOAD_ADDRESS)
{
// LOAD ADDRESS
uint16_t newAddress;
newAddress = getch() ;
newAddress = (newAddress & 0xff) | (getch() << 8);
#ifdef RAMPZ
// Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif
newAddress += newAddress; // Convert from word address to byte address
address = newAddress;
verifySpace();
}
else if(ch == STK_UNIVERSAL)
{
// UNIVERSAL command is ignored
getNch(4);
putch(0x00);
}
/* Write memory, length is big endian and is in bytes */
else if(ch == STK_PROG_PAGE)
{
// PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr;
uint16_t addrPtr;
register uint8_t length;
getch(); /* getlen() */
length = getch();
getch();
// If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
// While that is going on, read in page contents
bufPtr = buff;
do *bufPtr++ = getch();
while (--length);
// If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account
#ifdef MULTI_CALLED
if (address < 0x7E00)
#endif
{
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
}
// Read command terminator, start reply
verifySpace();
// If only a partial page is to be programmed, the erase might not be complete.
// So check that here
#ifdef MULTI_CALLED
if (address < 0x7E00)
#endif
{
boot_spm_busy_wait();
#ifdef VIRTUAL_BOOT_PARTITION
if ((uint16_t)(void*)address == 0) {
// This is the reset vector page. We need to live-patch the code so the
// bootloader runs.
//
// Move RESET vector to WDT vector
uint16_t vect = buff[0] | (buff[1]<<8);
rstVect = vect;
wdtVect = buff[8] | (buff[9]<<8);
vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
buff[8] = vect & 0xff;
buff[9] = vect >> 8;
// Add jump to bootloader at RESET vector
buff[0] = 0x7f;
buff[1] = 0xce; // rjmp 0x1d00 instruction
}
#endif
// Copy buffer into programming buffer
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2;
do {
uint16_t a;
// a = *bufPtr++;
// a |= (*bufPtr++) << 8;
a = *((uint16_t *)bufPtr) ;
bufPtr += 2 ;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
addrPtr += 2;
} while (--ch);
// Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address);
boot_spm_busy_wait();
#if defined(RWWSRE)
// Reenable read access to flash
boot_rww_enable();
#endif
}
}
/* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE)
{
register uint8_t length;
// READ PAGE - we only read flash
getch(); /* getlen() */
length = getch();
getch();
verifySpace();
#ifdef VIRTUAL_BOOT_PARTITION
do {
// Undo vector patch in bottom page so verify passes
if (address == 0) ch=rstVect & 0xff;
else if (address == 1) ch=rstVect >> 8;
else if (address == 8) ch=wdtVect & 0xff;
else if (address == 9) ch=wdtVect >> 8;
else ch = pgm_read_byte_near(address);
address++;
putch(ch);
} while (--length);
#else
#ifdef RAMPZ
// Since RAMPZ should already be set, we need to use EPLM directly.
// do putch(pgm_read_byte_near(address++));
// while (--length);
do {
uint8_t result;
__asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
putch(result);
address++;
}
while (--length);
#else
do putch(pgm_read_byte_near(address++));
while (--length);
#endif
#endif
}
/* Get device signature bytes */
else if(ch == STK_READ_SIGN)
{
// READ SIGN - return what Avrdude wants to hear
verifySpace();
putch(SIGNATURE_0);
putch(SIGNATURE_1);
putch(SIGNATURE_2);
}
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
// Adaboot no-wait mod
// watchdogConfig(WATCHDOG_16MS);
verifySpace();
#ifdef MULTI_CALLED
putch(STK_OK);
while (!(UART_SRA & _BV(TXC0)));
appStart() ;
#endif
}
else
{
// This covers the response to commands like STK_ENTER_PROGMODE
verifySpace();
}
putch(STK_OK);
}
}
void putch(char ch) {
#ifndef SOFT_UART
while (!(UART_SRA & _BV(UDRE0)));
UART_UDR = ch;
#else
__asm__ __volatile__ (
" com %[ch]\n" // ones complement, carry set
" sec\n"
"1: brcc 2f\n"
" cbi %[uartPort],%[uartBit]\n"
" rjmp 3f\n"
"2: sbi %[uartPort],%[uartBit]\n"
" nop\n"
"3: rcall uartDelay\n"
" rcall uartDelay\n"
" lsr %[ch]\n"
" dec %[bitcnt]\n"
" brne 1b\n"
:
:
[bitcnt] "d" (10),
[ch] "r" (ch),
[uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
[uartBit] "I" (UART_TX_BIT)
:
"r25"
);
#endif
}
uint8_t getch(void) {
uint8_t ch;
#ifdef LED_DATA_FLASH
#ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED);
#else
LED_PIN |= _BV(LED);
#endif
#endif
#ifdef SOFT_UART
__asm__ __volatile__ (
"1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge
" rjmp 1b\n"
" rcall uartDelay\n" // Get to middle of start bit
"2: rcall uartDelay\n" // Wait 1 bit period
" rcall uartDelay\n" // Wait 1 bit period
" clc\n"
" sbic %[uartPin],%[uartBit]\n"
" sec\n"
" dec %[bitCnt]\n"
" breq 3f\n"
" ror %[ch]\n"
" rjmp 2b\n"
"3:\n"
:
[ch] "=r" (ch)
:
[bitCnt] "d" (9),
[uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
[uartBit] "I" (UART_RX_BIT)
:
"r25"
);
#else
while(!(UART_SRA & _BV(RXC0)))
// watchdogReset()
;
// if (!(UART_SRA & _BV(FE0))) {
/*
* A Framing Error indicates (probably) that something is talking
* to us at the wrong bit rate. Assume that this is because it
* expects to be talking to the application, and DON'T reset the
* watchdog. This should cause the bootloader to abort and run
* the application "soon", if it keeps happening. (Note that we
* don't care that an invalid char is returned...)
*/
// watchdogReset();
// }
ch = UART_UDR;
#endif
#ifdef LED_DATA_FLASH
#ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED);
#else
LED_PIN |= _BV(LED);
#endif
#endif
return ch;
}
#ifdef SOFT_UART
// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
// Adding 3 to numerator simulates nearest rounding for more accurate baud rates
#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
#if UART_B_VALUE > 255
#error Baud rate too slow for soft UART
#endif
void uartDelay() {
__asm__ __volatile__ (
"ldi r25,%[count]\n"
"1:dec r25\n"
"brne 1b\n"
"ret\n"
::[count] "M" (UART_B_VALUE)
);
}
#endif
void getNch(uint8_t count) {
do getch(); while (--count);
verifySpace();
}
void verifySpace()
{
if ( getch() != CRC_EOP) {
putch(STK_NOSYNC);
// watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
//
// while (1) // and busy-loop so that WD causes
// ; // a reset and app start.
}
putch(STK_INSYNC);
}
#if LED_START_FLASHES > 0
void flash_led(uint8_t count) {
do {
TCNT1 = -(F_CPU/(1024*16));
TIFR1 = _BV(TOV1);
while(!(TIFR1 & _BV(TOV1)));
//#ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED);
//#else
// LED_PIN |= _BV(LED);
//#endif
watchdogReset();
} while (--count);
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
"wdr\n"
);
}
void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart()
{
// watchdogConfig(WATCHDOG_OFF);
// __asm__ __volatile__ (
//#ifdef VIRTUAL_BOOT_PARTITION
// // Jump to WDT vector
// "ldi r30,4\n"
// "clr r31\n"
//#else
// // Jump to RST vector
// "clr r30\n"
// "clr r31\n"
//#endif
// "ijmp\n"
// );
register void (*p)() ;
p = 0 ;
if ( pgm_read_byte( (uint16_t)p ) != 0xFF )
{
(*p)() ;
}
}

View File

@@ -0,0 +1,80 @@
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define LED PINB5
/* Ports for soft UART */
#ifdef SOFT_UART
#define UART_PORT PORTD
#define UART_PIN PIND
#define UART_DDR DDRD
#define UART_TX_BIT 1
#define UART_RX_BIT 0
#endif
#endif
#if defined(__AVR_ATmega8__)
//Name conversion R.Wiersma
#define UCSR0A UCSRA
#define UDR0 UDR
#define UDRE0 UDRE
#define RXC0 RXC
#define FE0 FE
#define TIFR1 TIFR
#define WDTCSR WDTCR
#endif
/* Luminet support */
#if defined(__AVR_ATtiny84__)
/* Red LED is connected to pin PA4 */
#define LED_DDR DDRA
#define LED_PORT PORTA
#define LED_PIN PINA
#define LED PINA4
/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
#ifdef SOFT_UART
#define UART_PORT PORTA
#define UART_PIN PINA
#define UART_DDR DDRA
#define UART_TX_BIT 2
#define UART_RX_BIT 3
#endif
#endif
/* Sanguino support */
#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
/* Onboard LED is connected to pin PB0 on Sanguino */
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define LED PINB0
/* Ports for soft UART */
#ifdef SOFT_UART
#define UART_PORT PORTD
#define UART_PIN PIND
#define UART_DDR DDRD
#define UART_TX_BIT 1
#define UART_RX_BIT 0
#endif
#endif
/* Mega support */
#if defined(__AVR_ATmega1280__)
/* Onboard LED is connected to pin PB7 on Arduino Mega */
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define LED PINB7
/* Ports for soft UART */
#ifdef SOFT_UART
#define UART_PORT PORTE
#define UART_PIN PINE
#define UART_DDR DDRE
#define UART_TX_BIT 1
#define UART_RX_BIT 0
#endif
#endif

View File

@@ -0,0 +1,39 @@
/* STK500 constants list, from AVRDUDE */
#define STK_OK 0x10
#define STK_FAILED 0x11 // Not used
#define STK_UNKNOWN 0x12 // Not used
#define STK_NODEVICE 0x13 // Not used
#define STK_INSYNC 0x14 // ' '
#define STK_NOSYNC 0x15 // Not used
#define ADC_CHANNEL_ERROR 0x16 // Not used
#define ADC_MEASURE_OK 0x17 // Not used
#define PWM_CHANNEL_ERROR 0x18 // Not used
#define PWM_ADJUST_OK 0x19 // Not used
#define CRC_EOP 0x20 // 'SPACE'
#define STK_GET_SYNC 0x30 // '0'
#define STK_GET_SIGN_ON 0x31 // '1'
#define STK_SET_PARAMETER 0x40 // '@'
#define STK_GET_PARAMETER 0x41 // 'A'
#define STK_SET_DEVICE 0x42 // 'B'
#define STK_SET_DEVICE_EXT 0x45 // 'E'
#define STK_ENTER_PROGMODE 0x50 // 'P'
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
#define STK_CHIP_ERASE 0x52 // 'R'
#define STK_CHECK_AUTOINC 0x53 // 'S'
#define STK_LOAD_ADDRESS 0x55 // 'U'
#define STK_UNIVERSAL 0x56 // 'V'
#define STK_PROG_FLASH 0x60 // '`'
#define STK_PROG_DATA 0x61 // 'a'
#define STK_PROG_FUSE 0x62 // 'b'
#define STK_PROG_LOCK 0x63 // 'c'
#define STK_PROG_PAGE 0x64 // 'd'
#define STK_PROG_FUSE_EXT 0x65 // 'e'
#define STK_READ_FLASH 0x70 // 'p'
#define STK_READ_DATA 0x71 // 'q'
#define STK_READ_FUSE 0x72 // 'r'
#define STK_READ_LOCK 0x73 // 's'
#define STK_READ_PAGE 0x74 // 't'
#define STK_READ_SIGN 0x75 // 'u'
#define STK_READ_OSCCAL 0x76 // 'v'
#define STK_READ_FUSE_EXT 0x77 // 'w'
#define STK_READ_OSCCAL_EXT 0x78 // 'x'

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
# See: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
# See: http://code.google.com/p/arduino/wiki/Platforms
##############################################################
menu.bootloader=Bootloader
##############################################################
## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328p
## --------------------------------------------------
multiatmega328p.name=Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)
multiatmega328p.upload.tool=arduino:avrdude
multiatmega328p.upload.protocol=arduino
multiatmega328p.upload.speed=57600
multiatmega328p.upload.maximum_data_size=2048
multiatmega328p.build.mcu=atmega328p
multiatmega328p.build.f_cpu=16000000L
multiatmega328p.build.core=arduino:arduino
multiatmega328p.build.variant=arduino:eightanaloginputs
multiatmega328p.build.extra_flags=-Wl,--relax
multiatmega328p.build.board=MULTI_AVR=102
multiatmega328p.board.compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects
multiatmega328p.board.compiler.c.elf.flags=-Os -g -flto -fuse-linker-plugin -Wl,--gc-sections
multiatmega328p.board.compiler.S.flags=-c -g -x assembler-with-cpp -flto -MMD
multiatmega328p.board.recipe.output.save_file=multi-avr.hex
multiatmega328p.board.tools.avrdude.config.path={path}/etc/avrdude.conf
multiatmega328p.board.tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m
multiatmega328p.board.tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
multiatmega328p.bootloader.tool=arduino:avrdude
multiatmega328p.bootloader.low_fuses=0xFF
multiatmega328p.bootloader.extended_fuses=0xFD
multiatmega328p.bootloader.unlock_bits=0x3F
multiatmega328p.bootloader.lock_bits=0x0F
multiatmega328p.menu.bootloader.none=No bootloader
multiatmega328p.menu.bootloader.none.build.board=MULTI_NO_BOOT=102
multiatmega328p.menu.bootloader.none.upload.maximum_size=32768
multiatmega328p.menu.bootloader.none.bootloader.file=Multi4in1/AtmegaMultiEmpty.hex
multiatmega328p.menu.bootloader.none.bootloader.high_fuses=0xD7
multiatmega328p.menu.bootloader.optiboot=Flash from TX
multiatmega328p.menu.bootloader.optiboot.build.board=MULTI_FLASH_FROM_TX=102
multiatmega328p.menu.bootloader.optiboot.upload.maximum_size=32256
multiatmega328p.menu.bootloader.optiboot.bootloader.file=Multi4in1/AtmegaMultiBoot.hex
multiatmega328p.menu.bootloader.optiboot.bootloader.high_fuses=0xD6
##############################################################
##############################################################
## Multi 4-in-1 (OrangeRX)
## --------------------------------------------------
multixmega32d4.name=Multi 4-in-1 (OrangeRX)
multixmega32d4.build.board=MULTI_ORANGERX=102
multixmega32d4.build.mcu=atxmega32d4
multixmega32d4.build.f_cpu=32000000L
multixmega32d4.build.core=xmega
multixmega32d4.build.variant=xmega32d4
multixmega32d4.upload.tool=arduino:avrdude
multixmega32d4.upload.protocol=avrispmkii
multixmega32d4.upload.maximum_size=32768
multixmega32d4.upload.speed=57600
multixmega32d4.bootloader.tool=arduino:avrdude
multixmega32d4.bootloader.file=Multi4in1/OrangeMultiBoot.hex
multixmega32d4.bootloader.lock_bits=0xFF
multixmega32d4.board.compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto
multixmega32d4.board.compiler.c.elf.flags=-Os -flto -Wl,--gc-sections
multixmega32d4.board.compiler.S.flags=-c -g -x assembler-with-cpp -flto
multixmega32d4.board.recipe.output.save_file=multi-orx.hex
multixmega32d4.board.tools.avrdude.config.path={runtime.platform.path}/avrdude_xmega.conf
multixmega32d4.board.tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Ufuse1:w:{bootloader.fuse1}:m -Ufuse2:w:{bootloader.fuse2}:m -Ufuse4:w:{bootloader.fuse4}:m -Ufuse5:w:{bootloader.fuse5}:m
multixmega32d4.board.tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uboot:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
##############################################################

View File

@@ -0,0 +1,34 @@
:107E0000112484B714BE9FEF9BB99CE395B991E010
:107E100098B98370A9F08AEF80938500109284004E
:107E200085E08093810096BBB09BFECF10928100CD
:107E300093B186B181709C73892B8D3109F0B3D0D9
:107E400082E08093C00088E18093C10086E0809347
:107E5000C20081E28093C400259AC0E0D0E093E0A4
:107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
:107E7000813481F4A6D08EBBABD08EB3823811F49E
:107E800085E006C08EB3813811F484E001C083E040
:107E900091D086C0823411F484E103C0853419F492
:107EA00085E09DD07DC0853541F48BD0C82F89D029
:107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
:107EC0008ED080E0E5CF843609F03DC07AD079D0FD
:107ED000B82E77D0C11520E7D20718F000E011E0E6
:107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
:107EF0008F01BE12FACFCE01905781159E4018F423
:107F0000FE01F7BEE89564D0C115FEE7DF0708F073
:107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
:107F20009D910C01E7BEE89511243296A03821E01E
:107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
:107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
:107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
:107F6000849128D0A01205C02196BA94CB0DD11DC2
:107F700017C0F801F2CF853739F42AD08EE11AD034
:107F800085E918D08FE084CF813549F421D080E194
:107F900011D08091C00086FFFCCF05D001C018D061
:107FA00080E108D064CFE0E0F0E084918F3F09F0F9
:107FB000099408959091C00095FFFCCF8093C6006E
:107FC00008958091C00087FFFCCF8091C60008957E
:107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
:107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
:0C7FF000E0E6F0E098E1908380830895C3
:0400000300007E007B
:00000001FF

View File

@@ -0,0 +1,2 @@
:02000000FFFF00
:00000001FF

View File

@@ -0,0 +1,47 @@
:108000001F92CDB7DEB7CFD01124809178009FEFBB
:1080100090937800837099F088EA91E680936808DD
:108020009093690880E180934C0880914C0884FF0C
:10803000FCCF109240088091680682FD8FD082E0CC
:1080400080936106C12CD12C97D0813479F494D0DF
:10805000898399D08981823811F485E005C08138FF
:1080600011F484E001C083E080D075C0823411F443
:1080700084E103C0853419F485E08CD06CC085356B
:1080800059F47AD0C82E78D0D12CD82A8D2D881FBB
:108090008827881F8BBF5EC0863521F484E07AD0A4
:1080A00080E0E2CF843641F567D066D0F82E64D008
:1080B000C601DCD000E010E25FD0F80181938F01AF
:1080C000FE12FACF60D0D7FC46C0CBD0C601DAD0C2
:1080D000760100E010E2F801619171918F01C70112
:1080E000DBD0F2E0EF0EF11C011581E2180799F7E1
:1080F000C601E0D0B6D02FC08437C1F43DD03CD00B
:10810000F82E3AD040D0F601EC2CEF0C8F010F5F27
:108110001F4F84912AD0E01207C0EFEFCE1ADE0A7B
:10812000FA94CF0CD11C17C0F801F0CF853739F481
:108130002AD08EE11AD085E918D082E495CF813516
:1081400049F421D080E111D08091A10886FFFCCFB5
:1081500005D001C018D080E108D076CFE0E0F0E093
:1081600084918F3F09F0099408959091A10895FF9B
:10817000FCCF8093A00808958091A10887FFFCCFD1
:108180008091A0080895F8DF803211F085E1EDDFDD
:1081900084E1EBCFCF93C82FEFDFC150E9F7CF9148
:1081A000F2CFA895089583EC8093520080915000FF
:1081B0008860809350008091510083FFFCCF82EC57
:1081C0008093550080915000806180935000809191
:1081D000510084FFFCCF88ED84BF1092400084BF23
:1081E00024E02093400087E08093A20087E88093FA
:1081F0008301109241081092420810924308109295
:10820000440810924608109247088FEF9FEF809322
:1082100066089093670810926008109261088BE0DE
:1082200080934008209365062093620688E180933E
:10823000720698E0909345069093410692E29093DF
:10824000A6081092A7088093A4088091A3088F7CA9
:1082500080618093A30883E08093A5088091A008A3
:1082600008958091CF0187FDFCCF08958F939F9350
:1082700082E2E0ECF1E08287FF91EF918DE984BF2B
:10828000E8950895FC0186E28093CA0188ED84BFD9
:1082900081E08093CB0108950F921F92FC01062E7E
:1082A000172E83E28093CA018DE984BFE8951F9061
:1082B0000F900895FC018EE28093CA018DE984BF7E
:0482C000E8950895A0
:040000030000800079
:00000001FF

View File

@@ -0,0 +1,450 @@
/*
Arduino.h - standard definitions for Arduino build environment
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis [duplicated from pins_arduino.h, not present in original]
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
for the XMegaForArduino project - http://github.com/XMegaForArduino
In some cases, the xmega updates make assumptions about the pin assignments.
See 'pins_arduino.h' for more detail.
*/
#ifndef Arduino_h
#define Arduino_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "binary.h"
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0 /* totem poll, input */
#define OUTPUT 0x1 /* totem poll, output */
#define INPUT_BUS_KEEPER 0x2 /* weak pull up/down to maintain state when switched to or in input mode */
#define INPUT_PULLUP 0x3 /* pullup resistor on input */
#define INPUT_PULLDOWN 0x4 /* pulldown resistor on input */
#define OUTPUT_OR 0x5 /* output open drain 'or', no pulldown */
#define OUTPUT_AND 0x6 /* output open drain 'and', no pullup */
#define INPUT_OR_PULLDOWN 0x7 /* output open drain 'or' with pulldown */
#define INPUT_AND_PULLUP 0x8 /* output open drain 'and' with pullup */
#define OUTPUT_OR_PULLDOWN 0x9 /* output open drain 'or' with pulldown */
#define OUTPUT_AND_PULLUP 0xa /* output open drain 'and' with pullup */
#define INPUT_OUTPUT_MASK 0xf /* mask for INPUT/OUTPUT flags */
#define INPUT_SENSE_DEFAULT 0 /* input sense default - currently 'BOTH' */
#define INPUT_SENSE_RISING 0x10 /* just rising */
#define INPUT_SENSE_FALLING 0x20 /* just falling */
#define INPUT_SENSE_BOTH 0x30 /* rising AND falling */
#define INPUT_SENSE_LEVEL 0x40 /* high level (or low if I invert it) */
#define INPUT_SENSE_DISABLED 0x50 /* buffered input disabled (most pins won't be able to use 'IN' if you do this) */
#define INPUT_SENSE_MASK 0x70 /* mask for 'input sense' bits */
#define INPUT_OUTPUT_INVERT 0x80 /* bit for 'inverted' I/O - note that digitalRead and digitalWrite will re-invert to maintain consistency */
// NOTE: 'INPUT_OUTPUT_INVER' is primarily there to support LOW LEVEL interrupts. if you specify this flag for normal
// digital I/O, there will be no 'visible effect' since digitalRead and digitalWrite will "re-invert" the bit value
// and act as if the invert flag weren't set. That way, if you select 'LOW LEVEL' interrupt, you will read the
// low level as a '0' (as it should be) via digitalRead, even though the value MUST be inverted for this to work.
// NOTE: the values of 'true' and 'false' should be defined by C++ already
#define true /*0x1*/(!0) /* rather than '1' true is defined as '!0' - it's logically accurate */
#define false 0x0
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
/* I do not know what these next 4 #defines do, but all 4 seem to be WRONG - bf */
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
// INTERRUPT TYPE - LOW, HIGH, CHANGE, FALLING, RISING (compatibility with DUE etc.)
// 'LOW' is defined as '0' already
// 'HIGH' is defined as '1' already
#define CHANGE 2
#define FALLING 3
#define RISING 4
// definitions for atmega328 etc. carried forward - not sure what this is for
#define INTERNAL 3
#define DEFAULT 1
#define EXTERNAL 0
// undefine stdlib's abs if encountered (from 'arduino' version)
#ifdef abs
#undef abs
#endif
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define interrupts() sei()
#define noInterrupts() cli()
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
typedef unsigned int word;
#define bit(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void init(void);
void initVariant(void);
int atexit(void (*func)()) __attribute__((weak));
void adc_setup(void); // implemented in wiring_analog.c - configures ADC for analogRead()
// adc_setup must be called whenever exiting SLEEP MODE or ADC will malfunction
// It is automatically called from 'init()' but sleep mode typically resets the controller
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode); // somewhat different for xmega (default is Vcc/2) - see 'enum _analogReference_', below
// pass only one of THOSE values as 'mode'
void analogWrite(uint8_t, int);
// special XMEGA-specific functions for the analog inputs
int analogReadDeltaWithGain(uint8_t pin, uint8_t negpin, uint8_t gain);
// typically 'pin' can be A0 through An, 'negpin' may be restricted but typically A4-A7 or 'ANALOG_READ_DELTA_USE_GND' to use GND
// NOTE: On the A-series processors it is NOT possible to use 'diff input with gain' on MORE than A0-A7
// On later processors (like D series) it _IS_ possible.
#define ANALOG_READ_DELTA_USE_GND 0xff
// there is a bug in several headers for ADC_REFSEL_gm - should be 0x70, not 0x30 (and it gets re-defined, too)
#ifdef ADC_REFSEL_gm
#undef ADC_REFSEL_gm
#endif // ADC_REFSEL_gm
#define ADC_REFSEL_gm 0x70
enum _analogReference_ // pass to 'analogReference' function - see D manual section 22.14.3, or 28.16.3 in 'AU' manual
{
analogReference_INT1V = (ADC_REFSEL_INT1V_gc),
analogReference_PORTA0 = (ADC_REFSEL_AREFA_gc), // PORT A pin 0 is the AREF
#if !defined (__AVR_ATxmega8E5__) && !defined (__AVR_ATxmega16E5__) && !defined (__AVR_ATxmega32E5__)
// these 2 aren't valid for 'E' series
analogReference_PORTB0 = (ADC_REFSEL_AREFB_gc), // PORT B pin 0 is the AREF
analogReference_VCC = (ADC_REFSEL0_bm) /* (ADC_REFSEL_VCC_gc)*/, // VCC / 10, actually
// NOTE: 'ADC_REFSEL_VCC_gc' exists for some headers, and others 'ADC_REFSEL_INTVCC_gc'
// to avoid compile problems I use the bitmask instead.
#endif // E series
#if defined(__AVR_ATxmega64d4__) || defined(__AVR_ATxmega64a1u__) || defined(__AVR_ATxmega128a1u__)
analogReference_VCCDIV2 = (ADC_REFSEL_VCCDIV2_gc) // using THIS forces gain to 1/2, so it's rail-rail
#else
analogReference_VCCDIV2 = (0x04<<4) // (ADC_REFSEL_VCCDIV2_gc)
// NOTE that for some processor headers, ADC_REFSEL_VCCDIV2_gc is not properly defined
// this definition '(0x04<<4)' is taken from the 64d4 header. it's also THE DEFAULT for max compatibility
#endif // processors that define ADC_REFSEL_VCCDIV2_gc correctly
};
// NOTE: this constant isn't always defined, either
#ifndef ADC_CH_GAIN_gm
#define ADC_CH_GAIN_gm 0x1C /* Gain Factor group mask. */
#endif // ADC_CH_GAIN_gm
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
// XMEGA specific
void wait_for_interrupt(void); // uses 'IDLE' sleep mode to wait for an interrupt, then returns
void low_power_delay(unsigned long ms); // similar to 'delay' but goes into low power 'IDLE sleep' state
// X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A
//
// NOTE: for 'attachInterrupt' the 'mode' parameter indicates non-default input pins
// and the interrupt mode, as well as the interrupt priority. If the interrupt
// priority is INT_MODE_PRI_DEFAULT (0), it will be assigned a 'default' value.
// Default interrupt pin is pin 2 except for PORTR (since it doesn't have a pin 2)
// when it has not been specified.
//
// usage:
// attachInterrupt(PORTD_INT0, the specific interrupt vector - see pins_arduino.h
// my_callback, user-defined callback function
// RISING interrupt mode (can be LOW, HIGH, RISING, FALLING, CHANGE)
// | INT_MODE_PIN_DEFAULT the pin(s) to assign to this interrupt, or default pin 2 (optional)
// | INT_MODE_PRI_DEFAULT); interrupt priority, default is 'high' (optional)
//
// Additional note, the 'pin' constants (see below) refer to the port's pin number, and
// NOT the 'digital I/O pin' number. See 'pins_arduino.h' for more on this.
//
// for compatibility with newer arduino environment, attachInterrupt 'interruptNum' parameter
// can use the return value from 'digitalPinToInterrupt(pin)'
//
// X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A
#ifdef __cplusplus
void attachInterrupt(uint8_t interruptNum, void (*)(void), int mode = 0); // default 'mode' param is: LOW | INT_MODE_PRI_DEFAULT | INT_MODE_PIN_DEFAULT
#else // not __cplusplus
void attachInterrupt(uint8_t interruptNum, void (*)(void), int mode);
#endif // __cplusplus
void detachInterrupt(uint8_t interruptNum); // NOTE: detaches ALL interrupts for that port (special exceptions for serial flow control)
// this next function reads data from the calibration row, including the serial # info.
// This is often referred to as the 'PRODUCT SIGNATURE ROW'. It is xmega-specific.
uint8_t readCalibrationData(uint16_t iIndex);
// INTERRUPT MODE FLAGS - for attachInterrupt 'mode' parameter
#define INT_MODE_MODE_MASK 0x003f
#define INT_MODE_PRI_MASK 0x00c0
#define INT_MODE_PRI_DEFAULT 0
#define INT_MODE_PRI_LOW 0x0040
#define INT_MODE_PRI_MED 0x0080
#define INT_MODE_PRI_HIGH 0x00c0
#define INT_MODE_PRI_SHIFT 6 /* shift right 6 bits to get a 0, 1, 2 or 3 for priority (0 is 'default') */
#define INT_MODE_PIN_MASK 0xff00
#define INT_MODE_PIN0 0x0100
#define INT_MODE_PIN1 0x0200
#define INT_MODE_PIN2 0x0400
#define INT_MODE_PIN3 0x0800
#define INT_MODE_PIN4 0x1000
#define INT_MODE_PIN5 0x2000
#define INT_MODE_PIN6 0x4000
#define INT_MODE_PIN7 0x8000
#define INT_MODE_PIN_DEFAULT 0 /* no 'pin bits' set implies 'default' which is pin 2 on each capable port */
#define INT_MODE_PIN_SHIFT 8 /* shift right 8 bits to get the pin bits in a single byte */
// NOTE: the 'pin' constants refer to the port's pin number, and not the digital I/O pin
// The default 'pin 2' refers to the port's pin 2. See 'pins_arduino.h' for more on this.
// Multiple pins may be specified, so it is a bit mask. If a pin is specified by using
// digitalPinToInterrupt() and you also specify pins using the 'INT_MODE_PINx' flags, the
// pin specified in the 'interruptNum' parameter will be 'or'd with the pins specified in
// 'mode'. This can result in some unpredictable outcomes, so you should either use
// 'digitalPinToInterrupt' for 'interruptNum', or specify the port as 'interruptNum' and
// then specfify the pin info in 'mode'.
#define NOT_AN_INTERRUPT (-1) /* a placeholder for various arrays, etc. */
// SETUP and LOOP (no changes from Arduino classic)
void setup(void);
void loop(void);
// hardware flow control 'helpers'
void serial_0_cts_callback(void);
void serial_1_cts_callback(void);
void InitSerialFlowControlInterrupts(void);
// On the xmega, the addresses of the port registers are
// greater than 255, so we can't store them in uint8_t's.
extern const uint16_t PROGMEM port_to_mode_PGM[];
extern const uint16_t PROGMEM port_to_input_PGM[];
extern const uint16_t PROGMEM port_to_output_PGM[];
extern const uint16_t PROGMEM digital_pin_to_control_PGM[];
// these contain index values so they CAN be uint8_t's
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; not used on xmega
extern const uint16_t PROGMEM port_to_input_PGM[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
// note pins_arduino.h may need to override this next one, depending
#define analogInPinToBit(P) ((P) & 7) /* analog pin 0 = 0 (PORTA), analog pin 8 = 0 (PORTB) */
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
#define pinControlRegister(P) ( (volatile uint8_t *)( pgm_read_word( digital_pin_to_control_PGM + (P))) )
// use THIS macro to convert a _BV(n) value into 'n'
#define pinBitValueToIndex(B) ( (B)==_BV(0) ? 0 : (B)==_BV(1) ? 1 : (B)==_BV(2) ? 2 : (B)==_BV(3) ? 3 : \
(B)==_BV(4) ? 4 : (B)==_BV(5) ? 5 : (B)==_BV(6) ? 6 : (B)==_BV(7) ? 7 : 0 )
#define NOT_A_PIN 0
#define NOT_A_PORT 0
#ifdef ARDUINO_MAIN
// use of '_' prefix to prevent collisions with iox64d#.h and for consistency
#define _PA 1
#define _PB 2
#define _PC 3
#define _PD 4
#define _PE 5
#define _PR 6 /* was PF */
#define _PF 7
#define _PH 8
#define _PJ 9
#define _PK 10
#define _PQ 11
#endif
// modified timer definitions for xmega
// TCD2 --> TIMERD2
// TCC2 --> TIMERC2
// TCE0 --> TIMERE0 - 'D' series which has only 4 pins on PORTE */
// TCE2 --> TIMERE2 - A series and others that use all 8 pins for port E
// TCF2 --> TIMERF2 - A series and others that have PORT F
#define NOT_ON_TIMER 0
#define TIMERD2 1
#define TIMERC2 2
#define TIMERE0 3
#define TIMERE2 4
#define TIMERF2 5
#define TIMERC4 6
#define TIMERD5 7
// not using TCD0,1 nor TCC0,1
// The first 16 IO pins (PD0-PD7, PC0-PC7) will be PWM capable, as are PE0-PE3 (or PE0-PE7) and PF0-PF7 (when there)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
#if 0
// these are not currently implemented - TODO implement them
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
#endif // 0
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);
#endif // __cplusplus
// at this point we include the pin definitions from 'pins_arduino.h'
// you can customize 'pins_arduino.h' for your specific hardware
#include "pins_arduino.h"
// The default SPI interface is SPIC if not already defined
#ifndef DEFAULT_SPI
#define DEFAULT_SPI SPIC
#endif // DEFAULT_SPI
// the default TWI interface is TWIC if not already defined
#ifndef DEFAULT_TWI
#define DEFAULT_TWI TWIC
#endif // DEFAULT_TWI
// added support for hardware serial flow control - spans multiple files
#if defined(SERIAL_0_RTS_PORT_NAME) && defined(SERIAL_0_RTS_PIN_INDEX)
#define SERIAL_0_RTS_ENABLED
#define SERIAL_0_RTS_PORT (&SERIAL_0_RTS_PORT_NAME)
#define SERIAL_0_RTS_PIN _BV(SERIAL_0_RTS_PIN_INDEX)
#endif // defined(SERIAL_0_RTS_PORT) && defined(SERIAL_0_RTS_PIN)
#if defined(SERIAL_1_RTS_PORT_NAME) && defined(SERIAL_1_RTS_PIN_INDEX)
#define SERIAL_1_RTS_ENABLED
#define SERIAL_1_RTS_PORT (&SERIAL_1_RTS_PORT_NAME)
#define SERIAL_1_RTS_PIN _BV(SERIAL_1_RTS_PIN_INDEX)
#endif // defined(SERIAL_1_RTS_PORT) && defined(SERIAL_1_RTS_PIN)
#if defined(SERIAL_0_CTS_PORT_NAME) && defined(SERIAL_0_CTS_PIN_INDEX)
#define SERIAL_0_CTS_ENABLED
#define SERIAL_0_CTS_PORT (&SERIAL_0_CTS_PORT_NAME)
#define SERIAL_0_CTS_PIN _BV(SERIAL_0_CTS_PIN_INDEX)
#endif // defined(SERIAL_0_CTS_PORT) && defined(SERIAL_0_CTS_PIN)
#if defined(SERIAL_1_CTS_PORT_NAME) && defined(SERIAL_1_CTS_PIN_INDEX)
#define SERIAL_1_CTS_ENABLED
#define SERIAL_1_CTS_PORT (&SERIAL_1_CTS_PORT_NAME)
#define SERIAL_1_CTS_PIN _BV(SERIAL_1_CTS_PIN_INDEX)
#endif // defined(SERIAL_1_CTS_PORT) && defined(SERIAL_1_CTS_PIN)
#endif // Arduino_h

View File

@@ -0,0 +1,541 @@
//////////////////////////////////////////////////////////////////////////////
// //
// ____ ____ ____ //
// / ___|| _ \ / ___| ___ _ __ _ __ //
// | | | | | || | / __|| '_ \ | '_ \ //
// | |___ | |_| || |___ _| (__ | |_) || |_) | //
// \____||____/ \____|(_)\___|| .__/ | .__/ //
// |_| |_| //
// //
//////////////////////////////////////////////////////////////////////////////
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
// Updated for the XMegaForArduino project by Bob Frazier, S.F.T. Inc.
/////////////////////////////////////////////////////////////////////////////////
// XMEGA NOTES:
//
// a) major re-factoring, including API functions
// b) K&R style is hard to read. I won't use it. Hard tabs are evil. Same.
//
/////////////////////////////////////////////////////////////////////////////////
#include "Platform.h"
#include "USBAPI.h"
#include <avr/wdt.h>
#if defined(USBCON)
#ifdef CDC_ENABLED
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#define PROGMEM_ORIG PROGMEM
#else // PROGMEM workaround
// to avoid the bogus "initialized variables" warning
#ifdef PROGMEM
#undef PROGMEM
#endif // PROGMEM re-define
#define PROGMEM __attribute__((section(".progmem.cdc")))
#define PROGMEM_ORIG __attribute__((__progmem__))
#endif // check for GNUC >= or < 4.6
typedef struct
{
u32 dwDTERate; // little-endian line rate
u8 bCharFormat; // stop bits = one, one-and-a-half, two (0, 1, 2 respectively)
u8 bParityType; // none, odd, even, mark, space (0 through 4)
u8 bDataBits; // char bits 5, 6, 7, 8
} __attribute__((aligned(1))) LineInfo;
static volatile LineInfo _usbLineInfo; // for initialization, see CDC_Reset
static u8 _cdcLineState;
static u16 _cdcSerialState;
static uint16_t wInterval;
#define WEAK __attribute__ ((weak))
extern const DeviceDescriptor _cdcDeviceDescriptor PROGMEM;
extern const IADDescriptor _cdcIADDesc PROGMEM;
extern const CDCDescriptor _cdcInterface PROGMEM;
// CDC DEVICE DESCRIPTOR (for CDC device) - sent by CDC_SendDeviceDescriptor()
const DeviceDescriptor _cdcDeviceDescriptor PROGMEM =
D_DEVICE(USB_DEVICE_CLASS_COMMUNICATIONS, // device class (COMM)
CDC_COMMUNICATION_INTERFACE_CLASS, // device sub-class (CDC COMM)
CDC_ABSTRACT_CONTROL_MODEL, // device protocol (ACM)
64, // packet size (64)
USB_VID, // vendor ID for the USB device
USB_PID, // product ID for the USB device
0x100, // device release version as BCD (1.00)
USB_STRING_INDEX_MANUFACTURER, // string index for mfg
USB_STRING_INDEX_PRODUCT, // string index for product name
USB_STRING_INDEX_SERIAL, // string index for serial number (0 for 'none')
1); // number of configurations (1)
// IAD descriptor - REQUIRED for composite interfaces, sent via CDC_SendIAD()
const IADDescriptor _cdcIADDesc = D_IAD(0, // first interface
2, // count (interfaces, not endpoints)
CDC_COMMUNICATION_INTERFACE_CLASS, // interface class
CDC_ABSTRACT_CONTROL_MODEL, // interface sub-class
1); // protocol
// CDC interface descriptor - sent by CDC_SendInterfaceData()
const CDCDescriptor _cdcInterface = // needs to be no more than 55 bytes in length
{
// FIRST INTERFACE
// CDC communication interface (endpoint 0)
D_INTERFACE(CDC_ACM_INTERFACE, // 'n'
1, // number of endpoints
CDC_COMMUNICATION_INTERFACE_CLASS, // interface class
CDC_ABSTRACT_CONTROL_MODEL, // interface sub-class
0), // protocol
// these headers describe the supported interfaces
D_CDCCS(CDC_HEADER,0x10,0x01), // CDCCS InterfaceDescriptor Header (1.10 bcd) - version 1.10?
// D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (seems to be optional)
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 (?)
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM), // IN endpoint for CDC_ENDPOINT_ACM
USB_ENDPOINT_TYPE_INTERRUPT, // INTERRUPT type
0x10, // max packet size 16
0x40), // interval 64 frames i.e. 64 msec (see USB spec table 9-13)
// SECOND INTERFACE
// CDC data interface (endpoints 1, 2)
D_INTERFACE(CDC_DATA_INTERFACE, // 'n'
2, // number of endpoints
CDC_DATA_INTERFACE_CLASS, // interface class
0, // interface sub-class
0), // protocol
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), // OUT endpoint, index 'CDC_ENDPOINT_OUT'
USB_ENDPOINT_TYPE_BULK, // BULK data transfers
0x40, // max packet size 64
1), // interval 1 (was 0)
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN), // IN endpoint, index 'CDC_ENDPOINT_IN'
USB_ENDPOINT_TYPE_BULK, // BULK data transfers
0x40, // max packet size 64
0) // interval 0 (apparently not needed)
};
void WEAK CDC_Reset(void)
{
_usbLineInfo.dwDTERate = 115200;
_usbLineInfo.bCharFormat
= _usbLineInfo.bParityType
= _usbLineInfo.bDataBits
= 0; // says I'm not initialized, basically
_cdcLineState = 0;
_cdcSerialState = 0;
wInterval = 0;
}
bool WEAK CDC_SendIAD(void)
{
return USB_SendControl(TRANSFER_PGM, &_cdcIADDesc, sizeof(_cdcIADDesc))
!= 0;
}
int WEAK CDC_GetNumInterfaces(void)
{
return 2; // always 2
}
int WEAK CDC_GetInterfaceDataLength(void)
{
return sizeof(_cdcInterface);
}
int WEAK CDC_SendInterfaceData(void)
{
return USB_SendControl(TRANSFER_PGM, &_cdcInterface, sizeof(_cdcInterface));
}
bool WEAK CDC_SendDeviceDescriptor(void)
{
return 0 != USB_SendControl(TRANSFER_PGM, &_cdcDeviceDescriptor, sizeof(_cdcDeviceDescriptor));
}
bool WEAK CDC_Setup(Setup& setup)
{
u8 r = setup.bRequest;
u8 requestType = setup.bmRequestType;
if(REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
{
if (CDC_GET_LINE_CODING == r)
{
error_printP(F("Get Line Coding"));
#if 1
USB_SendControl(0,(void*)&_usbLineInfo, sizeof(_usbLineInfo)/*7*/);
#endif // 0
return true;
}
}
else if(REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
{
if(CDC_SET_LINE_CODING == r)
{
error_printP_(F("CDC_SET_LINE_CODING"));
// setup packet is followed by data?
memcpy((void *)&_usbLineInfo, (char *)&(setup) + sizeof(Setup), sizeof(_usbLineInfo));
error_printP_(F(" rate:"));
error_printL_(_usbLineInfo.dwDTERate);
error_printP_(F(" fmt:"));
error_printL_(_usbLineInfo.bCharFormat);
error_printP_(F(" par:"));
error_printL_(_usbLineInfo.bParityType);
error_printP_(F(" bit:"));
error_printL(_usbLineInfo.bDataBits);
USB_SendControl(0, NULL, 0); // send a ZLP
_cdcLineState = CONTROL_LINE_STATE_DTR; // for now... assume "this"
// now set up the ACM interrupt info in '_cdcSerialState' and send it back
_cdcSerialState = SERIAL_STATE_TX_CARRIER_DSR; // to tell host "I have data" (always)
return true;
}
else if(CDC_SET_CONTROL_LINE_STATE == r)
{
error_printP_(F("Set Control Line State: "));
error_printL(setup.wValueL);
_cdcLineState = setup.wValueL;
// NOTE: this next part is for the 'caterina' CDC bootloader, arduino/bootloaders/caterina/Caterina.c
// it has some "special" code in it, like using 0x0800 in RAM as an address for a 'key' (7777H)
// to indicate it was soft-booted. XMEGA has better ways of handling this, like a CPU flag that
// indicates "I was soft-booted" as one example, and a 'WDT' timeout flag on top of that.
// auto-reset into the bootloader is triggered when the port, already
// open at 1200 bps, is closed. this is the signal to start the watchdog
// with a relatively long period so it can finish housekeeping tasks
// like servicing endpoints before the sketch ends
if (1200 == _usbLineInfo.dwDTERate)
{
// We check DTR state to determine if host port is open (bit 0 of _cdcLineState).
if ((_cdcLineState & 0x01) == 0)
{
// This section of code is support for the 'caterina' bootloader, which allows USB flashing (apparently)
//
// *(uint16_t *)0x0800 = 0x7777; note that on XMEGA this is a VERY bad thing
// wdt_enable(WDTO_120MS);
//
// on the atmega, address 800H is the start of the final 256-byte page in RAM space for 2k RAM
//
// atmega328(p) RAM goes from 0x100 through 0x8ff - see datasheet for atmega 328 [etc.] section 8.3
// 32U4 RAM goes through 0xaff - see datasheet for U4 processors, section 5.2
// 8/16/32U2 RAM goes through 4FFH so this won't even work - see datasheet for U2 processors, section 7.2
// basically it's a 'hack' and needs to be re-evaluated
// TODO: would it be safe to enable interrupts, NOT return from this function,
// and simply wait until the appropriate time has elapsed? Or, as is
// handled in the section below, this 'wait period' is canceled
// TODO: if I use a function that's part of the USB driver to trigger a soft boot, I can detect
// that a soft boot has taken place using the bits in the 'RESET' status register. If all
// I have to do is detect this, it's not a problem, and I won't need "magic memory locations"
// TODO: timeout-based reboot
}
else
{
// Most OSs do some intermediate steps when configuring ports and DTR can
// twiggle more than once before stabilizing.
// To avoid spurious resets we set the watchdog to 250ms and eventually
// cancel if DTR goes back high.
// This section of code is support for the 'caterina' bootloader, which allows USB flashing (apparently)
//
// TODO: reset whatever boot timeout I did
// wdt_disable();
// wdt_reset();
// *(uint16_t *)0x0800 = 0x0; note that on XMEGA this is a VERY bad thing
}
}
USB_SendControl(0, NULL, 0); // send a ZLP
return true;
}
}
// unrecognized request - report it
error_printP_(F("CDC request: type="));
error_printL_(requestType);
error_printP_(F(" request="));
error_printL(r);
return false;
}
// 'frame received' callback - notification that a 'Start Of Frame' took place
void CDC_FrameReceived(void)
{
bool bSend = false;
// NOTE: if I haven't configured the baud/bits yet, or the DTR bit is cleared,
// do NOT send anything nor muck with the flags. Wait until the device
// is actually RUNNING, first.
if(!_usbLineInfo.bDataBits || !(_cdcLineState & CONTROL_LINE_STATE_DTR))
{
return; // don't do anything if I haven't properly set up the data bits yet
}
if(USB_Available(CDC_RX) >= 64) // allow ~64 buffered bytes
{
if(_cdcSerialState & SERIAL_STATE_RX_CARRIER_DCD) // was on?
{
_cdcSerialState &= ~SERIAL_STATE_RX_CARRIER_DCD;
bSend = true;
}
}
else
{
if(!(_cdcSerialState & SERIAL_STATE_RX_CARRIER_DCD)) // was off?
{
_cdcSerialState |= SERIAL_STATE_RX_CARRIER_DCD;
bSend = true;
}
}
// if(USB_SendQLength(CDC_TX) > 0) // anything to send??
// {
// if(!(_cdcSerialState & SERIAL_STATE_TX_CARRIER_DSR))
// {
// _cdcSerialState |= SERIAL_STATE_TX_CARRIER_DSR; // to tell host "I have data"
//
// bSend = true;
// }
// }
// else
// {
// if(_cdcSerialState & SERIAL_STATE_TX_CARRIER_DSR)
// {
// _cdcSerialState &= ~SERIAL_STATE_TX_CARRIER_DSR; // to tell host "I have data"
//
// bSend = true;
// }
// }
if((bSend || wInterval >= 64) // will send every 64 'bus cycles' or when there's a change
&& !USB_SendQLength(CDC_ACM))
{
CDC_SendACM();
wInterval = 0;
}
else if(wInterval < 64)
{
wInterval++;
}
}
void CDC_SendACM(void)
{
USB_Send(CDC_ACM, &_cdcSerialState, sizeof(_cdcSerialState), 1);
}
void Serial_::begin(unsigned long baud_count)
{
peek_buffer = -1;
}
void Serial_::begin(unsigned long baud_count, byte config)
{
peek_buffer = -1;
}
void Serial_::end(void)
{
}
int Serial_::available(void)
{
if (peek_buffer >= 0)
{
return 1 + USB_Available(CDC_RX);
}
return USB_Available(CDC_RX);
}
int Serial_::peek(void)
{
if (peek_buffer < 0)
{
if(USBDevice.configured())
{
peek_buffer = USB_Recv(CDC_RX);
}
}
return peek_buffer;
}
int Serial_::read(void)
{
if (peek_buffer >= 0)
{
int c = peek_buffer;
peek_buffer = -1;
return c;
}
if(USBDevice.configured())
{
return USB_Recv(CDC_RX);
}
return -1;
}
void Serial_::flush(void)
{
if(USBDevice.configured())
{
USB_Flush(CDC_TX);
}
}
size_t Serial_::write(uint8_t c)
{
return write(&c, 1);
}
size_t Serial_::write(const uint8_t *buffer, size_t size)
{
/* only try to send bytes if the high-level CDC connection itself
is open (not just the pipe) - the OS should set _cdcLineState when the port
is opened and clear _cdcLineState when the port is closed.
bytes sent before the user opens the connection or after
the connection is closed are lost - just like with a UART. */
// NOTE: if my outgoing buffer is too full, stop sending
// TODO - ZE - check behavior on different OSes and test what happens if an
// open connection isn't broken cleanly (cable is yanked out, host dies
// or locks up, or host virtual serial port hangs)
if(USBDevice.configured() && // make sure I'm running
// !USB_IsStalled(CDC_TX) && // make sure I'm not stalled
!USB_IsSendQFull(CDC_TX)) // make sure I'm not flooding the queue
{
if(_cdcLineState & CONTROL_LINE_STATE_DTR) // make sure DTR is set
{
if(size > 128)
{
size = 128; // adjust size DOWN to limit output buffer size
}
int r = USB_Send(CDC_TX, buffer, size, 1);
// TODO: check for partial sends and retry??
if(r > 0)
{
CDC_FrameReceived(); // inform the host of my data send/receive state
return r;
}
}
}
// TODO: block?
setWriteError();
return 0;
}
// This operator is a convenient way for a sketch to check whether the
// port has actually been configured and opened by the host (as opposed
// to just being connected to the host). It can be used, for example, in
// setup() before printing to ensure that an application on the host is
// actually ready to receive and display the data.
Serial_::operator bool()
{
bool result = false;
if(USBDevice.configured()
&& (_cdcLineState & CONTROL_LINE_STATE_DTR)
&& !USB_IsSendQFull(CDC_TX)
// && !USB_IsStalled(CDC_TX)
)
{
result = true;
}
// We add a short delay before returning to fix a bug observed by Federico
// where the port is configured (_cdcLineState != 0) but not quite opened.
// delay(10);
if(!result)
{
if(!USBDevice.configured())
{
error_printP(F("USB device not configured"));
}
else if(!(_cdcLineState & CONTROL_LINE_STATE_DTR))
{
error_printP(F("DTR is off"));
}
else if(USB_IsSendQFull(CDC_TX))
{
error_printP(F("Send Queue FULL"));
}
// else if(USB_IsStalled(CDC_TX))
// {
// error_printP(F("USB is stalled"));
// }
}
return result;
}
Serial_ Serial;
#endif
#endif /* if defined(USBCON) */

View File

@@ -0,0 +1,45 @@
/*
Client.h - Base class that provides Client
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef client_h
#define client_h
#include "Print.h"
#include "Stream.h"
#include "IPAddress.h"
class Client : public Stream {
public:
virtual int connect(IPAddress ip, uint16_t port) =0;
virtual int connect(const char *host, uint16_t port) =0;
virtual size_t write(uint8_t) =0;
virtual size_t write(const uint8_t *buf, size_t size) =0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
#endif

View File

@@ -0,0 +1,593 @@
//////////////////////////////////////////////////////////////////////////////
// //
// _ _ ___ ____ //
// | | | ||_ _|| _ \ ___ _ __ _ __ //
// | |_| | | | | | | | / __|| '_ \ | '_ \ //
// | _ | | | | |_| |_| (__ | |_) || |_) | //
// |_| |_||___||____/(_)\___|| .__/ | .__/ //
// |_| |_| //
// //
//////////////////////////////////////////////////////////////////////////////
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
/////////////////////////////////////////////////////////////////////////////////
// XMEGA NOTES:
//
// a) it appears that, at one time at least, this was intended to be overridden
// by user code, hence the use of 'WEAK' all over the place;
// b) This API is *VERY* 'tricky' in that it's tied in heavily with the atmega
// USB implementation and (in some cases) does 'magic things' that are not
// apparently obvious to someone trying to port it to another processor
// (for an example see original use of CDC_GetInterface - lame!)
// c) Given the fact that it's (in my view) POORLY WRITTEN, it deserves a makeover.
// d) K&R style is hard to read. I won't use it. Hard tabs are evil. Same.
//
/////////////////////////////////////////////////////////////////////////////////
#include "Platform.h"
#include "USBAPI.h"
#include "USBDesc.h"
#if defined(USBCON)
#ifdef HID_ENABLED
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#define PROGMEM_ORIG PROGMEM
#else // PROGMEM workaround
// to avoid the bogus "initialized variables" warning
#ifdef PROGMEM
#undef PROGMEM
#endif // PROGMEM re-define
#define PROGMEM __attribute__((section(".progmem.hid")))
#define PROGMEM_ORIG __attribute__((__progmem__))
#endif // check for GNUC >= or < 4.6
//#define RAWHID_ENABLED
// Singletons for mouse and keyboard
Mouse_ Mouse;
Keyboard_ Keyboard;
//================================================================================
//================================================================================
// HID report descriptor
#define LSB(_x) ((_x) & 0xFF)
#define MSB(_x) ((_x) >> 8)
#define RAWHID_USAGE_PAGE 0xFFC0
#define RAWHID_USAGE 0x0C00
#define RAWHID_TX_SIZE 64
#define RAWHID_RX_SIZE 64
const u8 _hidReportDescriptor[] PROGMEM =
{
// Mouse
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
// Keyboard
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x02, // REPORT_ID (2)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0, // END_COLLECTION
#ifdef RAWHID_ENABLED
// RAW HID
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
0xA1, 0x01, // Collection 0x01
0x85, 0x03, // REPORT_ID (3)
0x75, 0x08, // report size = 8 bits
0x15, 0x00, // logical minimum = 0
0x26, 0xFF, 0x00, // logical maximum = 255
0x95, 64, // report count TX
0x09, 0x01, // usage
0x81, 0x02, // Input (array)
0x95, 64, // report count RX
0x09, 0x02, // usage
0x91, 0x02, // Output (array)
0xC0 // end collection
#endif
};
const HIDDescriptor _hidInterface PROGMEM =
{
D_INTERFACE(HID_INTERFACE,1,3,0,0),
D_HIDREPORT(sizeof(_hidReportDescriptor)),
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
};
//================================================================================
//================================================================================
// Driver
u8 _hid_protocol = 1;
u8 _hid_idle = 1;
#define WEAK __attribute__ ((weak))
int WEAK HID_GetNumInterfaces(void)
{
return 1; // always 1
}
int WEAK HID_GetInterfaceDataLength(void)
{
return sizeof(_hidInterface);
}
int WEAK HID_SendInterfaceData(void)
{
return USB_SendControl(TRANSFER_PGM, &_hidInterface, sizeof(_hidInterface));
}
int WEAK HID_GetDescriptor(int i)
{
// NOTE: 'i' is the max size for the request. Should I pay attention to it?
return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));
}
void WEAK HID_SendReport(u8 id, const void* data, int len)
{
USB_Send(HID_TX, &id, 1, 0);
USB_Send(HID_TX,data,len, 1);
}
bool WEAK HID_Setup(Setup& setup)
{
u8 r = setup.bRequest;
u8 requestType = setup.bmRequestType;
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
{
if (HID_GET_REPORT == r)
{
//HID_GetReport();
return true;
}
if (HID_GET_PROTOCOL == r)
{
//Send8(_hid_protocol); // TODO
return true;
}
}
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
{
if (HID_SET_PROTOCOL == r)
{
_hid_protocol = setup.wValueL;
return true;
}
if (HID_SET_IDLE == r)
{
_hid_idle = setup.wValueL;
return true;
}
}
return false;
}
//================================================================================
//================================================================================
// Mouse
Mouse_::Mouse_(void) : _buttons(0)
{
}
void Mouse_::begin(void)
{
}
void Mouse_::end(void)
{
}
void Mouse_::click(uint8_t b)
{
_buttons = b;
move(0,0,0);
_buttons = 0;
move(0,0,0);
}
void Mouse_::move(signed char x, signed char y, signed char wheel)
{
u8 m[4];
m[0] = _buttons;
m[1] = x;
m[2] = y;
m[3] = wheel;
HID_SendReport(1,m,4);
}
void Mouse_::buttons(uint8_t b)
{
if (b != _buttons)
{
_buttons = b;
move(0,0,0);
}
}
void Mouse_::press(uint8_t b)
{
buttons(_buttons | b);
}
void Mouse_::release(uint8_t b)
{
buttons(_buttons & ~b);
}
bool Mouse_::isPressed(uint8_t b)
{
if ((b & _buttons) > 0)
{
return true;
}
return false;
}
//================================================================================
//================================================================================
// Keyboard
Keyboard_::Keyboard_(void)
{
}
void Keyboard_::begin(void)
{
}
void Keyboard_::end(void)
{
}
void Keyboard_::sendReport(KeyReport* keys)
{
HID_SendReport(2,keys,sizeof(KeyReport));
}
extern
const uint8_t _asciimap[128] PROGMEM;
#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x34|SHIFT, // "
0x20|SHIFT, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x24|SHIFT, // &
0x34, // '
0x26|SHIFT, // (
0x27|SHIFT, // )
0x25|SHIFT, // *
0x2e|SHIFT, // +
0x36, // ,
0x2d, // -
0x37, // .
0x38, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x33|SHIFT, // :
0x33, // ;
0x36|SHIFT, // <
0x2e, // =
0x37|SHIFT, // >
0x38|SHIFT, // ?
0x1f|SHIFT, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x2f, // [
0x31, // bslash
0x30, // ]
0x23|SHIFT, // ^
0x2d|SHIFT, // _
0x35, // `
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x2f|SHIFT, //
0x31|SHIFT, // |
0x30|SHIFT, // }
0x35|SHIFT, // ~
0 // DEL
};
uint8_t USBPutChar(uint8_t c);
// press() adds the specified key (printing, non-printing, or modifier)
// to the persistent key report and sends the report. Because of the way
// USB HID works, the host acts like the key remains pressed until we
// call release(), releaseAll(), or otherwise clear the report and resend.
size_t Keyboard_::press(uint8_t k)
{
uint8_t i;
if (k >= 136) // it's a non-printing key (not a modifier)
{
k = k - 136;
}
else if (k >= 128)
{ // it's a modifier key
_keyReport.modifiers |= (1<<(k-128));
k = 0;
}
else // it's a printing key
{
k = pgm_read_byte(_asciimap + k);
if (!k)
{
setWriteError();
return 0;
}
if (k & 0x80) // it's a capital letter or other character reached with shift
{
_keyReport.modifiers |= 0x02; // the left shift modifier
k &= 0x7F;
}
}
// Add k to the key report only if it's not already present
// and if there is an empty slot.
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
_keyReport.keys[4] != k && _keyReport.keys[5] != k)
{
for (i=0; i<6; i++)
{
if (_keyReport.keys[i] == 0x00)
{
_keyReport.keys[i] = k;
break;
}
}
if (i == 6)
{
setWriteError();
return 0;
}
}
sendReport(&_keyReport);
return 1;
}
// release() takes the specified key out of the persistent key report and
// sends the report. This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::release(uint8_t k)
{
uint8_t i;
if (k >= 136)
{ // it's a non-printing key (not a modifier)
k = k - 136;
}
else if (k >= 128)
{ // it's a modifier key
_keyReport.modifiers &= ~(1<<(k-128));
k = 0;
}
else
{ // it's a printing key
k = pgm_read_byte(_asciimap + k);
if (!k)
{
return 0;
}
if (k & 0x80)
{ // it's a capital letter or other character reached with shift
_keyReport.modifiers &= ~(0x02); // the left shift modifier
k &= 0x7F;
}
}
// Test the key report to see if k is present. Clear it if it exists.
// Check all positions in case the key is present more than once (which it shouldn't be)
for (i=0; i<6; i++)
{
if (0 != k && _keyReport.keys[i] == k)
{
_keyReport.keys[i] = 0x00;
}
}
sendReport(&_keyReport);
return 1;
}
void Keyboard_::releaseAll(void)
{
_keyReport.keys[0] = 0;
_keyReport.keys[1] = 0;
_keyReport.keys[2] = 0;
_keyReport.keys[3] = 0;
_keyReport.keys[4] = 0;
_keyReport.keys[5] = 0;
_keyReport.modifiers = 0;
sendReport(&_keyReport);
}
size_t Keyboard_::write(uint8_t c)
{
uint8_t p = press(c); // Keydown
/*uint8_t r =*/ release(c); // Keyup
return (p); // just return the result of press() since release() almost always returns 1
}
#endif
#endif /* if defined(USBCON) */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
/*
HardwareSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
In some cases, the xmega updates make assumptions about the pin assignments.
See 'pins_arduino.h' for more detail.
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "Stream.h"
struct ring_buffer;
class HardwareSerial : public Stream
{
protected: // NEVER 'private'
// NOTE: xmega uses a structure pointer rather than individual pointers
// and the bit flags are consistent for all USART devices
ring_buffer *_rx_buffer;
ring_buffer *_tx_buffer;
volatile USART_t *_usart;
bool transmitting;
public:
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, uint16_t usart) __attribute__ ((noinline));
void init(ring_buffer *rx_buffer, ring_buffer *tx_buffer, uint16_t usart) __attribute__ ((noinline));
void begin(unsigned long);
void begin(unsigned long, uint8_t);
void end();
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool();
};
// Define config for Serial.begin(baud, config);
// PMODE 5:4 00=none 10=even 11=odd
// SBMODE 3 0=1 stop 1=2 stop
// CHSIZE 2:0 000=5 bit 001=6 bit 010=7 bit 011=8 bit 111=9 bit
#define SERIAL_TWO_STOP _BV(USART_SBMODE_bp)
#define SERIAL_EVEN_PARITY _BV(USART_PMODE1_bp)
#define SERIAL_ODD_PARITY (_BV(USART_PMODE1_bp) | _BV(USART_PMODE0_bp))
#define SERIAL_5N1 0x00
#define SERIAL_6N1 0x01
#define SERIAL_7N1 0x02
#define SERIAL_8N1 0x03
#define SERIAL_5N2 (SERIAL_5N1 | SERIAL_TWO_STOP)
#define SERIAL_6N2 (SERIAL_6N1 | SERIAL_TWO_STOP)
#define SERIAL_7N2 (SERIAL_7N1 | SERIAL_TWO_STOP)
#define SERIAL_8N2 (SERIAL_8N1 | SERIAL_TWO_STOP)
#define SERIAL_5E1 (SERIAL_5N1 | SERIAL_EVEN_PARITY)
#define SERIAL_6E1 (SERIAL_6N1 | SERIAL_EVEN_PARITY)
#define SERIAL_7E1 (SERIAL_7N1 | SERIAL_EVEN_PARITY)
#define SERIAL_8E1 (SERIAL_8N1 | SERIAL_EVEN_PARITY)
#define SERIAL_5E2 (SERIAL_5N2 | SERIAL_EVEN_PARITY)
#define SERIAL_6E2 (SERIAL_6N2 | SERIAL_EVEN_PARITY)
#define SERIAL_7E2 (SERIAL_7N2 | SERIAL_EVEN_PARITY)
#define SERIAL_8E2 (SERIAL_8N2 | SERIAL_EVEN_PARITY)
#define SERIAL_5O1 (SERIAL_5N1 | SERIAL_ODD_PARITY)
#define SERIAL_6O1 (SERIAL_6N1 | SERIAL_ODD_PARITY)
#define SERIAL_7O1 (SERIAL_7N1 | SERIAL_ODD_PARITY)
#define SERIAL_8O1 (SERIAL_8N1 | SERIAL_ODD_PARITY)
#define SERIAL_5O2 (SERIAL_5N2 | SERIAL_ODD_PARITY)
#define SERIAL_6O2 (SERIAL_6N2 | SERIAL_ODD_PARITY)
#define SERIAL_7O2 (SERIAL_7N2 | SERIAL_ODD_PARITY)
#define SERIAL_8O2 (SERIAL_8N2 | SERIAL_ODD_PARITY)
// this is where I must include 'pins_arduino.h' to get the 'USBCON' definition
#include "pins_arduino.h"
// DEFAULT SERIAL or 'SERIAL 1'
#if defined(USBCON)
// NOTE: 'Serial1' will be the hardware serial and 'Serial' the USB serial
// whenever 'USBCON' is defined in pins_arduino.h
#include <USBAPI.h>
extern HardwareSerial Serial1;
#else // normal hardware serial
extern HardwareSerial Serial;
#define Serial1 Serial /* define as 'Serial' so compatible code won't break */
#endif
extern HardwareSerial Serial2; // this is the same regardless of USBCON (there will always be at least 2)
#ifdef SERIAL_2_PORT_NAME /* note these names are off by 1 with the 'Serial_N_' definitions */
extern HardwareSerial Serial3;
#endif // SERIAL_2_PORT_NAME
#ifdef SERIAL_3_PORT_NAME
extern HardwareSerial Serial4;
#endif // SERIAL_3_PORT_NAME
#ifdef SERIAL_4_PORT_NAME
extern HardwareSerial Serial5;
#endif // SERIAL_4_PORT_NAME
#ifdef SERIAL_5_PORT_NAME
extern HardwareSerial Serial6;
#endif // SERIAL_5_PORT_NAME
#ifdef SERIAL_6_PORT_NAME
extern HardwareSerial Serial7;
#endif // SERIAL_6_PORT_NAME
#ifdef SERIAL_7_PORT_NAME
extern HardwareSerial Serial8;
#endif // SERIAL_7_PORT_NAME
// this function calls the serial event handlers. you can override them (hence 'weak')
// the default implementation checks for data available and executes the callback if so
extern void serialEventRun(void) __attribute__((weak));
#endif // HardwareSerial_h

View File

@@ -0,0 +1,74 @@
/*
IPAddress.cpp - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <IPAddress.h>
IPAddress::IPAddress()
{
memset(_address, 0, sizeof(_address));
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address[0] = first_octet;
_address[1] = second_octet;
_address[2] = third_octet;
_address[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address)
{
memcpy(_address, &address, sizeof(_address));
}
IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
}
IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
return *this;
}
IPAddress& IPAddress::operator=(uint32_t address)
{
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
return *this;
}
bool IPAddress::operator==(const uint8_t* addr)
{
return memcmp(addr, _address, sizeof(_address)) == 0;
}
size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address[i], DEC);
n += p.print('.');
}
n += p.print(_address[3], DEC);
return n;
}

View File

@@ -0,0 +1,82 @@
/*
IPAddress.h - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef IPAddress_h
#define IPAddress_h
#include <Printable.h>
// A class to make it easier to handle and pass around IP addresses
class IPAddress : public Printable
{
private:
uint8_t _address[4]; // IPv4 address
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address; };
public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t()
{
register const uint32_t *p1 = (const uint32_t *)(const void *)_address;
return *p1;
};
bool operator==(const IPAddress& addr)
{
register const uint32_t *p1 = (const uint32_t*)_address;
register const uint32_t *p2 = (const uint32_t*)(addr._address);
return *p1 == *p2;
};
bool operator==(const uint8_t* addr);
// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address[index]; };
uint8_t& operator[](int index) { return _address[index]; };
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
virtual size_t printTo(Print& p) const;
friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
};
const IPAddress INADDR_NONE(0,0,0,0);
#endif

View File

@@ -0,0 +1,27 @@
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#ifndef _PLATFORM_H_TYPES_DEFINED_
#define _PLATFORM_H_TYPES_DEFINED_
// this is a temporary fix for USCore.h data types and header file include order issues
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#endif // _PLATFORM_H_TYPES_DEFINED_
#include "Arduino.h"
#if defined(USBCON)
#include "USBDesc.h"
#include "USBCore.h"
#include "USBAPI.h"
#endif /* if defined(USBCON) */
#endif

View File

@@ -0,0 +1,381 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Arduino.h"
#include "Print.h"
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--)
{
register size_t cb = write(*buffer++);
if(!cb) // error return (prevents infinite loops)
{
break;
}
n += cb;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
char tbuf[32]; // will write 32 chars at a time (helps for USB)
register char *p1;
p1 = tbuf;
while (1)
{
unsigned char c = pgm_read_byte(p++);
if(c == 0)
{
if(p1 > &(tbuf[0]))
{
n += write(tbuf, p1 - &(tbuf[0])); // write whatever I've got
}
break;
}
if(p1 >= &(tbuf[sizeof(tbuf)]))
{
register size_t cb = write(tbuf, p1 - &(tbuf[0]));
if(!cb) // error (prevents infinite loops)
{
break;
}
n += cb;
p1 = tbuf;
}
*(p1++) = c;
}
return n;
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0)
{
return write(n);
}
else if (base == 10)
{
if (n < 0)
{
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0)
return write(n);
else
return printNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
char tbuf[2];
tbuf[0] = '\r'; // this should be more efficient, and smaller
tbuf[1] = '\n';
return write(tbuf, 2);
// size_t n = print('\r');
// n += print('\n');
// return n;
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
// Private Methods /////////////////////////////////////////////////////////////
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2)
base = 10;
do
{
unsigned long m = n;
n /= base;
char c = m - base * n;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
return write(str);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number))
return print("nan");
if (isinf(number))
return print("inf");
if (number > 4294967040.0)
return print ("ovf"); // constant determined empirically
if (number <-4294967040.0)
return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
{
rounding /= 10.0;
}
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
// things that I added
int Print::printf(const char *pszFormat, ...) /*__attribute__ ((format(printf, 2, 3)))*/ // added API for 'printf' since it has been suggested...
{
va_list va;
int cbOut;
va_start(va, pszFormat);
cbOut = vsnprintf(NULL, 0, pszFormat, va);
if(cbOut > 0)
{
char *p1 = (char *)malloc(cbOut + 2);
if(p1)
{
cbOut = vsnprintf(p1, cbOut + 1, pszFormat, va);
print(p1);
free(p1);
}
}
va_end(va);
return cbOut;
}
int Print::printf_P(const char *pszFormat, ...) /*__attribute__ ((format(printf_P, 2, 3)))*/ // added API for 'printf' since it has been suggested...
{
va_list va;
int cbOut;
va_start(va, pszFormat);
cbOut = vsnprintf_P(NULL, 0, (const char *)pszFormat, va);
if(cbOut > 0)
{
char *p1 = (char *)malloc(cbOut + 2);
if(p1)
{
cbOut = vsnprintf_P(p1, cbOut + 1, (const char *)pszFormat, va);
print(p1);
free(p1);
}
}
va_end(va);
return cbOut;
}

View File

@@ -0,0 +1,97 @@
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#include "WString.h"
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Print() : write_error(0) {} // default constructor only assigns 0 to 'write_error'
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0; // derived class must implement
size_t write(const char *str)
{
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
// write multiple characters from a buffer - default calls 'write(uint8_t)' on each byte
// NOTE: for better efficiency, a derived class SHOULD implement its own 'write' for a buffer
virtual size_t write(const uint8_t *buffer, size_t size); // overridable
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
// custom mod - implement 'printf' member function
int printf(const char *pszFormat, ...) __attribute__ ((format(printf, 2, 3))); // added API for 'printf' since it has been suggested...
int printf_P(const char *pszFormat, ...) __attribute__ ((format(printf, 2, 3))); // added API for 'printf_P' since it has been suggested...
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
};
#endif

View File

@@ -0,0 +1,40 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include <new.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif

View File

@@ -0,0 +1,28 @@
/*
Server.h - Base class that provides Server
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef server_h
#define server_h
class Server : public Print {
public:
virtual void begin() =0;
};
#endif

View File

@@ -0,0 +1,362 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
*/
#include "Arduino.h"
#include "Stream.h"
// if/branch optimization
#define UNLIKELY(x) (__builtin_expect (!!(x), 0))
#define LIKELY(x) (__builtin_expect (!!(x), 1))
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
// private method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
do
{
c = read();
if (c >= 0)
return c;
wait_for_interrupt(); // XMega enhancement
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// private method to peek stream with timeout
int Stream::timedPeek()
{
int c;
_startMillis = millis();
do
{
c = peek();
if (c >= 0)
return c;
wait_for_interrupt(); // XMega enhancement
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
int c;
while (1)
{
c = timedPeek();
// refactored this for (possibly) better efficiency AND readability - seems to be the same size/footprint
// if (c < 0)
// return c; // timeout
//
// if (c == '-')
// return c;
//
// if (c >= '0' && c <= '9')
// return c;
if(UNLIKELY(c < 0) || // refactored. < 0 is a timeout
UNLIKELY(c == '-') || // negative (TODO: test for leading char only, or lead on exponent)
LIKELY(c >= '0' && c <= '9')) // numeric digit; TODO test for exponent on float?
{
return c;
}
read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, NULL/*""*/);
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;
if(!target || *target == 0) // update, allow NULL pointer
{
return true; // return true if target is a null string
}
while( (c = timedRead()) > 0)
{
if(c != target[index])
{
index = 0; // reset index if any char does not match
}
if( c == target[index])
{
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen) // return true if all chars in the target match
{
return true;
}
}
// allow for NULL 'terminator'
if(terminator && termLen > 0 &&
UNLIKELY(c == terminator[termIndex]))
{
if(++termIndex >= termLen)
{
return false; // return false if terminate string found before target string
}
}
else
{
termIndex = 0;
}
}
return false;
}
// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}
// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;
c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do
{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == skipChar )
;
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat()
{
return parseFloat(NO_SKIP_CHAR);
}
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar)
{
boolean isNegative = false;
boolean isFraction = false;
long value = 0;
char c;
float fraction = 1.0;
c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
{
return 0; // zero returned if timeout
}
do
{
if(c == skipChar)
{
// ignore
}
else if(c == '-')
{
isNegative = true;
}
else if (c == '.')
{
isFraction = true;
}
else if(c >= '0' && c <= '9') // is c a digit?
{
value = value * 10 + c - '0';
if(isFraction)
{
fraction *= 0.1;
}
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar )
;
if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length)
{
int c = timedRead();
if (c < 0)
break;
*buffer++ = (char)c;
count++;
}
return count;
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
if (length < 1)
return 0;
size_t index = 0;
while (index < length)
{
int c = timedRead();
if (c < 0 || c == terminator) break;
*buffer++ = (char)c;
index++;
}
return index; // return number of characters, not including null terminator
}
String Stream::readString()
{
String ret;
int c = timedRead();
while (c >= 0)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
String Stream::readStringUntil(char terminator)
{
String ret;
int c = timedRead();
while (c >= 0 && c != terminator)
{
ret += (char)c;
c = timedRead();
}
return ret;
}

View File

@@ -0,0 +1,96 @@
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/
#ifndef Stream_h
#define Stream_h
#include <inttypes.h>
#include "Print.h"
// compatability macros for testing
/*
#define getInt() parseInt()
#define getInt(skipChar) parseInt(skipchar)
#define getFloat() parseFloat()
#define getFloat(skipChar) parseFloat(skipChar)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
class Stream : public Print
{
protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout
int timedPeek(); // private method to peek stream with timeout
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;
Stream() {_timeout=1000;}
// parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
bool find(char *target); // reads data from the stream until the target string is found
// returns true if target string is found, false if timed out (see setTimeout)
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
long parseInt(); // returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// integer is terminated by the first character that is not a digit.
float parseFloat(); // float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
String readStringUntil(char terminator);
protected:
long parseInt(char skipChar); // as above but the given skipChar is ignored
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float parseFloat(char skipChar); // as above but the given skipChar is ignored
};
#endif

View File

@@ -0,0 +1,960 @@
/* Tone.cpp
A Tone Generator Library
Written by Brett Hagman
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Version Modified By Date Comments
------- ----------- -------- --------
0001 B Hagman 09/08/02 Initial coding
0002 B Hagman 09/08/18 Multiple pins
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
0004 B Hagman 09/09/26 Fixed problems with ATmega8
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
09/11/25 Changed pin toggle method to XOR
09/11/25 Fixed timer0 from being excluded
0006 D Mellis 09/12/29 Replaced objects with functions
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
*************************************************/
// COMPLETE re-write for ATXMega by Bob Frazier, S.F.T. Inc. - http://mrp3.com/
// NOTE: this still only supports one tone output. However, xmega can do more than one
// due to the way the timers are. In fact, 'E' series can probably do a LOT more
// than one. If you want to implement that, it's a public project, so get it working
// reliably and submit the changes, thanks.
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "Arduino.h"
#include "pins_arduino.h"
#if defined(TCC4) || !defined(TCC2)
// in these cases this file isn't ready for prime time, so disable it for now
#ifdef TONE_SUPPORTED
#undef TONE_SUPPORTED
#endif // TONE_SUPPORTED
#else // !TCC4 && TCC2
#ifndef TONE_SUPPORTED
#define TONE_SUPPORTED // for now turn it off for 'E"
#endif // TONE_SUPPORTED
#endif // TCC4 || !TCC2
#ifdef TONE_SUPPORTED
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#define PROGMEM_ORIG PROGMEM
#else // PROGMEM workaround
// to avoid the bogus "initialized variables" warning
#ifdef PROGMEM
#undef PROGMEM
#endif // PROGMEM re-define
#define PROGMEM __attribute__((section(".progmem.tone")))
#define PROGMEM_ORIG __attribute__((__progmem__))
#endif // check for GNUC >= or < 4.6
static PORT_t *pTonePort = NULL; // must assign at startup due to ISR
static uint8_t bToneMask = 0; // bitmask for tone pin
static unsigned long toggle_count = 0; // number of cycles to output
static void toneBegin(uint8_t _pin, uint8_t _div, uint16_t _per)
{
pTonePort = (PORT_t *)portModeRegister(digitalPinToPort(_pin));
bToneMask = digitalPinToBitMask(_pin);
// Set the pinMode as OUTPUT
pinMode(_pin, OUTPUT);
#if NUM_DIGITAL_PINS > 18 /* meaning there is a PORT E available */
TCE0_INTCTRLA = 0; // temporarily disable overflow interrupt
TCE0_INTCTRLB = 0; // disable other interrupts
TCE0_CTRLA = _div; // divisor for pre-scaler
TCE0_CTRLB = TC_WGMODE_NORMAL_gc; // 'normal' mode (interrupt on 'overflow')
TCE0_CTRLD = 0; // not an event timer, 16-bit mode (12.11.4)
TCE0_CTRLE = 0; // 16-bit mode
TCE0_PER = _per; // period (16-bit value)
TCE0_INTCTRLA = 3; // overflow int level 3 (enables interrupt)
#elif defined(TCC4) // E series and anything else with 'TCC4'
TCC4_INTCTRLA = 0; // temporarily disable overflow interrupt
TCC4_INTCTRLB = 0; // disable other interrupts
TCC4_CTRLA = _div; // divisor for pre-scaler
TCC4_CTRLB = TC45_WGMODE_NORMAL_gc; // 'normal' mode (interrupt on 'overflow')
TCC4_CTRLD = 0; // not an event timer, 16-bit mode (12.11.4)
TCC4_CTRLE = 0; // 16-bit mode
TCC4_PER = _per; // period (16-bit value)
TCC4_INTCTRLA = 3; // overflow int level 3 (enables interrupt)
#else // other stuff not yet explored by me
TCC0_INTCTRLA = 0; // temporarily disable overflow interrupt
TCC0_INTCTRLB = 0; // disable other interrupts
TCC0_CTRLA = _div; // divisor for pre-scaler
TCC0_CTRLB = TC_WGMODE_NORMAL_gc; // 'normal' mode (interrupt on 'overflow')
TCC0_CTRLD = 0; // not an event timer, 16-bit mode (12.11.4)
TCC0_CTRLE = 0; // 16-bit mode
TCC0_PER = _per; // period (16-bit value)
TCC0_INTCTRLA = 3; // overflow int level 3 (enables interrupt)
#endif // NUM_DIGITAL_PINS > 18
// tone starts now, shuts off when the 'toggle_count' hits zero
}
// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
{
register int8_t b1;
unsigned short per, w2;
unsigned long ulTemp;
static const uint16_t aPreScaler[] PROGMEM = {1,2,4,8,64,256,1024}; // pre-scaler
// frequency
// based on the frequency, set up the divider and period
// period is 16-bits
// NOTE: use the smallest possible divisor
if(!frequency)
{
return;
}
ulTemp = frequency * 16384L; // ideal counter 16384
for(b1=sizeof(aPreScaler)/sizeof(aPreScaler[0]) - 1; b1 > 0; b1--)
{
w2 = pgm_read_word(&(aPreScaler[0]) + b1);
if(((unsigned long)F_CPU / 2 / w2) >= ulTemp) // note that I flip the bit every OTHER cycle
{
break;
}
}
if(!b1)
{
w2 = 1; // make sure
}
// b1 is the divisor bit value for CTRLA, per caches the actual divisor
per = (F_CPU / 2 / w2) / frequency;
if(!per)
{
per++;
}
// Calculate the toggle count
if (duration > 0)
{
toggle_count = 2 * frequency * duration / 1000;
}
else
{
toggle_count = -1;
}
toneBegin(_pin, b1, per);
}
// XXX: this function only works properly for timer E (the only one we use
// currently). Since I use the ISR on timer E to toggle the pin, it should
// be just fine.
void disableTimer(uint8_t _timer)
{
// parameter is ignored
#if NUM_DIGITAL_PINS > 18 /* meaning there is a PORT E available */
// disable under/overflow and comparison interrupts FIRST
TCE0_INTCTRLA = 0; // no underflow interrupts
TCE0_INTCTRLB = 0; // no comparison interrupts
pTonePort = NULL; // make sure
// re-assign TCE0 defaults. see 'wiring.c'
#if NUM_DIGITAL_PINS > 22 /* meaning PORTE has 8 pins */
TCE2_CTRLA = 5; // b0101 - divide by 64 - D manual 13.9.1
TCE2_CTRLB = 0; // compare outputs disabled on all 8 bits (13.9.2)
// TCE2_CTRLC = 0; // when timer not running, sets compare (13.9.3)
TCE2_CTRLE = 0x2; // b10 - 'split' mode - D manual 13.9.4
TCE2_CTRLF = 0; // not resetting or anything (13.9.7)
TCE2_LPER = 255; // count 255 to 0 (total period = 256)
TCE2_HPER = 255;
// pre-assign comparison registers to 'zero' (for PWM out) which is actually 255
// 'timer 2' counts DOWN. This, however, would generate a '1' output.
TCE2_LCMPA = 255;
TCE2_LCMPB = 255;
TCE2_LCMPC = 255;
TCE2_LCMPD = 255;
TCE2_HCMPA = 255;
TCE2_HCMPB = 255;
TCE2_HCMPC = 255;
TCE2_HCMPD = 255;
TCE2_INTCTRLA = 0; // no underflow interrupts
TCE2_INTCTRLB = 0; // no comparison interrupts
#else // 16-bit timer on TCE0
TCE0_CTRLA = 5; // b0101 - divide by 64 - D manual 12.11.1
TCE0_CTRLB = TC_WGMODE_SS_gc; // single-slope PWM. NOTE: this counts UP, whereas the other timers count DOWN
// other bits (high nybble) are OFF - they enable output on the 4 port E pins
// TCE0_CTRLC = 0; // when timer not running, sets compare (12.11.3)
TCE0_CTRLD = 0; // not an event timer, 16-bit mode (12.11.4)
TCE0_CTRLE = 1; // normal 8-bit timer (set to 0 for 16-bit mode) (12.11.5)
// make sure the timer E 'period' register is correctly set at 255 (i.e. 0-255 or 256 clock cycles).
TCE0_PER = 255;
// pre-assign comparison registers to 'zero' (for PWM out) which is actually 255
// timer 0 can be configured to count UP or DOWN, but for single-slope PWM it is
// always 'UP'. A value of '255' should generate a '1' output for each PWM.
TCE0_CCA = 255;
TCE0_CCB = 255;
TCE0_CCC = 255;
TCE0_CCD = 255;
#endif // 8/16 bit timer on E
#elif defined(TCC4) // E series and anything else with 'TCC4'
// disable under/overflow and comparison interrupts FIRST
TCC4_INTCTRLA = 0; // no underflow interrupts
TCC4_INTCTRLB = 0; // no comparison interrupts
pTonePort = NULL; // make sure
// re-assign TCC0 defaults. see 'wiring.c'
TCC4_CTRLA = 5; // b0101 - divide by 64 - E manual 13.13.1
TCC4_CTRLB = TC45_BYTEM_BYTEMODE_gc | TC45_WGMODE_SINGLESLOPE_gc; // byte mode, single slope
// TCC5_CTRLC = 0; // when timer not running, sets compare (13.9.3)
TCC4_CTRLD = 0; // events off
TCC4_CTRLE = 0; // no output on L pins
TCC4_CTRLF = 0; // no output on H pins
TCC4_PER = 255; // 255 for period limit
// pre-assign comparison registers to 'zero' (for PWM out) which is actually 255
// 'timer 2' counts DOWN.
TCC4_CCA = 65535;
TCC4_CCB = 65535;
TCC4_CCC = 65535;
TCC4_CCD = 65535;
#else // other stuff not yet explored by me
// disable under/overflow and comparison interrupts FIRST
TCC0_INTCTRLA = 0; // no underflow interrupts
TCC0_INTCTRLB = 0; // no comparison interrupts
pTonePort = NULL; // make sure
// re-assign TCC0 defaults. see 'wiring.c'
TCC2_CTRLA = 5; // b0101 - divide by 64 - D manual 13.9.1
TCC2_CTRLB = 0; // compare outputs disabled on all 8 bits (13.9.2)
// TCC2_CTRLC = 0; // when timer not running, sets compare (13.9.3)
TCC2_CTRLE = 0x2; // b10 - 'split' mode - D manual 13.9.4
TCC2_CTRLF = 0; // not resetting or anything (13.9.7)
TCC2_LPER = 255; // count 255 to 0 (total period = 256)
TCC2_HPER = 255;
// pre-assign comparison registers to 'zero' (for PWM out) which is actually 255
// 'timer 2' counts DOWN. This, however, would generate a '1' output.
TCC2_LCMPA = 255;
TCC2_LCMPB = 255;
TCC2_LCMPC = 255;
TCC2_LCMPD = 255;
TCC2_HCMPA = 255;
TCC2_HCMPB = 255;
TCC2_HCMPC = 255;
TCC2_HCMPD = 255;
TCC2_INTCTRLA = 0; // no underflow interrupts
TCC2_INTCTRLB = 0; // no comparison interrupts
#endif // NUM_DIGITAL_PINS > 18
}
void noTone(uint8_t _pin)
{
disableTimer(0);
digitalWrite(_pin, 0);
}
#if NUM_DIGITAL_PINS > 18 /* meaning PORTE exists */
ISR(TCE0_OVF_vect) // the 'overflow' vector on timer E0
#elif defined(TCC4) // E series and anything else with 'TCC4'
ISR(TCC4_OVF_vect) // the 'overflow' vector on timer C4
#else // everything else
ISR(TCC0_OVF_vect) // the 'overflow' vector on timer C0
#endif // PORTE exist check
{
if(!toggle_count || !pTonePort || !bToneMask
#if 1 /* this section in for bullet-proofing, consider removing */
|| (pTonePort != &PORTA &&
#if NUM_ANALOG_PINS > 8
pTonePort != &PORTB &&
#endif // NUM_ANALOG_PINS > 8
pTonePort != &PORTC && pTonePort != &PORTD &&
#if NUM_DIGITAL_PINS > 18
pTonePort != &PORTE &&
#endif // PORTE exist check
pTonePort != &PORTR)
#endif // 1
)
{
// disable the timer (also disables the interrupt)
disableTimer(0);
return;
}
// each time I get an overflow, toggle the tone pin
pTonePort->OUTTGL = bToneMask; // toggle that bit
toggle_count--;
}
#if 0 // OLD CODE for reference only
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
#define TCCR2A TCCR2
#define TCCR2B TCCR2
#define COM2A1 COM21
#define COM2A0 COM20
#define OCR2A OCR2
#define TIMSK2 TIMSK
#define OCIE2A OCIE2
#define TIMER2_COMPA_vect TIMER2_COMP_vect
#define TIMSK1 TIMSK
#endif
// timerx_toggle_count:
// > 0 - duration specified
// = 0 - stopped
// < 0 - infinitely (until stop() method called, or new play() called)
#if !defined(__AVR_ATmega8__)
volatile long timer0_toggle_count;
volatile uint8_t *timer0_pin_port;
volatile uint8_t timer0_pin_mask;
#endif
volatile long timer1_toggle_count;
volatile uint8_t *timer1_pin_port;
volatile uint8_t timer1_pin_mask;
volatile long timer2_toggle_count;
volatile uint8_t *timer2_pin_port;
volatile uint8_t timer2_pin_mask;
#if defined(TIMSK3)
volatile long timer3_toggle_count;
volatile uint8_t *timer3_pin_port;
volatile uint8_t timer3_pin_mask;
#endif
#if defined(TIMSK4)
volatile long timer4_toggle_count;
volatile uint8_t *timer4_pin_port;
volatile uint8_t timer4_pin_mask;
#endif
#if defined(TIMSK5)
volatile long timer5_toggle_count;
volatile uint8_t *timer5_pin_port;
volatile uint8_t timer5_pin_mask;
#endif
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER2
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
#elif defined(__AVR_ATmega8__)
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER2
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
#elif defined(__AVR_ATmega32U4__)
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER3
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
#else
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER2
// Leave timer 0 to last.
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
#endif
// NOTE: K&R coding style edited away. Allman style rules - BF
static int8_t toneBegin(uint8_t _pin)
{
int8_t _timer = -1;
// if we're already using the pin, the timer should be configured.
for (int i = 0; i < AVAILABLE_TONE_PINS; i++)
{
if (tone_pins[i] == _pin)
{
return pgm_read_byte(tone_pin_to_timer_PGM + i);
}
}
// search for an unused timer.
for (int i = 0; i < AVAILABLE_TONE_PINS; i++)
{
if (tone_pins[i] == 255)
{
tone_pins[i] = _pin;
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
break;
}
}
if (_timer != -1)
{
// Set timer specific stuff
// All timers in CTC mode
// 8 bit timers will require changing prescalar values,
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
switch (_timer)
{
#if defined(TCCR0A) && defined(TCCR0B)
case 0:
// 8 bit timer
TCCR0A = 0;
TCCR0B = 0;
bitWrite(TCCR0A, WGM01, 1);
bitWrite(TCCR0B, CS00, 1);
timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer0_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
case 1:
// 16 bit timer
TCCR1A = 0;
TCCR1B = 0;
bitWrite(TCCR1B, WGM12, 1);
bitWrite(TCCR1B, CS10, 1);
timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer1_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR2A) && defined(TCCR2B)
case 2:
// 8 bit timer
TCCR2A = 0;
TCCR2B = 0;
bitWrite(TCCR2A, WGM21, 1);
bitWrite(TCCR2B, CS20, 1);
timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer2_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3)
case 3:
// 16 bit timer
TCCR3A = 0;
TCCR3B = 0;
bitWrite(TCCR3B, WGM32, 1);
bitWrite(TCCR3B, CS30, 1);
timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer3_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4)
case 4:
// 16 bit timer
TCCR4A = 0;
TCCR4B = 0;
#if defined(WGM42)
bitWrite(TCCR4B, WGM42, 1);
#elif defined(CS43)
#warning this may not be correct
// atmega32u4
bitWrite(TCCR4B, CS43, 1);
#endif
bitWrite(TCCR4B, CS40, 1);
timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer4_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5)
case 5:
// 16 bit timer
TCCR5A = 0;
TCCR5B = 0;
bitWrite(TCCR5B, WGM52, 1);
bitWrite(TCCR5B, CS50, 1);
timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer5_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
}
}
return _timer;
}
// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
{
uint8_t prescalarbits = 0b001;
long toggle_count = 0;
uint32_t ocr = 0;
int8_t _timer;
_timer = toneBegin(_pin);
if (_timer >= 0)
{
// Set the pinMode as OUTPUT
pinMode(_pin, OUTPUT);
// if we are using an 8 bit timer, scan through prescalars to find the best fit
if (_timer == 0 || _timer == 2)
{
ocr = F_CPU / frequency / 2 - 1;
prescalarbits = 0b001; // ck/1: same for both timers
if (ocr > 255)
{
ocr = F_CPU / frequency / 2 / 8 - 1;
prescalarbits = 0b010; // ck/8: same for both timers
if (_timer == 2 && ocr > 255)
{
ocr = F_CPU / frequency / 2 / 32 - 1;
prescalarbits = 0b011;
}
if (ocr > 255)
{
ocr = F_CPU / frequency / 2 / 64 - 1;
prescalarbits = _timer == 0 ? 0b011 : 0b100;
if (_timer == 2 && ocr > 255)
{
ocr = F_CPU / frequency / 2 / 128 - 1;
prescalarbits = 0b101;
}
if (ocr > 255)
{
ocr = F_CPU / frequency / 2 / 256 - 1;
prescalarbits = _timer == 0 ? 0b100 : 0b110;
if (ocr > 255)
{
// can't do any better than /1024
ocr = F_CPU / frequency / 2 / 1024 - 1;
prescalarbits = _timer == 0 ? 0b101 : 0b111;
}
}
}
}
#if defined(TCCR0B)
if (_timer == 0)
{
TCCR0B = prescalarbits;
}
else
#endif
#if defined(TCCR2B)
{
TCCR2B = prescalarbits;
}
#else
{
// dummy place holder to make the above ifdefs work
}
#endif
}
else
{
// two choices for the 16 bit timers: ck/1 or ck/64
ocr = F_CPU / frequency / 2 - 1;
prescalarbits = 0b001;
if (ocr > 0xffff)
{
ocr = F_CPU / frequency / 2 / 64 - 1;
prescalarbits = 0b011;
}
if (_timer == 1)
{
#if defined(TCCR1B)
TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
#endif
}
#if defined(TCCR3B)
else if (_timer == 3)
TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
#endif
#if defined(TCCR4B)
else if (_timer == 4)
TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
#endif
#if defined(TCCR5B)
else if (_timer == 5)
TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
#endif
}
// Calculate the toggle count
if (duration > 0)
{
toggle_count = 2 * frequency * duration / 1000;
}
else
{
toggle_count = -1;
}
// Set the OCR for the given timer,
// set the toggle count,
// then turn on the interrupts
switch (_timer)
{
#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
case 0:
OCR0A = ocr;
timer0_toggle_count = toggle_count;
bitWrite(TIMSK0, OCIE0A, 1);
break;
#endif
case 1:
#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
OCR1A = ocr;
timer1_toggle_count = toggle_count;
bitWrite(TIMSK1, OCIE1A, 1);
#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
// this combination is for at least the ATmega32
OCR1A = ocr;
timer1_toggle_count = toggle_count;
bitWrite(TIMSK, OCIE1A, 1);
#endif
break;
#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
case 2:
OCR2A = ocr;
timer2_toggle_count = toggle_count;
bitWrite(TIMSK2, OCIE2A, 1);
break;
#endif
#if defined(TIMSK3)
case 3:
OCR3A = ocr;
timer3_toggle_count = toggle_count;
bitWrite(TIMSK3, OCIE3A, 1);
break;
#endif
#if defined(TIMSK4)
case 4:
OCR4A = ocr;
timer4_toggle_count = toggle_count;
bitWrite(TIMSK4, OCIE4A, 1);
break;
#endif
#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
case 5:
OCR5A = ocr;
timer5_toggle_count = toggle_count;
bitWrite(TIMSK5, OCIE5A, 1);
break;
#endif
}
}
}
// XXX: this function only works properly for timer 2 (the only one we use
// currently). for the others, it should end the tone, but won't restore
// proper PWM functionality for the timer.
void disableTimer(uint8_t _timer)
{
switch (_timer)
{
case 0:
#if defined(TIMSK0)
TIMSK0 = 0;
#elif defined(TIMSK)
TIMSK = 0; // atmega32
#endif
break;
#if defined(TIMSK1) && defined(OCIE1A)
case 1:
bitWrite(TIMSK1, OCIE1A, 0);
break;
#endif
case 2:
#if defined(TIMSK2) && defined(OCIE2A)
bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
#endif
#if defined(TCCR2A) && defined(WGM20)
TCCR2A = (1 << WGM20);
#endif
#if defined(TCCR2B) && defined(CS22)
TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
#endif
#if defined(OCR2A)
OCR2A = 0;
#endif
break;
#if defined(TIMSK3)
case 3:
TIMSK3 = 0;
break;
#endif
#if defined(TIMSK4)
case 4:
TIMSK4 = 0;
break;
#endif
#if defined(TIMSK5)
case 5:
TIMSK5 = 0;
break;
#endif
}
}
// XXX: this function only works properly for timer 2 (the only one we use
// currently). for the others, it should end the tone, but won't restore
// proper PWM functionality for the timer.
void disableTimer(uint8_t _timer)
void noTone(uint8_t _pin)
{
int8_t _timer = -1;
for (int i = 0; i < AVAILABLE_TONE_PINS; i++)
{
if (tone_pins[i] == _pin)
{
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
tone_pins[i] = 255;
}
}
disableTimer(_timer);
digitalWrite(_pin, 0);
}
#ifdef USE_TIMER0
ISR(TIMER0_COMPA_vect)
{
if (timer0_toggle_count != 0)
{
// toggle the pin
*timer0_pin_port ^= timer0_pin_mask;
if (timer0_toggle_count > 0)
timer0_toggle_count--;
}
else
{
disableTimer(0);
*timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop
}
}
#endif
#ifdef USE_TIMER1
ISR(TIMER1_COMPA_vect)
{
if (timer1_toggle_count != 0)
{
// toggle the pin
*timer1_pin_port ^= timer1_pin_mask;
if (timer1_toggle_count > 0)
timer1_toggle_count--;
}
else
{
disableTimer(1);
*timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
}
}
#endif
#ifdef USE_TIMER2
ISR(TIMER2_COMPA_vect)
{
if (timer2_toggle_count != 0)
{
// toggle the pin
*timer2_pin_port ^= timer2_pin_mask;
if (timer2_toggle_count > 0)
timer2_toggle_count--;
}
else
{
// need to call noTone() so that the tone_pins[] entry is reset, so the
// timer gets initialized next time we call tone().
// XXX: this assumes timer 2 is always the first one used.
noTone(tone_pins[0]);
// disableTimer(2);
// *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
}
}
#endif
#ifdef USE_TIMER3
ISR(TIMER3_COMPA_vect)
{
if (timer3_toggle_count != 0)
{
// toggle the pin
*timer3_pin_port ^= timer3_pin_mask;
if (timer3_toggle_count > 0)
timer3_toggle_count--;
}
else
{
disableTimer(3);
*timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop
}
}
#endif
#ifdef USE_TIMER4
ISR(TIMER4_COMPA_vect)
{
if (timer4_toggle_count != 0)
{
// toggle the pin
*timer4_pin_port ^= timer4_pin_mask;
if (timer4_toggle_count > 0)
timer4_toggle_count--;
}
else
{
disableTimer(4);
*timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop
}
}
#endif
#ifdef USE_TIMER5
ISR(TIMER5_COMPA_vect)
{
if (timer5_toggle_count != 0)
{
// toggle the pin
*timer5_pin_port ^= timer5_pin_mask;
if (timer5_toggle_count > 0)
timer5_toggle_count--;
}
else
{
disableTimer(5);
*timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop
}
}
#endif
#endif // 0 [OLD CODE]
#endif // TONE_SUPPORTED

View File

@@ -0,0 +1,275 @@
//////////////////////////////////////////////////////////////////////////////
// //
// _ _ ____ ____ _ _ _ //
// | | | |/ ___| | __ ) / \ _ __ (_) | |__ //
// | | | |\___ \ | _ \ / _ \ | '_ \ | | | '_ \ //
// | |_| | ___) || |_) |/ ___ \ | |_) || | _ | | | | //
// \___/ |____/ |____//_/ \_\| .__/ |_|(_)|_| |_| //
// |_| //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef __USBAPI__
#define __USBAPI__
#if defined(USBCON)
#include "USBCore.h" /* make sure since I use its definitions here */
#ifdef DEBUG_CODE
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
extern void error_print(const char *p1); // TEMPORARY
extern void error_print_(const char *p1); // TEMPORARY
extern void error_printH(unsigned long); // TEMPORARY
extern void error_printH_(unsigned long); // TEMPORARY
extern void error_printL(unsigned long); // TEMPORARY
extern void error_printL_(unsigned long); // TEMPORARY
extern void error_printP(const void * /*PROGMEM*/ p1); // TEMPORARY
extern void error_printP_(const void * /*PROGMEM*/ p1); // TEMPORARY
extern void DumpHex(void *pBuf, uint8_t nBytes);
#ifdef __cplusplus
}
#endif // __cplusplus
#else // DEBUG_CODE
#define error_print(p1)
#define error_print_(p1)
#define error_printH(X)
#define error_printH_(X)
#define error_printL(X)
#define error_printL_(X)
#define error_printP(p1)
#define error_printP_(p1)
#define DumpHex(X,Y)
#endif // DEBUG_CODE
//================================================================================
//================================================================================
// USB
class USBDevice_
{
public:
USBDevice_();
bool configured();
void attach();
void detach(); // Serial port goes down too...
void poll();
protected:
static XMegaEPDataStruct *GetEPData(); // necessary
};
extern USBDevice_ USBDevice;
//================================================================================
//================================================================================
// Serial over CDC (Serial1 is the physical port)
class Serial_ : public Stream
{
protected:
int peek_buffer;
public:
Serial_() { peek_buffer = -1; };
void begin(unsigned long);
void begin(unsigned long, uint8_t);
void end(void);
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t*, size_t);
using Print::write; // pull in write(str) etc. from Print
operator bool();
};
extern Serial_ Serial; // NOTE: HardwareSerial.h defines the 1st port as 'Serial1' whenever USBCON defined
//================================================================================
//================================================================================
// Mouse
#define MOUSE_LEFT 1
#define MOUSE_RIGHT 2
#define MOUSE_MIDDLE 4
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
class Mouse_
{
protected:
uint8_t _buttons;
void buttons(uint8_t b);
public:
Mouse_(void);
void begin(void);
void end(void);
void click(uint8_t b = MOUSE_LEFT);
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
};
extern Mouse_ Mouse;
//================================================================================
//================================================================================
// Keyboard
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87
#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
#define KEY_F9 0xCA
#define KEY_F10 0xCB
#define KEY_F11 0xCC
#define KEY_F12 0xCD
// Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
uint8_t modifiers;
uint8_t reserved;
uint8_t keys[6];
} KeyReport;
class Keyboard_ : public Print
{
protected:
KeyReport _keyReport;
void sendReport(KeyReport* keys);
public:
Keyboard_(void);
void begin(void);
void end(void);
virtual size_t write(uint8_t k);
virtual size_t press(uint8_t k);
virtual size_t release(uint8_t k);
virtual void releaseAll(void);
};
extern Keyboard_ Keyboard;
//================================================================================
//================================================================================
// Low level API
typedef struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint8_t wValueL;
uint8_t wValueH;
uint16_t wIndex;
uint16_t wLength;
} Setup;
//================================================================================
//================================================================================
// HID 'Driver'
int HID_GetNumInterfaces(void);
int HID_GetInterfaceDataLength(void);
int HID_SendInterfaceData(void);
bool HID_SendDeviceDescriptor(void);
int HID_GetDescriptor(int i); // handles the 'GET DESCRIPTOR' control packet
bool HID_Setup(Setup& setup); // handles a 'SETUP' control packet
void HID_SendReport(uint8_t id, const void* data, int len);
void HID_Reset(void); // called whenever I get a bus reset
//================================================================================
//================================================================================
// CDC 'Driver'
bool CDC_SendIAD(void);
int CDC_GetNumInterfaces(void);
int CDC_GetInterfaceDataLength(void);
int CDC_SendInterfaceData(void);
bool CDC_SendDeviceDescriptor(void);
int CDC_GetDescriptor(int i); // handles the 'GET DESCRIPTOR' control packet
bool CDC_Setup(Setup& setup); // handles a 'SETUP' control packet
void CDC_FrameReceived(void); // call when frame is received and EP is configured
void CDC_SendACM(void); // call when you need to send a packet on the interrupt EP
void CDC_Reset(void); // called whenever I get a bus reset
//================================================================================
//================================================================================
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40
#define TRANSFER_TOGGLE_ON 0x20 /* assign this to pre-set the 'toggle' bit on - only works when send queue is empty */
#define TRANSFER_TOGGLE_OFF 0x10 /* assign this to pre-set the 'toggle' bit off - only works when send queue is empty */
// NOTE: USB_SendControl returns # of bytes sent, or 0x8000 if a ZLP is sent
// it will return 0 on error, such as the inability to allocate a buffer
// control packets send 64 bytes at a time, so the total size is limited
// by the number of available buffers.
int USB_SendControl(uint8_t flags, const void* d, int len);
#ifdef PROGMEM
int USB_SendControlP(uint8_t flags, const void * PROGMEM d, int len);
// called internally if you use TRANSFER_PGM flag; you can also call this directly
#endif // PROGMEM
uint16_t USB_Available(uint8_t ep); // returns # of bytes in the buffer on an OUT or CONTROL endpoint
uint16_t USB_SendQLength(uint8_t ep); // returns # of buffers in the send queue for an IN or CONTROL endpoint
bool USB_IsSendQFull(uint8_t ep); // this returns TRUE if there are too many outgoing buffers already (IN, CONTROL)
bool USB_IsStalled(uint8_t ep); // this tells me I'm 'stalled' (BULK IN, INTERRUPT, CONTROL)
int USB_Send(uint8_t ep, const void* data, // send endpoint data. bSendNow marks it "to send"
int len, uint8_t bSendNow);
int USB_Recv(uint8_t ep, void* data, // 'receive' data from endpoint receive queue. returns < 0 on error, or # of bytes
int len);
int USB_Recv(uint8_t ep); // 'receive' one byte of data from endpoint receive queue
void USB_Flush(uint8_t ep); // 'sends' all pending data by marking the buffers "to send"
uint16_t GetFrameNumber(void); // a debug API to obtain the latest USB frame number
uint8_t USB_GetEPType(uint8_t nEP); // another debug API to return endpoint type by index
#endif
#endif /* if defined(USBCON) */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,442 @@
//////////////////////////////////////////////////////////////////////////////
// //
// _ _ ____ ____ ____ _ //
// | | | |/ ___| | __ ) / ___| ___ _ __ ___ | |__ //
// | | | |\___ \ | _ \ | | / _ \ | '__|/ _ \ | '_ \ //
// | |_| | ___) || |_) || |___| (_) || | | __/ _ | | | | //
// \___/ |____/ |____/ \____|\___/ |_| \___|(_)|_| |_| //
// //
// //
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2010, Peter Barrett
/*
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
#ifndef __USBCORE_H__
#define __USBCORE_H__
// USB implementation MUST have USB_VID and USB_PID defined - can be done in 'boards.txt'
#if defined(USBCON) /* TODO add others here, things that require VID and PID for USB */
#ifdef USB_VID
#if USB_VID==null
#error cannot work with NULL value for VID
#endif // USB_VID==null
#else
#error must define USB_VID
#endif // USB_VID
#ifdef USB_PID
#if USB_PID==null
#error cannot work with NULL value for PID
#endif // USB_PID==null
#else
#error must define USB_PID
#endif // USB_PID
#endif // defined(USBCON)
#define FAST_USB /* necessary for 'FULL' speed operation - this is 12Mbit, not 480Mbit USB 2 'HIGH' speed - 'LOW' may not work properly */
#ifndef _PLATFORM_H_TYPES_DEFINED_ /* TEMPORARY FIX, SEE Platform.h */
#define _PLATFORM_H_TYPES_DEFINED_
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#endif // _PLATFORM_H_TYPES_DEFINED_
// Standard requests
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define SET_DESCRIPTOR 7
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
// bmRequestType
#define REQUEST_HOSTTODEVICE 0x00
#define REQUEST_DEVICETOHOST 0x80 /* device to host, i.e. 'in' - when not set, it's 'out' (host to device) */
#define REQUEST_DIRECTION 0x80
#define REQUEST_STANDARD 0x00
#define REQUEST_CLASS 0x20
#define REQUEST_VENDOR 0x40
#define REQUEST_TYPE 0x60
#define REQUEST_DEVICE 0x00
#define REQUEST_INTERFACE 0x01
#define REQUEST_ENDPOINT 0x02
#define REQUEST_OTHER 0x03
#define REQUEST_RECIPIENT 0x03
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE)
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE)
// Class requests
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#define MSC_RESET 0xFF
#define MSC_GET_MAX_LUN 0xFE
#define HID_GET_REPORT 0x01
#define HID_GET_IDLE 0x02
#define HID_GET_PROTOCOL 0x03
#define HID_SET_REPORT 0x09
#define HID_SET_IDLE 0x0A
#define HID_SET_PROTOCOL 0x0B
// Descriptors
#define USB_DEVICE_DESC_SIZE 18
#define USB_CONFIGUARTION_DESC_SIZE 9
#define USB_INTERFACE_DESC_SIZE 9
#define USB_ENDPOINT_DESC_SIZE 7
#define USB_DEVICE_DESCRIPTOR_TYPE 1
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
#define USB_STRING_DESCRIPTOR_TYPE 3
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
#define USB_DEVICE_QUALIFIER_TYPE 6
#define USB_OTHER_SPEED_CONFIGURATION_TYPE 7
#define USB_INTERFACE_POWER_TYPE 8
#define USB_OTG_TYPE 9
#define USB_DEVICE_DEBUG_TYPE 10
#define USB_INTERFACE_ASSOCIATION_TYPE 11 /* see InterfaceAssociationDescriptor_ecn.pdf */
// NOTE: for USB_INTERFACE_ASSOCIATION_TYPE respond with IADDescriptor
#define USB_DEVICE_CLASS_ZERO 0x00
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
#define USB_DEVICE_CLASS_STORAGE 0x08
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
#define USB_CONFIG_POWERED_MASK 0x40
#define USB_CONFIG_BUS_POWERED 0x80
#define USB_CONFIG_SELF_POWERED 0xC0
#define USB_CONFIG_REMOTE_WAKEUP 0x20
// bMaxPower in Configuration Descriptor
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
// bEndpointAddress in Endpoint Descriptor
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
#define CDC_V1_10 0x0110
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
#define CDC_CALL_MANAGEMENT 0x01
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
#define CDC_HEADER 0x00
#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
#define CDC_UNION 0x06
#define CDC_CS_INTERFACE 0x24
#define CDC_CS_ENDPOINT 0x25
#define CDC_DATA_INTERFACE_CLASS 0x0A
#define MSC_SUBCLASS_SCSI 0x06
#define MSC_PROTOCOL_BULK_ONLY 0x50
#define HID_HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
// CONTROL LINE STATE and SERIAL STATE - BIT VALUES (16-bits, LE)
// USED BY 'SET CONTROL LINE STATE' and 'SERIAL STATE' FOR CAM INTERRUPT 'IN'
#define CONTROL_LINE_STATE_DTR 0x01 /* data terminal ready [ok to send on IN] */
#define CONTROL_LINE_STATE_RTS 0x02 /* ready to send [has data ready for OUT] */
#define SERIAL_STATE_RX_CARRIER_DCD 0x01 /* receive carrier detect - on to allow receive */
#define SERIAL_STATE_TX_CARRIER_DSR 0x02 /* data set ready - inform host I have data */
#define SERIAL_STATE_BREAK_DETECT 0x04 /* 'break' detect */
#define SERIAL_STATE_RING_DETECT 0x08 /* 'ring' detect */
#define SERIAL_STATE_FRAMING_ERROR 0x10 /* framing error */
#define SERIAL_STATE_PARITY_ERROR 0x20 /* parity error */
#define SERIAL_STATE_OVERRUN 0x40 /* overrun input (data lost) */
// A1U series needs 16-byte alignment for endpoint structure
#if defined(__AVR_ATxmega64A1U__) || defined(__AVR_ATxmega128A1U__)
#define A1U_SERIES
#endif // A1U
// Device
typedef struct _device_descriptor_
{
u8 len; // 18
u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
u16 usbVersion; // 0x200
u8 deviceClass;
u8 deviceSubClass;
u8 deviceProtocol;
u8 packetSize0; // Packet 0
u16 idVendor;
u16 idProduct;
u16 deviceVersion; // 0x100
u8 iManufacturer;
u8 iProduct;
u8 iSerialNumber;
u8 bNumConfigurations;
} DeviceDescriptor;
// Config
typedef struct _config_descriptor_
{
u8 len; // 9
u8 dtype; // 2
u16 clen; // total length
u8 numInterfaces;
u8 config;
u8 iconfig;
u8 attributes;
u8 maxPower;
} ConfigDescriptor;
// String
// Interface
typedef struct _interface_descriptor_
{
u8 len; // 9
u8 dtype; // 4
u8 number;
u8 alternate;
u8 numEndpoints;
u8 interfaceClass;
u8 interfaceSubClass;
u8 protocol;
u8 iInterface;
} InterfaceDescriptor;
// Endpoint
typedef struct _endpoint_descriptor_
{
u8 len; // 7
u8 dtype; // 5
u8 addr;
u8 attr;
u16 packetSize;
u8 interval;
} EndpointDescriptor;
// Interface Association Descriptor
// Used to bind 2 interfaces together in CDC compostite device
typedef struct _iad_descriptor_
{
u8 len; // 8
u8 dtype; // 11
u8 firstInterface;
u8 interfaceCount;
u8 functionClass;
u8 funtionSubClass;
u8 functionProtocol;
u8 iInterface;
} IADDescriptor;
// CDC CS interface descriptor
typedef struct _cdccs_interface_descriptor_
{
u8 len; // 5
u8 dtype; // 0x24
u8 subtype;
u8 d0;
u8 d1;
} CDCCSInterfaceDescriptor;
typedef struct _cdccs_interface_descriptor4_
{
u8 len; // 4
u8 dtype; // 0x24
u8 subtype;
u8 d0;
} CDCCSInterfaceDescriptor4;
typedef struct _cm_functional_descriptor_
{
u8 len; // 5
u8 dtype; // 0x24
u8 subtype; // 1
u8 bmCapabilities;
u8 bDataInterface;
} CMFunctionalDescriptor;
typedef struct _acm_functional_descriptor_
{
u8 len;
u8 dtype; // 0x24
u8 subtype; // 1
u8 bmCapabilities;
} ACMFunctionalDescriptor;
typedef struct _cdc_descriptor_
{
// // IAD
// IADDescriptor iad; // for complex endpoints (apparently not critical)
// Control
InterfaceDescriptor cif; //
CDCCSInterfaceDescriptor header;
// CMFunctionalDescriptor callManagement; // Call Management
ACMFunctionalDescriptor controlManagement; // ACM
CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
EndpointDescriptor cifin;
// Data
InterfaceDescriptor dif;
EndpointDescriptor in;
EndpointDescriptor out;
} CDCDescriptor;
typedef struct _msc_descriptor_
{
InterfaceDescriptor msc;
EndpointDescriptor in;
EndpointDescriptor out;
} MSCDescriptor;
typedef struct _hid_desc_descriptor_
{
u8 len; // 9
u8 dtype; // 0x21
u8 addr;
u8 versionL; // 0x101
u8 versionH; // 0x101
u8 country;
u8 desctype; // 0x22 report
u8 descLenL;
u8 descLenH;
} HIDDescDescriptor;
typedef struct _hid_descriptor_
{
InterfaceDescriptor hid;
HIDDescDescriptor desc;
EndpointDescriptor in;
} HIDDescriptor;
// XMEGA STRUCTURES
#define MAXEP 5 /*15*/ /* 4 bit value, 0-15 - see 20.14.1 'CTRLA register' in AU manual */
// I assigned this to '5' because there are only 5 endpoints being used by THIS code.
// The 'mega' code could only have a total of 6 and 0 was always the 'control' endpoint
// and setting a 'smaller-than-maximum' value for XMEGA burns up less RAM.
// If this poses a problem I _could_ malloc the structures, but to be effective, it would
// have to require a reboot to change it, or you'd get major RAM fragmentation
//
// TODO: put MAXEP into pins_arduino.h and override if too small (or not defined already)
typedef union _xmega_fifo_entry_
{
struct
{
uint8_t h, l;
};
uint16_t heW; // high endian word
} XMegaFIFOEntry;
typedef struct _xmega_fifo_
{
XMegaFIFOEntry in;
XMegaFIFOEntry out;
} XMegaFIFO;
// see AU manual, pg 231 section 20.4
typedef struct _xmega_endpoint_descriptor_
{
volatile uint8_t status;
volatile uint8_t ctrl;
volatile uint16_t /*HLByteWord*/ cnt; // so, cnt.w is the 16-bit value, cnt.l and cnt.h the 8-bit low/high
// it is the 'data count' value. it may be zero.
// only bits 1:0 of cnt.h are valid. cnt.w should be 'and'd with 0x3ff
// the high bit of cnt.w and cnt.h is the 'AZLP' (auto zero length packet) bit
// see AU manual section 20.15.4
volatile uint16_t /*HLByteWord*/ dataptr; // pointer to data buffer. max packet length assigned to CTRL [1:0] or [2:0]
// see table 20-5 in AU manual for max packet length. may need 2 buffers "that long"
volatile uint16_t /*HLByteWord*/ auxdata; // used for multi-packet transfers
} XMegaEndpointDescriptor; // NOTE: 2 per channel (one 'out', one 'in') pointed by EPPTR
typedef struct _xmega_endpoint_channel_
{
XMegaEndpointDescriptor out;
XMegaEndpointDescriptor in;
} XMegaEndpointChannel
#ifdef A1U_SERIES
__attribute (( aligned (16) ));
#else // not an A1U series
__attribute__ (( aligned (2) /*, packed*/));
#endif // A1U or not
// also section 20.4 in AU manual
typedef struct _XMegaEPDataStruct_
{
#ifdef A1U_SERIES
#if ((MAXEP+1)%4) != 0 // A1U needs 16-byte boundary, not merely word-aligned
uint8_t padding[sizeof(XMegaFIFO) * (4 - ((MAXEP+1)%4))]; // this should 16-byte align 'endpoint' as required
#endif // needs padding
#endif // XMEGA A1U series
XMegaFIFO fifo[MAXEP + 1];
XMegaEndpointChannel endpoint[MAXEP + 1]; // point EPPTR to THIS (must be word boundary)
volatile uint16_t framenum; // 1 word frame number
} XMegaEPDataStruct /*__attribute__ ((packed))*/; // note: point EPPTR to &endpoint[0], word alignment needed
#ifdef DEBUG_CODE
uint16_t endpoint_data_pointer(void);
#define EP_DATA_STRUCT() ((XMegaEPDataStruct *)(endpoint_data_pointer() - (uint16_t)&(((XMegaEPDataStruct *)0)->endpoint[0])))
#endif // DEBUG_CODE
// this is the USB Device Descriptor
#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
#define D_CONFIG(_totalLength,_interfaces) \
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) }
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
{ 7, 5, _addr,_attr,_packetSize, _interval }
#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
#define D_HIDREPORT(_descriptorLength) \
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 }
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
#endif

View File

@@ -0,0 +1,83 @@
//////////////////////////////////////////////////////////////////////////////
// //
// _ _ ____ ____ ____ _ //
// | | | |/ ___| | __ ) | _ \ ___ ___ ___ | |__ //
// | | | |\___ \ | _ \ | | | | / _ \/ __| / __| | '_ \ //
// | |_| | ___) || |_) || |_| || __/\__ \| (__ _ | | | | //
// \___/ |____/ |____/ |____/ \___||___/ \___|(_)|_| |_| //
// //
// //
//////////////////////////////////////////////////////////////////////////////
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
// NOTE: don't define these here; define them in pins_arduino.h
//#define CDC_ENABLED
//#define HID_ENABLED
#ifdef CDC_ENABLED
#define CDC_INTERFACE_COUNT 2
#define CDC_ENDPOINT_COUNT 3
#else
#define CDC_INTERFACE_COUNT 0
#define CDC_ENPOINT_COUNT 0
#endif
#ifdef HID_ENABLED
#define HID_INTERFACE_COUNT 1
#define HID_ENPOINT_COUNT 1
#else
#define HID_INTERFACE_COUNT 0
#define HID_ENPOINT_COUNT 0
#endif
#define CDC_ACM_INTERFACE 0 // CDC ACM interface
#define CDC_DATA_INTERFACE 1 // CDC Data interface
#define CDC_FIRST_ENDPOINT 1
#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First
#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1)
#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2)
#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface
#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT)
#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT)
#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT)
#ifdef CDC_ENABLED
#define CDC_RX CDC_ENDPOINT_OUT
#define CDC_TX CDC_ENDPOINT_IN
#define CDC_ACM CDC_ENDPOINT_ACM
#endif
#ifdef HID_ENABLED
#define HID_TX HID_ENDPOINT_INT
#endif
// string indexes/indices for USB_STRING_DESCRIPTOR_TYPE
#define USB_STRING_INDEX_LANGUAGE 0 /* not actually a STRING though */
#define USB_STRING_INDEX_MANUFACTURER 1
#define USB_STRING_INDEX_PRODUCT 2
#define USB_STRING_INDEX_DESCRIPTION 3
#define USB_STRING_INDEX_VERSION 4
#define USB_STRING_INDEX_URL 5
#define USB_STRING_INDEX_SERIAL 6
#define USB_STRING_INDEX_CONFIG 7

View File

@@ -0,0 +1,88 @@
/*
* Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* bjoern@cs.stanford.edu 12/30/2008
*/
#ifndef udp_h
#define udp_h
#include <Stream.h>
#include <IPAddress.h>
class UDP : public Stream {
public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop() =0; // Finish with the UDP socket
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() =0;
// Number of bytes remaining in the current packet
virtual int available() =0;
// Read a single byte from the current packet
virtual int read() =0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) =0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() =0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
#endif

View File

@@ -0,0 +1,168 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Character_h
#define Character_h
#include <ctype.h>
// WCharacter.h prototypes
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
inline boolean isAlpha(int c) __attribute__((always_inline));
inline boolean isAscii(int c) __attribute__((always_inline));
inline boolean isWhitespace(int c) __attribute__((always_inline));
inline boolean isControl(int c) __attribute__((always_inline));
inline boolean isDigit(int c) __attribute__((always_inline));
inline boolean isGraph(int c) __attribute__((always_inline));
inline boolean isLowerCase(int c) __attribute__((always_inline));
inline boolean isPrintable(int c) __attribute__((always_inline));
inline boolean isPunct(int c) __attribute__((always_inline));
inline boolean isSpace(int c) __attribute__((always_inline));
inline boolean isUpperCase(int c) __attribute__((always_inline));
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline boolean isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline boolean isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline boolean isAscii(int c)
{
return ( isascii (c) == 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline boolean isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline boolean isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline boolean isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline boolean isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline boolean isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline boolean isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline boolean isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline boolean isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline boolean isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline boolean isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
return toascii (c);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
#endif

View File

@@ -0,0 +1,808 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.uniandes.edu.co
Copyright (c) 2004-05 Hernando Barragan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Modified 24 November 2006 by David A. Mellis
Modified 1 August 2010 by Mark Sproul
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
In some cases, the xmega updates make assumptions about the pin assignments.
See 'pins_arduino.h' for more detail.
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include "wiring_private.h"
// interrupts on the xmega are handled differently than the mega
// there are 2 interrupt vectors for each port. Typical xmega
// will use ports A, B, C, D, E, and R. The vectors for those
// are as follows:
//
// PORTn_INT0_vect
// - and -
// PORTn_INT1_vect
//
// where 'n' is A, B, C, D, E, or R
//
// Additional vectors are:
//
// OSC_XOSCF_vect (external oscillator failure, NMI)
//
// RTC_OVF_vect (real-time clock overflow)
// RTC_COMP_vect (real-time clock compare)
//
// TWIC_TWIS_vect (2-wire slave on port C)
// TWIC_TWIM_vect (2-wire master on port C)
// TWIE_TWIS_vect (2-wire slave on port E)
// TWIE_TWIM_vect (2-wire master on port E)
//
// timers - 'n' is C or D
// TCn0_OVF_vect (n timer 0 overflow)
// TCn1_OVF_vect (n timer 1 overflow)
// TCn2_LUNF_vect (n timer 2 low byte underflow)
// TCn2_HUNF_vect (n timer 2 high byte underflow)
// TCE0_OVF_vect (E timer 0 overflow)
// TCn0_ERR_vect (n timer 0 error)
// TCn1_ERR_vect (n timer 1 error)
// TCE0_ERR_vect (E timer 0 error)
// TCn0_CCA_vect (n timer 0 compare or capture A)
// TCn1_CCA_vect (n timer 1 compare or capture A)
// TCn2_LCMPA_vect (n timer 2 low-byte compare or capture A)
// TCE0_CCA_vect (E timer 0 compare or capture A)
// TCn0_CCB_vect (n timer 0 compare or capture B)
// TCn1_CCB_vect (n timer 1 compare or capture B)
// TCn2_LCMPB_vect (n timer 2 low-byte compare or capture B)
// TCE0_CCB_vect (E timer 0 compare or capture B)
// TCn0_CCC_vect (n timer 0 compare or capture C)
// TCn2_LCMPC_vect (n timer 2 low-byte compare or capture C)
// TCE0_CCC_vect (E timer 0 compare or capture C)
// TCn0_CCD_vect (n timer 0 compare or capture D)
// TCn2_LCMPD_vect (n timer 2 low-byte compare or capture D)
// TCE0_CCD_vect (E timer 0 compare or capture D)
//
// SPIn_INT_vect (SPI C or D)
//
// USARTn0_RXC_vect (USART 'n' [C or D] receive complete)
// USARTn0_DRE_vect (USART 'n' [C or D] data reg empty)
// USARTn0_TXC_vect (USART 'n' [C or D] transmit complete)
//
// NOTE: a 'USARTE' interrupt vector also exists, but isn't
// implemented on the D4 series
//
// ASYNC interrupts are only possible on pin 2 for each of the 5
// ports ('R' only has 2 pins, 0 and 1, so no async interrupt).
// Sleep modes typically need ASYNC interrupts to wake up.
// The interrupt will be handled for a particular port, and not for
// a particular interrupt. The 'attachInterrupt' function will default
// to pin 2 (asynchronous interrupt) unless otherwise specified in the
// 'mode' parameter.
// BOOTLOADER NOTES
//
// Bit 6 of the CTRL reg must be assigned to '0'. Bit 7 can be assigned
// to '1' to enable 'round robin' scheduling using the priority bits.
// Bits 0-2 (HILVLEN, MEDLVLEN, LOLVLEN) should also be assigned to '1'
// to allow all 3 interrupt levels to execute. ('D' manual 10.8.3 pg 102)
// The CTRL reg can be assigned to b10000111 to accomplish this. Bit 6
// needs to use the "configuration change protection" method to change it
// and may need to be assigned separately.
// interrupt mode - predefined values are LOW, CHANGE, RISING, FALLING, HIGH
// additional bits are 'or'd with mode
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
static volatile uint8_t intPins[EXTERNAL_NUM_INTERRUPTS]; // added - store pins for this interrupt
// volatile static voidFuncPtr twiIntFunc;
// NOTE: I _HATE_ K&R style so I'll make it Allman style as I go along...
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
{
uint8_t iPinBits, iPriBits, iModeBits, iInv, iNum, iMask;
uint8_t oldSREG;
uint8_t intInfo;
PORT_t *port;
// for compatibility with newer IDE, 'interruptNum' can be encoded with pin information.
// if it is, then the pin info will be derived from pin info in 'mode' and 'interruptNum'
// pin info will be incorporated into it.
intInfo = ((interruptNum & 0xe0) >> 5); // is an int pin encoded here by digitalPinToInterrupt ?
interruptNum &= 0x1f; // so the rest of the code will work correctly
if(interruptNum >= EXTERNAL_NUM_INTERRUPTS)
{
return;
}
iPinBits = (uint8_t)((mode & INT_MODE_PIN_MASK) >> 8);
if(intInfo)
{
intInfo = ((intInfo + 2) & 7); // convert to actual pin number
iPinBits |= _BV(intInfo); // set respective bit in 'iPinBits'
}
if(!iPinBits)
{
if(interruptNum == PORTR_INT0
#ifdef PORTR_INT1
|| interruptNum == PORTR_INT1
#endif // PORTR_INT1
) // not valid for these
{
return; // do nothing (for now)
}
iPinBits = _BV(2); // set bit for pin 2 if none specified [i.e. 'default']
}
iPriBits = (mode & INT_MODE_PRI_MASK)
>> INT_MODE_PRI_SHIFT;
if(!iPriBits) // not assigned
{
iPriBits = 3; // for now, just use the highest priority
}
mode &= INT_MODE_MODE_MASK;
iInv = 0;
if(mode == LOW) // normally will be this, for backward hardware compatibility
{
iModeBits = PORT_ISC_LEVEL_gc; // b011, high level continuously generates events
}
else if(mode == HIGH) // these constants correspond to the mega's bit mask on ISC00,ISC10
{
iModeBits = PORT_ISC_LEVEL_gc; // b011, high level continuously generates events
iInv = 1; // invert input (so 'high level' becomes 'low level')
// NOTE: this was verified by experimentation. The documentation is misleading, suggesting
// that a LEVEL interrupt triggered on HIGH, not on LOW. But it triggers on LOW. So
// if you want HIGH, you must invert it. Not the other way around. Yeah.
}
else if(mode == CHANGE)
{
iModeBits = PORT_ISC_BOTHEDGES_gc; // BOTHEDGES - see table 11-6
}
else if(mode == RISING)
{
iModeBits = PORT_ISC_RISING_gc; // b001, RISING
}
else if(mode == FALLING)
{
iModeBits = PORT_ISC_FALLING_gc; // b010, FALLING
}
else
{
iModeBits = PORT_ISC_BOTHEDGES_gc; // BOTH (the default - note INTPUT_DISABLED (sic) won't buffer the input, so it's useless except for analog channels)
}
if(iInv)
{
iModeBits |= _BV(PORT_INVEN_bp); // set the 'inverted' bit
}
oldSREG = SREG; // store the interrupt flag basically
cli(); // disable interrupts for a bit
intFunc[interruptNum] = userFunc;
intPins[interruptNum] = iPinBits; // save what pins I used
// Enable the interrupt (smaller code to use if/else and pointer)
iNum = 0;
if(interruptNum == PORTA_INT0
#ifdef PORTA_INT1
|| interruptNum == PORTA_INT1
#endif // PORTA_INT1
)
{
port = &PORTA;
#ifdef PORTA_INT1
if(interruptNum == PORTA_INT1)
{
iNum = 1;
}
#endif // PORTA_INT1
}
#if NUM_ANALOG_PINS > 8 /* which means we have PORT B */
else if(interruptNum == PORTB_INT0
#ifdef PORTB_INT1
|| interruptNum == PORTB_INT1
#endif // PORTB_INT1
)
{
port = &PORTB;
#ifdef PORTB_INT1
if(interruptNum == PORTB_INT1)
{
iNum = 1;
}
#endif // PORTB_INT1
}
#endif // NUM_ANALOG_PINS > 8
else if(interruptNum == PORTC_INT0
#ifdef PORTC_INT1
|| interruptNum == PORTC_INT1
#endif // PORTC_INT1
)
{
port = &PORTC;
#ifdef PORTC_INT1
if(interruptNum == PORTC_INT1)
{
iNum = 1;
}
#endif // PORTC_INT1
}
else if(interruptNum == PORTD_INT0
#ifdef PORTD_INT1
|| interruptNum == PORTD_INT1
#endif // PORTD_INT1
)
{
port = &PORTD;
#ifdef PORTD_INT1
if(interruptNum == PORTD_INT1)
{
iNum = 1;
}
#endif // PORTC_INT1
}
#if NUM_DIGITAL_PINS > 18 /* which means we have PORT E */
else if(interruptNum == PORTE_INT0
#ifdef PORTE_INT1
|| interruptNum == PORTE_INT1
#endif // PORTE_INT1
)
{
port = &PORTE;
#ifdef PORTE_INT1
if(interruptNum == PORTE_INT1)
{
iNum = 1;
}
#endif // PORTE_INT1
}
#endif // NUM_DIGITAL_PINS > 18
else if(interruptNum == PORTR_INT0
#ifdef PORTR_INT1
|| interruptNum == PORTR_INT1
#endif // PORTR_INT1
)
{
port = &PORTR;
#ifdef PORTR_INT1
if(interruptNum == PORTR_INT1)
{
iNum = 1;
}
#endif // PORTR_INT1
}
else
{
return; // do nothing
}
// On certain processors there's only one interrupt, so it's called 'INTMASK'
// we test for this here
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
if(!iNum)
{
// set interrupt mask for PORT A, int 0 vector
port->INTMASK |= iPinBits; // enable int zero for these pins
port->INTCTRL = (port->INTCTRL & ~(PORT_INTLVL_gm))
| (iPriBits & 3);
}
#else // INT0MASK and INT1MASK supported
if(!iNum)
{
// set interrupt mask for PORT A, int 0 vector
port->INT0MASK |= iPinBits; // enable int zero for these pins
port->INTCTRL = (port->INTCTRL & ~(PORT_INT0LVL_gm))
| (iPriBits & 3);
}
else // if(iNum == 1)
{
port->INT1MASK |= iPinBits; // enable int zero for these pins
port->INTCTRL = (port->INTCTRL & ~(PORT_INT1LVL_gm))
| ((iPriBits & 3) << PORT_INT1LVL_gp);
}
#endif // INT0MASK and INT1MASK supported
for(iNum=0, iMask = 1; iNum < 8; iNum++, iMask <<= 1)
{
register8_t *pCTRL = &(port->PIN0CTRL) + iNum; // treat PIN0CTRL through PIN7CTRL as an array
// set corresponding 'type' in the interrupt control regs for the individual bits
if(iPinBits & iMask) // is this bit set in 'iPinBits'?
{
// enable the interrupt pin's mode bits and assign the 'invert' flag as needed
*pCTRL = (*pCTRL & ~(PORT_ISC_gm | PORT_INVEN_bm))
| iModeBits;
}
}
SREG = oldSREG; // restore it, interrupts (probably) re-enabled
// NOTE that this may throw an interrupt right away
}
void detachInterrupt(uint8_t interruptNum)
{
uint8_t iPinBits, iNum, iMask;
uint8_t oldSREG;
PORT_t *port;
// NOTE: this function will turn OFF the 'invert' bit if it's set for a HIGH level interrupt
// and digitalRead _SHOULD_ be consistent before/after this call.
if(interruptNum >= EXTERNAL_NUM_INTERRUPTS)
{
return;
}
oldSREG = SREG; // keep track of interrupt flag state
cli(); // clear the interrupt flag
// grab 'pin bits' so I know what to flip around
iPinBits = intPins[interruptNum]; // what I used when I added it
intFunc[interruptNum] = 0;
intPins[interruptNum] = 0; // zero both of these
// disable the interrupt
// Enable the interrupt (smaller code to use if/else and pointer)
iNum = 0;
if(interruptNum == PORTA_INT0
#ifdef PORTA_INT1
|| interruptNum == PORTA_INT1
#endif // PORTA_INT1
)
{
port = &PORTA;
#ifdef PORTA_INT1
if(interruptNum == PORTA_INT1)
{
iNum = 1;
}
#endif // PORTA_INT1
}
#if NUM_ANALOG_PINS > 8 /* which means we have PORT B */
else if(interruptNum == PORTB_INT0
#ifdef PORTB_INT1
|| interruptNum == PORTB_INT1
#endif // PORTB_INT1
)
{
port = &PORTB;
#ifdef PORTB_INT1
if(interruptNum == PORTB_INT1)
{
iNum = 1;
}
#endif // PORTB_INT1
}
#endif // NUM_ANALOG_PINS > 8
else if(interruptNum == PORTC_INT0
#ifdef PORTC_INT1
|| interruptNum == PORTC_INT1
#endif // PORTC_INT1
)
{
port = &PORTC;
#ifdef PORTC_INT1
if(interruptNum == PORTC_INT1)
{
iNum = 1;
}
#endif // PORTC_INT1
}
else if(interruptNum == PORTD_INT0
#ifdef PORTD_INT1
|| interruptNum == PORTD_INT1
#endif // PORTD_INT1
)
{
port = &PORTD;
#ifdef PORTD_INT1
if(interruptNum == PORTD_INT1)
{
iNum = 1;
}
#endif // PORTD_INT1
}
#if NUM_DIGITAL_PINS > 18 /* which means we have PORT E */
else if(interruptNum == PORTE_INT0
#ifdef PORTE_INT1
|| interruptNum == PORTE_INT1
#endif // PORTE_INT1
)
{
port = &PORTE;
#ifdef PORTE_INT1
if(interruptNum == PORTE_INT1)
{
iNum = 1;
}
#endif // PORTE_INT1
}
#endif // NUM_DIGITAL_PINS > 18
else if(interruptNum == PORTR_INT0
#ifdef PORTR_INT1
|| interruptNum == PORTR_INT1
#endif // PORTR_INT1
)
{
port = &PORTR;
#ifdef PORTR_INT1
if(interruptNum == PORTR_INT1)
{
iNum = 1;
}
#endif // PORTR_INT1
}
else
{
return; // do nothing
}
// On certain processors there's only one interrupt, so it's called 'INTMASK'
// we test for this here
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
if(!iNum)
{
// set interrupt mask for PORT A, int 0 vector
port->INTMASK = 0; // disable interrupts - TODO, read this instead of 'iPinBits' ?
port->INTCTRL &= ~(PORT_INTLVL_gm); // set interrupt control to 'OFF'
port->INTFLAGS = _BV(0); // clear the int flag
#else // INT0MASK and INT1MASK supported
if(!iNum)
{
// set interrupt mask for PORT A, int 0 vector
port->INT0MASK = 0; // disable interrupts - TODO, read this instead of 'iPinBits' ?
port->INTCTRL &= ~(PORT_INT0LVL_gm); // set interrupt control to 'OFF'
port->INTFLAGS = _BV(0); // clear the int 0 flag
}
else // if(iNum == 1)
{
#endif // INT0MASK and INT1MASK supported
// if this matches a CTS port, I do _NOT_ want to disable interrupts
#if defined(SERIAL_0_CTS_ENABLED) && defined(SERIAL_1_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == port)
{
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
if(SERIAL_1_CTS_PORT == port)
{
port->INTMASK = SERIAL_0_CTS_PIN | SERIAL_1_CTS_PIN; // disable interrupts but leave BOTH enabled
}
else
{
port->INTMASK = SERIAL_0_CTS_PIN; // disable interrupts but leave THIS one enabled
}
port->INTCTRL |= PORT_INTLVL_gm; // max priority when I do this
#else // INT0MASK and INT1MASK supported
if(SERIAL_1_CTS_PORT == port)
{
port->INT1MASK = SERIAL_0_CTS_PIN | SERIAL_1_CTS_PIN; // disable interrupts but leave BOTH enabled
}
else
{
port->INT1MASK = SERIAL_0_CTS_PIN; // disable interrupts but leave THIS one enabled
}
port->INTCTRL |= PORT_INT1LVL_gm; // max priority when I do this
#endif // INT0MASK and INT1MASK supported
}
else if(SERIAL_1_CTS_PORT == port)
{
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
port->INTMASK = SERIAL_1_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INTLVL_gm; // max priority when I do this
#else // INT0MASK and INT1MASK supported
port->INT1MASK = SERIAL_1_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INT1LVL_gm; // max priority when I do this
#endif // INT0MASK and INT1MASK supported
}
#elif defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == port)
{
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
port->INTMASK = SERIAL_0_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INTLVL_gm; // max priority when I do this
#else // INT0MASK and INT1MASK supported
port->INT1MASK = SERIAL_0_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INT1LVL_gm; // max priority when I do this
#endif // INT0MASK and INT1MASK supported
}
#elif defined(SERIAL_1_CTS_ENABLED)
if(SERIAL_1_CTS_PORT == port)
{
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
port->INTMASK = SERIAL_1_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INTLVL_gm; // max priority when I do this
#else // INT0MASK and INT1MASK supported
port->INT1MASK = SERIAL_1_CTS_PIN; // disable interrupts but leave THIS one enabled
port->INTCTRL |= PORT_INT1LVL_gm; // max priority when I do this
#endif // INT0MASK and INT1MASK supported
}
#endif // SERIAL_0/1_CTS_ENABLED
#if defined(SERIAL_0_CTS_ENABLED) || defined(SERIAL_1_CTS_ENABLED)
else
#endif // SERIAL_0/1_CTS_ENABLED
{
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
port->INTMASK = 0; // disable interrupts - TODO, read this instead of 'iPinBits' ?
port->INTCTRL &= ~(PORT_INTLVL_gm); // set interrupt control to 'OFF'
#else // INT0MASK and INT1MASK supported
port->INT1MASK = 0; // disable interrupts - TODO, read this instead of 'iPinBits' ?
port->INTCTRL &= ~(PORT_INT1LVL_gm); // set interrupt control to 'OFF'
#endif // INT0MASK and INT1MASK supported
}
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
port->INTFLAGS = _BV(0); // clear the int 0 flag
#else // INT0MASK and INT1MASK supported
port->INTFLAGS = _BV(1); // clear the int 1 flag
#endif // INT0MASK and INT1MASK supported
}
for(iNum=0, iMask = 1; iNum < 8; iNum++, iMask <<= 1)
{
register8_t *pCTRL = &(port->PIN0CTRL) + iNum; // treat PIN0CTRL through PIN7CTRL as an array
// set corresponding 'type' in the interrupt control regs for the individual bits
if(iPinBits & iMask) // is this bit set in 'iPinBits'?
{
*pCTRL &= ~(PORT_ISC_gm | PORT_INVEN_bm); // turn off invert flag and reset to 'BOTH' (the default)
}
}
SREG = oldSREG; // restore it, interrupts (probably) re-enabled
}
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
ISR(PORTA_INT_vect)
#else // INT0MASK and INT1MASK supported
ISR(PORTA_INT0_vect)
#endif // INT0MASK and INT1MASK supported
{
if(intFunc[PORTA_INT0])
intFunc[PORTA_INT0]();
#ifdef PORTC_INT0MASK // INT0MASK and INT1MASK supported
}
ISR(PORTA_INT1_vect)
{
if(intFunc[PORTA_INT1])
intFunc[PORTA_INT1]();
#endif // INT0MASK and INT1MASK supported
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTA)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTA))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}
#if NUM_ANALOG_PINS > 8 /* which means we have PORT B */
ISR(PORTB_INT0_vect)
{
if(intFunc[PORTB_INT0])
intFunc[PORTB_INT0]();
}
ISR(PORTB_INT1_vect)
{
if(intFunc[PORTB_INT1])
intFunc[PORTB_INT1]();
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTB)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTB))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}
#endif // NUM_ANALOG_PINS > 8
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
ISR(PORTC_INT_vect)
#else // INT0MASK and INT1MASK supported
ISR(PORTC_INT0_vect)
#endif // INT0MASK and INT1MASK supported
{
if(intFunc[PORTC_INT0])
intFunc[PORTC_INT0]();
#ifdef PORTC_INT0MASK // INT0MASK and INT1MASK supported
}
ISR(PORTC_INT1_vect)
{
if(intFunc[PORTC_INT1])
intFunc[PORTC_INT1]();
#endif // INT0MASK and INT1MASK supported
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTC)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTC))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
ISR(PORTD_INT_vect)
#else // INT0MASK and INT1MASK supported
ISR(PORTD_INT0_vect)
#endif // INT0MASK and INT1MASK supported
{
if(intFunc[PORTD_INT0])
intFunc[PORTD_INT0]();
#ifdef PORTC_INT0MASK // INT0MASK and INT1MASK supported
}
ISR(PORTD_INT1_vect)
{
if(intFunc[PORTD_INT1])
intFunc[PORTD_INT1]();
#endif // INT0MASK and INT1MASK supported
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTD)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTD))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}
#if NUM_DIGITAL_PINS > 18 /* which means we have PORT E */
ISR(PORTE_INT0_vect)
{
if(intFunc[PORTE_INT0])
intFunc[PORTE_INT0]();
}
ISR(PORTE_INT1_vect)
{
if(intFunc[PORTE_INT1])
intFunc[PORTE_INT1]();
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTE)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTE))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}
#endif // NUM_DIGITAL_PINS > 18
// TODO: ISRs for PORTF, PORTH, PORTJ, PORTK, PORTQ
#ifndef PORTC_INT0MASK /* meaning there's only one int vector and not two */
ISR(PORTR_INT_vect)
#else // INT0MASK and INT1MASK supported
ISR(PORTR_INT0_vect)
#endif // INT0MASK and INT1MASK supported
{
if(intFunc[PORTR_INT0])
intFunc[PORTR_INT0]();
#ifdef PORTC_INT0MASK // INT0MASK and INT1MASK supported
}
ISR(PORTR_INT1_vect)
{
if(intFunc[PORTR_INT1])
intFunc[PORTR_INT1]();
#endif // INT0MASK and INT1MASK supported
#if defined(SERIAL_0_CTS_ENABLED)
if(SERIAL_0_CTS_PORT == &(PORTR)) // this should compile as a constant expression
{
serial_0_cts_callback();
}
#endif // SERIAL_0_CTS_ENABLED
#ifdef SERIAL_1_CTS_ENABLED
if(SERIAL_1_CTS_PORT == &(PORTR))
{
serial_1_cts_callback();
}
#endif // SERIAL_1_CTS_ENABLED
}

View File

@@ -0,0 +1,60 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.org.co
Copyright (c) 2004-06 Hernando Barragan
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id$
*/
extern "C" {
#include "stdlib.h"
}
void randomSeed(unsigned int seed)
{
if (seed != 0) {
srandom(seed);
}
}
long random(long howbig)
{
if (howbig == 0) {
return 0;
}
return random() % howbig;
}
long random(long howsmall, long howbig)
{
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
return random(diff) + howsmall;
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
unsigned int makeWord(unsigned int w) { return w; }
unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }

View File

@@ -0,0 +1,744 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "WString.h"
/*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
String::String(const String &value)
{
init();
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
String::String(unsigned char value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base);
*this = buf;
}
String::String(int value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base);
*this = buf;
}
String::String(unsigned int value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base);
*this = buf;
}
String::String(long value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base);
*this = buf;
}
String::String(unsigned long value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base);
*this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::String(double value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::~String()
{
free(buffer);
}
/*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
void String::invalidate(void)
{
if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (PGM_P)pstr);
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void String::move(String &rhs)
{
if (buffer) {
if (capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}
String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{
return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, cstr);
len = newlen;
return 1;
}
unsigned char String::concat(const char *cstr)
{
if (!cstr) return 0;
return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return concat(buf, 1);
}
unsigned char String::concat(unsigned char num)
{
char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(float num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(double num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(const __FlashStringHelper * str)
{
if (!str) return 0;
int length = strlen_P((const char *) str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy_P(buffer + len, (const char *) str);
len = newlen;
return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}
char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}
/*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{
return indexOf(c, 0);
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) return -1;
const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
return temp - buffer;
}
int String::indexOf(const String &s2) const
{
return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
buffer[fromIndex + 1] = tempchar;
if (temp == NULL) return -1;
return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left > len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}
/*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
}
void String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
}
void String::remove(unsigned int index){
if (index >= len) { return; }
int count = len - index;
remove(index, count);
}
void String::remove(unsigned int index, unsigned int count){
if (index >= len) { return; }
if (count <= 0) { return; }
if (index + count > len) { count = len - index; }
char *writeTo = buffer + index;
len = len - count;
strncpy(writeTo, buffer + index + count,len - index);
buffer[len] = 0;
}
void String::toLowerCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
}
void String::toUpperCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
}
void String::trim(void)
{
if (!buffer || len == 0) return;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}
float String::toFloat(void) const
{
if (buffer) return float(atof(buffer));
return 0;
}

View File

@@ -0,0 +1,224 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String
{
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base=10);
explicit String(int, unsigned char base=10);
explicit String(unsigned int, unsigned char base=10);
explicit String(long, unsigned char base=10);
explicit String(unsigned long, unsigned char base=10);
explicit String(float, unsigned char decimalPlaces=2);
explicit String(double, unsigned char decimalPlaces=2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
String & operator += (const char *cstr) {concat(cstr); return (*this);}
String & operator += (char c) {concat(c); return (*this);}
String & operator += (unsigned char num) {concat(num); return (*this);}
String & operator += (int num) {concat(num); return (*this);}
String & operator += (unsigned int num) {concat(num); return (*this);}
String & operator += (long num) {concat(num); return (*this);}
String & operator += (unsigned long num) {concat(num); return (*this);}
String & operator += (float num) {concat(num); return (*this);}
String & operator += (double num) {concat(num); return (*this);}
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; }
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs);
#endif
};
class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num) : String(num) {}
StringSumHelper(double num) : String(num) {}
};
#endif // __cplusplus
#endif // String_class_h

View File

@@ -0,0 +1,267 @@
/* Copyright (c) 2002, 2004, 2010 Joerg Wunsch
Copyright (c) 2010 Gerben van den Broeke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: malloc.c 2149 2010-06-09 20:45:37Z joerg_wunsch $ */
#include <stdlib.h>
#include "sectionname.h"
#include "stdlib_private.h"
#include <avr/io.h>
/*
* Exported interface:
*
* When extending the data segment, the allocator will not try to go
* beyond the current stack limit, decreased by __malloc_margin bytes.
* Thus, all possible stack frames of interrupt routines that could
* interrupt the current function, plus all further nested function
* calls must not require more stack space, or they'll risk to collide
* with the data segment.
*/
/* May be changed by the user only before the first malloc() call. */
size_t __malloc_margin = 128;
char *__malloc_heap_start = &__heap_start;
char *__malloc_heap_end = &__heap_end;
char *__brkval;
struct __freelist *__flp;
ATTRIBUTE_CLIB_SECTION
void *
malloc(size_t len)
{
struct __freelist *fp1, *fp2, *sfp1=NULL, *sfp2=NULL; // BBB - added '=NULL' for sfp1, sfp2 as they were warned as being uninitialized
char *cp;
size_t s, avail;
/*
* Our minimum chunk size is the size of a pointer (plus the
* size of the "sz" field, but we don't need to account for
* this), otherwise we could not possibly fit a freelist entry
* into the chunk later.
*/
if (len < sizeof(struct __freelist) - sizeof(size_t))
len = sizeof(struct __freelist) - sizeof(size_t);
/*
* First, walk the free list and try finding a chunk that
* would match exactly. If we found one, we are done. While
* walking, note down the smallest chunk we found that would
* still fit the request -- we need it for step 2.
*
*/
for (s = 0, fp1 = __flp, fp2 = 0;
fp1;
fp2 = fp1, fp1 = fp1->nx) {
if (fp1->sz < len)
continue;
if (fp1->sz == len) {
/*
* Found it. Disconnect the chunk from the
* freelist, and return it.
*/
if (fp2)
fp2->nx = fp1->nx;
else
__flp = fp1->nx;
return &(fp1->nx);
}
else {
if (s == 0 || fp1->sz < s) {
/* this is the smallest chunk found so far */
s = fp1->sz;
sfp1 = fp1;
sfp2 = fp2;
}
}
}
/*
* Step 2: If we found a chunk on the freelist that would fit
* (but was too large), look it up again and use it, since it
* is our closest match now. Since the freelist entry needs
* to be split into two entries then, watch out that the
* difference between the requested size and the size of the
* chunk found is large enough for another freelist entry; if
* not, just enlarge the request size to what we have found,
* and use the entire chunk.
*/
if (s) {
if (s - len < sizeof(struct __freelist)) {
/* Disconnect it from freelist and return it. */
if (sfp2)
sfp2->nx = sfp1->nx;
else
__flp = sfp1->nx;
return &(sfp1->nx);
}
/*
* Split them up. Note that we leave the first part
* as the new (smaller) freelist entry, and return the
* upper portion to the caller. This saves us the
* work to fix up the freelist chain; we just need to
* fixup the size of the current entry, and note down
* the size of the new chunk before returning it to
* the caller.
*/
cp = (char *)sfp1;
s -= len;
cp += s;
sfp2 = (struct __freelist *)cp;
sfp2->sz = len;
sfp1->sz = s - sizeof(size_t);
return &(sfp2->nx);
}
/*
* Step 3: If the request could not be satisfied from a
* freelist entry, just prepare a new chunk. This means we
* need to obtain more memory first. The largest address just
* not allocated so far is remembered in the brkval variable.
* Under Unix, the "break value" was the end of the data
* segment as dynamically requested from the operating system.
* Since we don't have an operating system, just make sure
* that we don't collide with the stack.
*/
if (__brkval == 0)
__brkval = __malloc_heap_start;
cp = __malloc_heap_end;
if (cp == 0)
cp = STACK_POINTER() - __malloc_margin;
if (cp <= __brkval)
/*
* Memory exhausted.
*/
return 0;
avail = cp - __brkval;
/*
* Both tests below are needed to catch the case len >= 0xfffe.
*/
if (avail >= len && avail >= len + sizeof(size_t)) {
fp1 = (struct __freelist *)__brkval;
__brkval += len + sizeof(size_t);
fp1->sz = len;
return &(fp1->nx);
}
/*
* Step 4: There's no help, just fail. :-/
*/
return 0;
}
ATTRIBUTE_CLIB_SECTION
void
free(void *p)
{
struct __freelist *fp1, *fp2, *fpnew;
char *cp1, *cp2, *cpnew;
/* ISO C says free(NULL) must be a no-op */
if (p == 0)
return;
cpnew = p;
cpnew -= sizeof(size_t);
fpnew = (struct __freelist *)cpnew;
fpnew->nx = 0;
/*
* Trivial case first: if there's no freelist yet, our entry
* will be the only one on it. If this is the last entry, we
* can reduce __brkval instead.
*/
if (__flp == 0) {
if ((char *)p + fpnew->sz == __brkval)
__brkval = cpnew;
else
__flp = fpnew;
return;
}
/*
* Now, find the position where our new entry belongs onto the
* freelist. Try to aggregate the chunk with adjacent chunks
* if possible.
*/
for (fp1 = __flp, fp2 = 0;
fp1;
fp2 = fp1, fp1 = fp1->nx) {
if (fp1 < fpnew)
continue;
cp1 = (char *)fp1;
fpnew->nx = fp1;
if ((char *)&(fpnew->nx) + fpnew->sz == cp1) {
/* upper chunk adjacent, assimilate it */
fpnew->sz += fp1->sz + sizeof(size_t);
fpnew->nx = fp1->nx;
}
if (fp2 == 0) {
/* new head of freelist */
__flp = fpnew;
return;
}
break;
}
/*
* Note that we get here either if we hit the "break" above,
* or if we fell off the end of the loop. The latter means
* we've got a new topmost chunk. Either way, try aggregating
* with the lower chunk if possible.
*/
fp2->nx = fpnew;
cp2 = (char *)&(fp2->nx);
if (cp2 + fp2->sz == cpnew) {
/* lower junk adjacent, merge */
fp2->sz += fpnew->sz + sizeof(size_t);
fp2->nx = fpnew->nx;
}
/*
* If there's a new topmost chunk, lower __brkval instead.
*/
for (fp1 = __flp, fp2 = 0;
fp1->nx != 0;
fp2 = fp1, fp1 = fp1->nx)
/* advance to entry just before end of list */;
cp2 = (char *)&(fp1->nx);
if (cp2 + fp1->sz == __brkval) {
if (fp2 == NULL)
/* Freelist is empty now. */
__flp = NULL;
else
fp2->nx = NULL;
__brkval = cp2 - sizeof(size_t);
}
}

View File

@@ -0,0 +1,150 @@
/* Copyright (c) 2004, 2010 Joerg Wunsch
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: realloc.c 2127 2010-06-07 14:49:37Z joerg_wunsch $ */
#include <stdlib.h>
#include <string.h>
#include "sectionname.h"
#include "stdlib_private.h"
#include <avr/io.h>
ATTRIBUTE_CLIB_SECTION
void *
realloc(void *ptr, size_t len)
{
struct __freelist *fp1, *fp2, *fp3, *ofp3;
char *cp, *cp1;
void *memp;
size_t s, incr;
/* Trivial case, required by C standard. */
if (ptr == 0)
return malloc(len);
cp1 = (char *)ptr;
cp1 -= sizeof(size_t);
fp1 = (struct __freelist *)cp1;
cp = (char *)ptr + len; /* new next pointer */
if (cp < cp1)
/* Pointer wrapped across top of RAM, fail. */
return 0;
/*
* See whether we are growing or shrinking. When shrinking,
* we split off a chunk for the released portion, and call
* free() on it. Therefore, we can only shrink if the new
* size is at least sizeof(struct __freelist) smaller than the
* previous size.
*/
if (len <= fp1->sz) {
/* The first test catches a possible unsigned int
* rollover condition. */
if (fp1->sz <= sizeof(struct __freelist) ||
len > fp1->sz - sizeof(struct __freelist))
return ptr;
fp2 = (struct __freelist *)cp;
fp2->sz = fp1->sz - len - sizeof(size_t);
fp1->sz = len;
free(&(fp2->nx));
return ptr;
}
/*
* If we get here, we are growing. First, see whether there
* is space in the free list on top of our current chunk.
*/
incr = len - fp1->sz;
cp = (char *)ptr + fp1->sz;
fp2 = (struct __freelist *)cp;
for (s = 0, ofp3 = 0, fp3 = __flp;
fp3;
ofp3 = fp3, fp3 = fp3->nx) {
if (fp3 == fp2 && fp3->sz + sizeof(size_t) >= incr) {
/* found something that fits */
if (fp3->sz + sizeof(size_t) - incr > sizeof(struct __freelist)) {
/* split off a new freelist entry */
cp = (char *)ptr + len;
fp2 = (struct __freelist *)cp;
fp2->nx = fp3->nx;
fp2->sz = fp3->sz - incr;
fp1->sz = len;
} else {
/* it just fits, so use it entirely */
fp1->sz += fp3->sz + sizeof(size_t);
fp2 = fp3->nx;
}
if (ofp3)
ofp3->nx = fp2;
else
__flp = fp2;
return ptr;
}
/*
* Find the largest chunk on the freelist while
* walking it.
*/
if (fp3->sz > s)
s = fp3->sz;
}
/*
* If we are the topmost chunk in memory, and there was no
* large enough chunk on the freelist that could be re-used
* (by a call to malloc() below), quickly extend the
* allocation area if possible, without need to copy the old
* data.
*/
if (__brkval == (char *)ptr + fp1->sz && len > s) {
cp1 = __malloc_heap_end;
cp = (char *)ptr + len;
if (cp1 == 0)
cp1 = STACK_POINTER() - __malloc_margin;
if (cp < cp1) {
__brkval = cp;
fp1->sz = len;
return ptr;
}
/* If that failed, we are out of luck. */
return 0;
}
/*
* Call malloc() for a new chunk, then copy over the data, and
* release the old region.
*/
if ((memp = malloc(len)) == 0)
return 0;
memcpy(memp, ptr, fp1->sz);
free(ptr);
return memp;
}

View File

@@ -0,0 +1,49 @@
/* Copyright (c) 2009 Atmel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SECTIONNAME_H__
#define __SECTIONNAME_H__
/* Put all avr-libc functions in a common, unique sub-section name under .text. */
#define CLIB_SECTION .text.avr-libc
#define MLIB_SECTION .text.avr-libc.fplib
#define STR(x) _STR(x)
#define _STR(x) #x
#define ATTRIBUTE_CLIB_SECTION __attribute__ ((section (STR(CLIB_SECTION))))
#define ATTRIBUTE_MLIB_SECTION __attribute__ ((section (STR(MLIB_SECTION))))
#define ASSEMBLY_CLIB_SECTION .section CLIB_SECTION, "ax", @progbits
#define ASSEMBLY_MLIB_SECTION .section MLIB_SECTION, "ax", @progbits
#endif

View File

@@ -0,0 +1,58 @@
/* Copyright (c) 2004, Joerg Wunsch
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: stdlib_private.h 1657 2008-03-24 17:11:08Z arcanum $ */
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#if !defined(__DOXYGEN__)
struct __freelist {
size_t sz;
struct __freelist *nx;
};
#endif
extern char *__brkval; /* first location not yet allocated */
extern struct __freelist *__flp; /* freelist pointer (head of freelist) */
extern size_t __malloc_margin; /* user-changeable before the first malloc() */
extern char *__malloc_heap_start;
extern char *__malloc_heap_end;
extern char __heap_start;
extern char __heap_end;
/* Needed for definition of AVR_STACK_POINTER_REG. */
#include <avr/io.h>
#define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG)

View File

@@ -0,0 +1,534 @@
/*
binary.h - Definitions for binary constants
Copyright (c) 2006 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Binary_h
#define Binary_h
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
#define B11 3
#define B011 3
#define B0011 3
#define B00011 3
#define B000011 3
#define B0000011 3
#define B00000011 3
#define B100 4
#define B0100 4
#define B00100 4
#define B000100 4
#define B0000100 4
#define B00000100 4
#define B101 5
#define B0101 5
#define B00101 5
#define B000101 5
#define B0000101 5
#define B00000101 5
#define B110 6
#define B0110 6
#define B00110 6
#define B000110 6
#define B0000110 6
#define B00000110 6
#define B111 7
#define B0111 7
#define B00111 7
#define B000111 7
#define B0000111 7
#define B00000111 7
#define B1000 8
#define B01000 8
#define B001000 8
#define B0001000 8
#define B00001000 8
#define B1001 9
#define B01001 9
#define B001001 9
#define B0001001 9
#define B00001001 9
#define B1010 10
#define B01010 10
#define B001010 10
#define B0001010 10
#define B00001010 10
#define B1011 11
#define B01011 11
#define B001011 11
#define B0001011 11
#define B00001011 11
#define B1100 12
#define B01100 12
#define B001100 12
#define B0001100 12
#define B00001100 12
#define B1101 13
#define B01101 13
#define B001101 13
#define B0001101 13
#define B00001101 13
#define B1110 14
#define B01110 14
#define B001110 14
#define B0001110 14
#define B00001110 14
#define B1111 15
#define B01111 15
#define B001111 15
#define B0001111 15
#define B00001111 15
#define B10000 16
#define B010000 16
#define B0010000 16
#define B00010000 16
#define B10001 17
#define B010001 17
#define B0010001 17
#define B00010001 17
#define B10010 18
#define B010010 18
#define B0010010 18
#define B00010010 18
#define B10011 19
#define B010011 19
#define B0010011 19
#define B00010011 19
#define B10100 20
#define B010100 20
#define B0010100 20
#define B00010100 20
#define B10101 21
#define B010101 21
#define B0010101 21
#define B00010101 21
#define B10110 22
#define B010110 22
#define B0010110 22
#define B00010110 22
#define B10111 23
#define B010111 23
#define B0010111 23
#define B00010111 23
#define B11000 24
#define B011000 24
#define B0011000 24
#define B00011000 24
#define B11001 25
#define B011001 25
#define B0011001 25
#define B00011001 25
#define B11010 26
#define B011010 26
#define B0011010 26
#define B00011010 26
#define B11011 27
#define B011011 27
#define B0011011 27
#define B00011011 27
#define B11100 28
#define B011100 28
#define B0011100 28
#define B00011100 28
#define B11101 29
#define B011101 29
#define B0011101 29
#define B00011101 29
#define B11110 30
#define B011110 30
#define B0011110 30
#define B00011110 30
#define B11111 31
#define B011111 31
#define B0011111 31
#define B00011111 31
#define B100000 32
#define B0100000 32
#define B00100000 32
#define B100001 33
#define B0100001 33
#define B00100001 33
#define B100010 34
#define B0100010 34
#define B00100010 34
#define B100011 35
#define B0100011 35
#define B00100011 35
#define B100100 36
#define B0100100 36
#define B00100100 36
#define B100101 37
#define B0100101 37
#define B00100101 37
#define B100110 38
#define B0100110 38
#define B00100110 38
#define B100111 39
#define B0100111 39
#define B00100111 39
#define B101000 40
#define B0101000 40
#define B00101000 40
#define B101001 41
#define B0101001 41
#define B00101001 41
#define B101010 42
#define B0101010 42
#define B00101010 42
#define B101011 43
#define B0101011 43
#define B00101011 43
#define B101100 44
#define B0101100 44
#define B00101100 44
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51
#define B00110011 51
#define B110100 52
#define B0110100 52
#define B00110100 52
#define B110101 53
#define B0110101 53
#define B00110101 53
#define B110110 54
#define B0110110 54
#define B00110110 54
#define B110111 55
#define B0110111 55
#define B00110111 55
#define B111000 56
#define B0111000 56
#define B00111000 56
#define B111001 57
#define B0111001 57
#define B00111001 57
#define B111010 58
#define B0111010 58
#define B00111010 58
#define B111011 59
#define B0111011 59
#define B00111011 59
#define B111100 60
#define B0111100 60
#define B00111100 60
#define B111101 61
#define B0111101 61
#define B00111101 61
#define B111110 62
#define B0111110 62
#define B00111110 62
#define B111111 63
#define B0111111 63
#define B00111111 63
#define B1000000 64
#define B01000000 64
#define B1000001 65
#define B01000001 65
#define B1000010 66
#define B01000010 66
#define B1000011 67
#define B01000011 67
#define B1000100 68
#define B01000100 68
#define B1000101 69
#define B01000101 69
#define B1000110 70
#define B01000110 70
#define B1000111 71
#define B01000111 71
#define B1001000 72
#define B01001000 72
#define B1001001 73
#define B01001001 73
#define B1001010 74
#define B01001010 74
#define B1001011 75
#define B01001011 75
#define B1001100 76
#define B01001100 76
#define B1001101 77
#define B01001101 77
#define B1001110 78
#define B01001110 78
#define B1001111 79
#define B01001111 79
#define B1010000 80
#define B01010000 80
#define B1010001 81
#define B01010001 81
#define B1010010 82
#define B01010010 82
#define B1010011 83
#define B01010011 83
#define B1010100 84
#define B01010100 84
#define B1010101 85
#define B01010101 85
#define B1010110 86
#define B01010110 86
#define B1010111 87
#define B01010111 87
#define B1011000 88
#define B01011000 88
#define B1011001 89
#define B01011001 89
#define B1011010 90
#define B01011010 90
#define B1011011 91
#define B01011011 91
#define B1011100 92
#define B01011100 92
#define B1011101 93
#define B01011101 93
#define B1011110 94
#define B01011110 94
#define B1011111 95
#define B01011111 95
#define B1100000 96
#define B01100000 96
#define B1100001 97
#define B01100001 97
#define B1100010 98
#define B01100010 98
#define B1100011 99
#define B01100011 99
#define B1100100 100
#define B01100100 100
#define B1100101 101
#define B01100101 101
#define B1100110 102
#define B01100110 102
#define B1100111 103
#define B01100111 103
#define B1101000 104
#define B01101000 104
#define B1101001 105
#define B01101001 105
#define B1101010 106
#define B01101010 106
#define B1101011 107
#define B01101011 107
#define B1101100 108
#define B01101100 108
#define B1101101 109
#define B01101101 109
#define B1101110 110
#define B01101110 110
#define B1101111 111
#define B01101111 111
#define B1110000 112
#define B01110000 112
#define B1110001 113
#define B01110001 113
#define B1110010 114
#define B01110010 114
#define B1110011 115
#define B01110011 115
#define B1110100 116
#define B01110100 116
#define B1110101 117
#define B01110101 117
#define B1110110 118
#define B01110110 118
#define B1110111 119
#define B01110111 119
#define B1111000 120
#define B01111000 120
#define B1111001 121
#define B01111001 121
#define B1111010 122
#define B01111010 122
#define B1111011 123
#define B01111011 123
#define B1111100 124
#define B01111100 124
#define B1111101 125
#define B01111101 125
#define B1111110 126
#define B01111110 126
#define B1111111 127
#define B01111111 127
#define B10000000 128
#define B10000001 129
#define B10000010 130
#define B10000011 131
#define B10000100 132
#define B10000101 133
#define B10000110 134
#define B10000111 135
#define B10001000 136
#define B10001001 137
#define B10001010 138
#define B10001011 139
#define B10001100 140
#define B10001101 141
#define B10001110 142
#define B10001111 143
#define B10010000 144
#define B10010001 145
#define B10010010 146
#define B10010011 147
#define B10010100 148
#define B10010101 149
#define B10010110 150
#define B10010111 151
#define B10011000 152
#define B10011001 153
#define B10011010 154
#define B10011011 155
#define B10011100 156
#define B10011101 157
#define B10011110 158
#define B10011111 159
#define B10100000 160
#define B10100001 161
#define B10100010 162
#define B10100011 163
#define B10100100 164
#define B10100101 165
#define B10100110 166
#define B10100111 167
#define B10101000 168
#define B10101001 169
#define B10101010 170
#define B10101011 171
#define B10101100 172
#define B10101101 173
#define B10101110 174
#define B10101111 175
#define B10110000 176
#define B10110001 177
#define B10110010 178
#define B10110011 179
#define B10110100 180
#define B10110101 181
#define B10110110 182
#define B10110111 183
#define B10111000 184
#define B10111001 185
#define B10111010 186
#define B10111011 187
#define B10111100 188
#define B10111101 189
#define B10111110 190
#define B10111111 191
#define B11000000 192
#define B11000001 193
#define B11000010 194
#define B11000011 195
#define B11000100 196
#define B11000101 197
#define B11000110 198
#define B11000111 199
#define B11001000 200
#define B11001001 201
#define B11001010 202
#define B11001011 203
#define B11001100 204
#define B11001101 205
#define B11001110 206
#define B11001111 207
#define B11010000 208
#define B11010001 209
#define B11010010 210
#define B11010011 211
#define B11010100 212
#define B11010101 213
#define B11010110 214
#define B11010111 215
#define B11011000 216
#define B11011001 217
#define B11011010 218
#define B11011011 219
#define B11011100 220
#define B11011101 221
#define B11011110 222
#define B11011111 223
#define B11100000 224
#define B11100001 225
#define B11100010 226
#define B11100011 227
#define B11100100 228
#define B11100101 229
#define B11100110 230
#define B11100111 231
#define B11101000 232
#define B11101001 233
#define B11101010 234
#define B11101011 235
#define B11101100 236
#define B11101101 237
#define B11101110 238
#define B11101111 239
#define B11110000 240
#define B11110001 241
#define B11110010 242
#define B11110011 243
#define B11110100 244
#define B11110101 245
#define B11110110 246
#define B11110111 247
#define B11111000 248
#define B11111001 249
#define B11111010 250
#define B11111011 251
#define B11111100 252
#define B11111101 253
#define B11111110 254
#define B11111111 255
#endif

View File

@@ -0,0 +1,68 @@
/*
main.cpp - Main loop for Arduino sketches
Copyright (c) 2005-2013 Arduino Team. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#include <Arduino.h> Platform.h includes Arduino.h
#include <Platform.h> /* to make sure that Arduino.h is included, as well as pins_arduino.h and other things */
#ifdef EIND
// if I have an EIND register, I want it pre-loaded with the correct value
// for info on THIS thing, see http://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
// in essence, 'init3' section functions run just before 'main()'
// must prototype it to get all of the attributes
static void __attribute__((section(".init3"),naked,used,no_instrument_function)) init3_set_eind (void);
void init3_set_eind (void)
{
__asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t"
"out %i0,r24" :: "n" (&EIND) : "r24","memory");
}
#endif // EIND
//Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (*func)()) { return 0; }
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
int main(void)
{
init();
initVariant();
// TEMPORARY - moved [so I can debug it]
//#if defined(USBCON)
// USBDevice.attach();
//#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}

View File

@@ -0,0 +1,28 @@
#include <new.h>
void * operator new(size_t size)
{
return malloc(size);
}
void * operator new[](size_t size)
{
return malloc(size);
}
void operator delete(void * ptr)
{
free(ptr);
}
void operator delete[](void * ptr)
{
free(ptr);
}
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};
void __cxa_pure_virtual(void) {};

View File

@@ -0,0 +1,24 @@
/* Header to define new/delete operators as they aren't provided by avr-gcc by default
Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
*/
#ifndef NEW_H
#define NEW_H
#include <stdlib.h>
void * operator new(size_t size);
void * operator new[](size_t size);
void operator delete(void * ptr);
void operator delete[](void * ptr);
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
extern "C" void __cxa_pure_virtual(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,859 @@
/*
wiring_analog.c - analog input and output
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Modified 28 September 2010 by Mark Sproul
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
In some cases, the xmega updates make assumptions about the pin assignments.
See 'pins_arduino.h' for more detail.
*/
#include "wiring_private.h"
#include "pins_arduino.h"
//#define DEBUG_CODE
#ifdef DEBUG_CODE
extern void DebugOutL(unsigned long lVal);
extern void DebugOutP(const void * PROGMEM pStr);
#endif // DEBUG_CODE
#ifndef ADCA_SAMPCTRL
#define ADCA_SAMPCTRL _SFR_MEM8(0x0208) /* missing from header for some reason, struct defines it as reserved_0x08 */
#endif // ADCA_SAMPCTRL
uint8_t analog_reference, muxctrl_muxneg; // = ADC_REFSEL2_bp;// the default analog reference is Vcc / 2 (now assigned in adc_setup)
// NOTE: On the A-series processors with more than a handful of inputs,
// it is NOT possible to use 'diff input with gain' on MORE than
// A0-A7. On later processors (like D series) it _IS_ possible.
// Because of this, the 'hack' that allows rail-rail measurements
// is no longer possible on PB0-PB7. PA0-PA7 will still work.
// IF PA0 or PB0 is used as VRef (see 28.16.3 in AU manual) via 'REFCTRL'
// then you can read all 15 remaining values with whatever VRef you want.
// adc_setup() - call this from init() and whenever you wake up from sleep mode
void adc_setup(void)
{
// calibration is a 16-bit register - CAL0 + (CAL1 << 8)
ADCA_CAL = (uint16_t)readCalibrationData((uint8_t)(uint16_t)&PRODSIGNATURES_ADCACAL0)
| (((uint16_t)readCalibrationData((uint8_t)(uint16_t)&PRODSIGNATURES_ADCACAL1)) << 8);
// must make sure power reduction register enables the ADC
PR_PRPA &= ~PR_ADC_bm; // clear this bit to enable the ADC clock
// assign clock prescaler for 100khz, and clear the interrupt bit
// also make sure the 'interrupt enable' is OFF
ADCA_EVCTRL = 0; // no triggering events (sect 22.14.4)
ADCA_PRESCALER = ADC_PRESCALER_DIV256_gc; // 100khz, approximately, for 32Mhz clock
ADCA_CTRLA = _BV(ADC_ENABLE_bp); // enables the ADC
ADCA_CTRLB = _BV(6) | _BV(4); // medium current limit, signed mode [temporary]
// _BV(6) | _BV(5); // section 22.14.2, 'HIGH' current limit, no apparent bit value constants in iox64d4.h
// NOTE: all other bits are zero - no 'freerun', 12-bit right-justified unsigned mode
analog_reference = 1; // which is NONE of the possibilities
ADCA_REFCTRL = 0; // pre-assign zero to this, as I'll OR bits into it
#ifdef USE_AREF
analogReference(USE_AREF);
#else // everything else - NOTE: do I want to do this different for 'A' series?
analogReference(analogReference_VCCDIV2);
#endif // USE_AREF
// TODO: is this actually a RESERVED functionality?
ADCA_SAMPCTRL = 24; // sect 22.14.8 - this value + 1 is # of "half cycles" used for sampling
// in this case, it's 25 "half cycles" at 100khz, or appx 8khz (125uS)
// adjust this for 'best accuracy' without taking for-freaking-evar
// also make sure the sample rate is lower than the 'HIGH LIMIT' max rate (see 22.14.2)
// set up the channel (no offset calc at this time - later do an offset calc)
ADCA_CH0_SCAN = 0; // disable scan
ADCA_CH0_INTCTRL = 0; // no interrupts, flag on complete sect 22.15.3
// clear interrupt flag (probably not needed)
ADCA_INTFLAGS = _BV(ADC_CH0IF_bp); // write a 1 to the interrupt bit (which clears it - 22.14.6)
analogRead(0); // do a single conversion so that everything stabilizes
// these are taken care of at the beginning of the function, as a 16-bit register assignment to ADCA_CAL
// ADCA.CALL = readCalibrationData(&PRODSIGNATURES_ADCACAL0);
// ADCA.CALH = readCalibrationData(&PRODSIGNATURES_ADCACAL1);
}
// see _analogReference_ enum
static uint8_t normal_adca_ch0_ctrl_bits(void) // also assigns 'muxctrl_muxneg'
{
#if defined (__AVR_ATxmega8E5__) || defined (__AVR_ATxmega16E5__) || defined (__AVR_ATxmega32E5__)
// NOTE: the E5 has a significant difference in how it handles 'DIFF WITH GAIN'
// ADC_CH_INPUTMODE_DIFFWGAINL_gc uses A0-A3, GND, and internal GND (not same as D and earlier)
// ADC_CH_INPUTMODE_DIFFWGAINH_gc uses A4-A7 and GND (see E manual table 24-16,17 pg 366-7) (similar to D and earlier)
if(analog_reference == analogReference_VCCDIV2)
{
return ADC_CH_INPUTMODE_DIFFWGAINH_gc | ADC_CH_GAIN_DIV2_gc; // gain of 1/2 for VCC/2
}
else
{
return ADC_CH_INPUTMODE_DIFFWGAINH_gc | ADC_CH_GAIN_1X_gc;
}
#else // everything NOT an 'E' series
if(analog_reference == analogReference_VCCDIV2)
{
// NOTE: On the A-series processors with more than a handful of inputs,
// it is NOT possible to use 'diff input with gain' on MORE than
// A0-A7. On later processors (like D series) it _IS_ possible.
// Because of this, the 'hack' that allows rail-rail measurements
// is no longer possible on PB0-PB7. PA0-PA7 will still work.
// IF PA0 or PB0 is used as VRef (see 28.16.3 in AU manual) via 'REFCTRL'
// then you can read all 15 remaining values with whatever VRef you want.
return ADC_CH_INPUTMODE_DIFFWGAIN_gc | ADC_CH_GAIN_DIV2_gc; // gain of 1/2 for VCC/2
}
else
{
// NOTE: this one uses a different 'muxneg' (see below, 'analogReference()')
return ADC_CH_INPUTMODE_DIFF_gc | ADC_CH_GAIN_1X_gc;
}
#endif // E series or not
}
void analogReference(uint8_t bMode)
{
if((bMode & ADC_REFSEL_gm) != bMode)
{
bMode &= ADC_REFSEL_gm;
}
if(bMode != analog_reference)
{
analog_reference = bMode;
// changes to this must be reflected in ADCA_REFCTRL and ADCA_CH0_MUXCTRL
// when I read a specific pin. I assign the 'muxneg' bits according muxctrl_muxneg
ADCA_REFCTRL = (ADCA_REFCTRL & ~(ADC_REFSEL_gm))
| analog_reference // section 22.14.3, or 28.16.3 in 'AU' manual
| ADC_BANDGAP_bm; // enable 'bandgap' i.e. 1V reference
// NOTE: all other ADCA_REFCTRL bits are zero (like tempref) - section 22.14.3
// ASSIGNING ADCA_CH0_CTRL and muxctrl_muxneg
ADCA_CH0_CTRL = normal_adca_ch0_ctrl_bits();
// assign 'muxneg' according to what teh analog reference is
#if defined (__AVR_ATxmega8E5__) || (__AVR_ATxmega16E5__) || defined (__AVR_ATxmega32E5__)
muxctrl_muxneg = 7; /* bits 111 which is GND for MUXNEG - see E manual 24.15.2 */
#else // everything NOT an 'E' series
if(analog_reference == analogReference_VCCDIV2)
{
// analog delta WITH GAIN always uses this
muxctrl_muxneg = 7; /* bits 111 which is GND for MUXNEG - see D manual 22.15.2, A manual 28.17.2 */
}
else
{
// analog delta WITHOUT GAIN uses THIS
muxctrl_muxneg = 5; /* bits 101 which is GND for MUXNEG - see D manual 22.15.2, A manual 28.17.2 */
}
#endif // E series or not
}
}
// For 100% atmega compatibility, analogRead will return a value of 0-1023
// for input voltages of 0 to Vcc (assuming AVCC is connected to VCC, etc.)
// by using a gain of 1/2, a comparison of Vcc/2, and signed conversion
int analogRead(uint8_t pin)
{
short iRval;
// this is pure XMEGA code
if(pin >= A0)
{
if(pin >= (NUM_ANALOG_INPUTS + A0)) // pin number too high?
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
pin = analogInputToAnalogPin(pin);
#else // analogInputToAnalogPin
pin -= A0; // this works when PA0-PA7 and PB0-PBn are in sequence for A0-An
#endif // analogInputToAnalogPin
}
else
{
// NOTE: for pins less than 'A0', assume it's referring to the analog index (0 to NUM_ANALOG_INPUTS-1)
if(pin >= NUM_ANALOG_INPUTS)
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
pin = analogInputToAnalogPin(pin + A0); // calc pin number (might not have 0 mapped to A0)
#endif // analogInputToAnalogPin
}
// ANALOG REFERENCE - in some cases I can map one of the analog inputs
// as an analog reference. For now, assume it's Vcc/2.
// NOTE: On the A-series processors with more than a handful of inputs,
// it is NOT possible to use 'diff input with gain' on MORE than
// A0-A7. On later processors (like D series) it _IS_ possible.
// Because of this, the 'hack' that allows rail-rail measurements
// is no longer possible on PB0-PB7. PA0-PA7 will still work.
// IF PA0 or PB0 is used as VRef (see 28.16.3 in AU manual) via 'REFCTRL'
// then you can read all 15 remaining values with whatever VRef you want.
ADCA_CH0_SCAN = 0; // disable scan
ADCA_CH0_MUXCTRL = (pin << ADC_CH_MUXPOS_gp) // sect 22.15.2 in 'D' manual, 28.17.2 in 'A' manual, 24.15.2 in 'E' manual
| muxctrl_muxneg; // typically, GND is the 'other input' (change via 'analogReference()')
ADCA_CH0_INTCTRL = 0; // no interrupts, flag on complete sect 22.15.3
#ifdef ADC_CH_IF_bm /* iox16e5.h and iox32e5.h - probably the ATMel Studio version */
ADCA_CH0_INTFLAGS = ADC_CH_IF_bm; // write a 1 to the interrupt bit (which clears it - 22.15.4)
#else // everyone else
ADCA_CH0_INTFLAGS = ADC_CH_CHIF_bm; // write a 1 to the interrupt bit (which clears it - 22.15.4)
#endif // ADC_CH_IF_bm
// NOTE: this will clear any re-assigned gain bits, etc.
// (if you want to preserve those, need to call 'analogReadDeltaWithGain()')
ADCA_CH0_CTRL = normal_adca_ch0_ctrl_bits()
| ADC_CH_START_bm; // conversion start (bit will clear itself I think)
#ifdef ADC_CH_IF_bm /* iox16e5.h and iox32e5.h - probably the ATMel Studio version */
while(!(ADCA_CH0_INTFLAGS & ADC_CH_IF_bm)) { }
#else // everyone else
while(!(ADCA_CH0_INTFLAGS & ADC_CH_CHIF_bm)) { }
#endif // ADC_CH_IF_bm
iRval = ADCA_CH0_RES;
if(iRval < 0) // backward compatibility
{
return 0;
}
return iRval / 2; // -1023 to 1023 but clipped at zero (so 0 to 1023 only)
}
// THIS function returns a full 12-bit signed integer value (no scaling)
int analogReadDeltaWithGain(uint8_t pin, uint8_t negpin, uint8_t gain)
{
short iRval;
uint8_t mode;
// this is pure XMEGA code
// NOTE: On the A-series processors with more than a handful of inputs,
// it is NOT possible to use 'diff input with gain' on MORE than
// A0-A7. On later processors (like D series) it _IS_ possible.
// TODO: check for A0-A7 for 'pin' for A series?
if(pin >= A0)
{
if(pin >= (NUM_ANALOG_INPUTS + A0)) // pin number too high?
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
pin = analogInputToAnalogPin(pin);
#else // analogInputToAnalogPin
pin -= A0; // this works when PA0-PA7 and PB0-PBn are in sequence for A0-An
#endif // analogInputToAnalogPin
}
else
{
// NOTE: for pins less than 'A0', assume it's referring to the analog index (0 to NUM_ANALOG_INPUTS-1)
if(pin >= NUM_ANALOG_INPUTS)
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
pin = analogInputToAnalogPin(pin + A0); // calc pin number (might not have 0 mapped to A0)
#endif // analogInputToAnalogPin
}
#if defined (__AVR_ATxmega8E5__) || defined (__AVR_ATxmega16E5__) || defined (__AVR_ATxmega32E5__)
// NOTE: the E5 has a significant difference in how it handles 'DIFF WITH GAIN'
// ADC_CH_INPUTMODE_DIFFWGAINL_gc uses A0-A3, GND, and internal GND (not same as D and earlier)
// ADC_CH_INPUTMODE_DIFFWGAINH_gc uses A4-A7 and GND (see E manual table 24-16,17 pg 366-7) (similar to D and earlier)
if(negpin != ANALOG_READ_DELTA_USE_GND)
{
if(negpin >= A0)
{
#ifdef analogInputToAnalogPin
negpin = analogInputToAnalogPin(negpin);
#else // analogInputToAnalogPin
negpin -= A0; // this works when PA0-PA7 and PB0-PBn are in sequence for A0-An
#endif // analogInputToAnalogPin
}
else
{
if(negpin >= NUM_ANALOG_INPUTS)
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
negpin = analogInputToAnalogPin(negpin + A0); // calc pin number (might not have 0 mapped to A0)
#endif // analogInputToAnalogPin
}
if(negpin >= 0 && negpin <= 3)
{
mode = ADC_CH_INPUTMODE_DIFFWGAINL_gc;
}
else if(negpin > 7)
{
return 0; // dis-allowed combination
}
else
{
mode = ADC_CH_INPUTMODE_DIFFWGAINH_gc;
negpin -= 4; // so that it's 0-3
}
}
else
{
mode = ADC_CH_INPUTMODE_DIFFWGAINL_gc; // see 24.15.2 section on 'MUXNEG' when using INTERNAL GND or PAD GND
}
#else // NOT an 'E5'
mode = ADC_CH_INPUTMODE_DIFFWGAIN_gc;
// now for the negative pin, which will depend on a number of things
if(negpin != ANALOG_READ_DELTA_USE_GND)
{
if(negpin >= A0)
{
#ifdef analogInputToAnalogPin
negpin = analogInputToAnalogPin(negpin);
#else // analogInputToAnalogPin
negpin -= A0; // this works when PA0-PA7 and PB0-PBn are in sequence for A0-An
#endif // analogInputToAnalogPin
}
else
{
if(negpin >= NUM_ANALOG_INPUTS)
{
return 0; // not a valid analog input
}
#ifdef analogInputToAnalogPin
negpin = analogInputToAnalogPin(negpin + A0); // calc pin number (might not have 0 mapped to A0)
#endif // analogInputToAnalogPin
}
if(negpin >= 0 && negpin <= 3 && gain != ADC_CH_GAIN_1X_gc) // allow this *IF* gain is 1X
{
return 0; // dis-allowed combination
}
else if(negpin >= 0 && negpin <= 3)
{
mode = ADC_CH_INPUTMODE_DIFF_gc; // just 'diff' mode, with 1X gain, for A0 to A3
}
else if(negpin > 7)
{
return 0; // dis-allowed combination
}
else
{
negpin -= 4; // so that it's 0-3
}
}
#endif // 'E' series, or not
ADCA_CH0_SCAN = 0; // disable scan
// NOTE: assume 'CONVMODE' (CTRLB) is set to 'Signed'
if(negpin == ANALOG_READ_DELTA_USE_GND)
{
#if defined (__AVR_ATxmega8E5__) || (__AVR_ATxmega16E5__) || defined (__AVR_ATxmega32E5__)
ADCA_CH0_MUXCTRL = (pin << ADC_CH_MUXPOS_gp) // sect 22.15.2 in 'D' manual, 28.17.2 in 'A' manual, 24.15.2 in 'E' manual
| 7; /* bits 111 which is GND for MUXNEG - see E manual 24.15.2 */
#else // everything NOT an 'E' series
if(mode == ADC_CH_INPUTMODE_DIFFWGAIN_gc)
{
ADCA_CH0_MUXCTRL = (pin << ADC_CH_MUXPOS_gp) // sect 22.15.2 in 'D' manual, 28.17.2 in 'A' manual, 24.15.2 in 'E' manual
| 7; /* bits 111 which is GND for MUXNEG - see D manual 22.15.2, A manual 28.17.2 */
}
else
{
ADCA_CH0_MUXCTRL = (pin << ADC_CH_MUXPOS_gp) // sect 22.15.2 in 'D' manual, 28.17.2 in 'A' manual, 24.15.2 in 'E' manual
| 5; /* bits 101 which is GND for MUXNEG - see D manual 22.15.2, A manual 28.17.2 */
}
#endif // E series or not
}
else
{
ADCA_CH0_MUXCTRL = (pin << ADC_CH_MUXPOS_gp) // sect 22.15.2 in 'D' manual, 28.17.2 in 'A' manual, 24.15.2 in 'E' manual
| negpin; // DIFF or 'DIFF WITH GAIN' uses this
}
ADCA_CH0_INTCTRL = 0; // no interrupts, flag on complete sect 22.15.3
#ifdef ADC_CH_IF_bm /* iox16e5.h and iox32e5.h - probably the ATMel Studio version */
ADCA_CH0_INTFLAGS = ADC_CH_IF_bm; // write a 1 to the interrupt bit (which clears it - 22.15.4)
#else // everyone else
ADCA_CH0_INTFLAGS = ADC_CH_CHIF_bm; // write a 1 to the interrupt bit (which clears it - 22.15.4)
#endif // ADC_CH_IF_bm
if(negpin == ANALOG_READ_DELTA_USE_GND)
{
// NOTE: On the A-series processors with more than a handful of inputs,
// it is NOT possible to use 'diff input with gain' on MORE than
// A0-A7. On later processors (like D series) it _IS_ possible.
ADCA_CH0_CTRL = mode // ADC_CH_INPUTMODE_DIFFWGAIN_gc
| (gain & ADC_CH_GAIN_gm)
| ADC_CH_START_bm; // conversion start (bit will clear itself I think)
}
else
{
ADCA_CH0_CTRL = mode // ADC_CH_INPUTMODE_DIFFWGAIN_gc
| (gain & ADC_CH_GAIN_gm)
| ADC_CH_START_bm; // conversion start (bit will clear itself I think)
}
#ifdef ADC_CH_IF_bm /* iox16e5.h and iox32e5.h - probably the ATMel Studio version */
while(!(ADCA_CH0_INTFLAGS & ADC_CH_IF_bm)) { }
#else // everyone else
while(!(ADCA_CH0_INTFLAGS & ADC_CH_CHIF_bm)) { }
#endif // ADC_CH_IF_bm
iRval = ADCA_CH0_RES;
// TODO: scaling and clipping if needed, else +/- 2047
return iRval;
}
// Right now, PWM output only works on the pins with hardware support.
// These are defined in the appropriate pins_arduino.h file. For the
// rest of the pins, we default to digital output with a 1 or 0
#ifdef TCC4
static void DoAnalogWriteForPort(TC4_t *port, uint8_t bit, uint8_t val);
#elif defined(TCC2)
static void DoAnalogWriteForPort(TC2_t *port, uint8_t bit, uint8_t val);
#else // TCC0
static void DoAnalogWriteForPort(TC0_t *port, uint8_t bit, uint8_t val);
#endif // TCC4, TCC2, TCC0
// NOTE: for the xxE5, only 3, 4, 8, 9 seem to work properly with the default configuration
// that would be PORTD pins 4 and 5, and PORTC pins 2 and 3. PORTC pins 0 and 1
// are mapped to the TWI pins SDA and SCL. As such, PORTD pins 4 and 5, and PORTC pins 0-3
// will be allowed. Others will not. PORTD pins 6 and 7 are 'erratic' at best.
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
// NOTE: period registers all contain zeros, which is the MAXIMUM period of 0-255
#ifdef TCC4 /* 'E' series and later that have TCC4 */
uint8_t mode;
#endif // TCC4
uint8_t bit = digitalPinToBitMask(pin);
pinMode(pin, OUTPUT); // forces 'totem pole' - TODO allow for something different?
// note 'val' is a SIGNED INTEGER. deal with 'out of range' values accordingly
if (val <= 0)
{
digitalWrite(pin, LOW);
}
else if (val >= 255)
{
digitalWrite(pin, HIGH);
}
else
{
// NOTE: according to the docs, 16-bit registers MUST be accessed
// low byte first, then high byte, before the actual value
// is transferred to the register. THIS code will.
// see A1U manual sect. 3.11 (and others as well)
switch(digitalPinToTimer(pin))
{
#ifdef TCC4 /* 'E' series and later that have TCC4 */
case TIMERC4:
#ifdef DEBUG_CODE
DebugOutP(PSTR("TIMERC4 "));
DebugOutL(bit);
DebugOutP(PSTR(","));
DebugOutL(val);
DebugOutP(PSTR("\r\n"));
#endif // DEBUG_CODE
DoAnalogWriteForPort(&TCC4, bit, val); // TODO: smaller if inlined here?
break;
case TIMERD5:
// THIS code is unique to the E5, most likely, so it's inlined
if(bit == 1 || bit == 16) // TODO: either bit? not sure if I can re-map these to 0-3
{
*((volatile uint16_t *)&(TCD5_CCA)) = (TCD5_CCA & 0xff00) | (val & 0xff);
mode = (TCD5_CTRLE & ~TC5_LCCAMODE_gm) | TC5_LCCAMODE0_bm;
}
else if(bit == 2 || bit == 32)
{
*((volatile uint16_t *)&(TCD5_CCB)) = (TCD5_CCB & 0xff00) | (val & 0xff);
mode = (TCD5_CTRLE & ~TC5_LCCBMODE_gm) | TC5_LCCBMODE0_bm;
}
else if(bit == 4 || bit == 64)
{
*((volatile uint16_t *)&(TCD5_CCA)) = (TCD5_CCA & 0xff) | ((val << 8) & 0xff00);
mode = (TCD5_CTRLF & ~TC5_HCCAMODE_gm) | TC5_HCCAMODE0_bm;
}
else if(bit == 8 || bit == 128)
{
*((volatile uint16_t *)&(TCD5_CCB)) = (TCD5_CCB & 0xff) | ((val << 8) & 0xff00);
mode = (TCD5_CTRLF & ~TC5_HCCBMODE_gm) | TC5_HCCBMODE0_bm;
}
else
{
break;
}
#ifdef DEBUG_CODE
DebugOutP(PSTR("TIMERD5 "));
DebugOutL(bit);
DebugOutP(PSTR(","));
DebugOutL(val);
DebugOutP(PSTR(","));
DebugOutL(TCD5_CCA);
DebugOutP(PSTR(","));
DebugOutL(TCD5_CCB);
DebugOutP(PSTR(","));
DebugOutL(mode);
DebugOutP(PSTR("\r\n"));
#endif // DEBUG_CODE
if(bit == 1 || bit == 2 || bit == 16 || bit == 32)
{
*((volatile uint8_t *)&(TCD5_CTRLE)) = mode;
#ifdef DEBUG_CODE
DebugOutP(PSTR("E!\r\n"));
#endif // DEBUG_CODE
}
else
{
*((volatile uint8_t *)&(TCD5_CTRLF)) = mode;
#ifdef DEBUG_CODE
DebugOutP(PSTR("F!\r\n"));
#endif // DEBUG_CODE
}
break;
#else // everything else NOT an 'E' series
case TIMERD2:
#ifndef TCD2
DoAnalogWriteForPort(&TCD0, bit, val);
#else // TCD2 defined
DoAnalogWriteForPort(&TCD2, bit, val);
#endif // TCD2 defined
break;
case TIMERC2:
#ifndef TCC2
DoAnalogWriteForPort(&TCC0, bit, val);
#else // TCC2 defined
DoAnalogWriteForPort(&TCC2, bit, val);
#endif // TCC2 defined
break;
#if NUM_DIGITAL_PINS > 22 /* meaning there is a PORT E available with 8 pins */
case TIMERE2: // TIMER 'E2' for 8-bits
#ifndef TCE2
DoAnalogWriteForPort(&TCE0, bit, val);
#else // TCE2 defined
DoAnalogWriteForPort(&TCE2, bit, val);
#endif // TCE2 defined
break;
#if NUM_DIGITAL_PINS > 30 /* meaning there is a PORT F available */
case TIMERF2:
#ifndef TCF2
DoAnalogWriteForPort(&TCF0, bit, val);
#else // TCF2 defined
DoAnalogWriteForPort(&TCF2, bit, val);
#endif // TCF2 defined
break;
#endif // NUM_DIGITAL_PINS > 30
#elif NUM_DIGITAL_PINS > 18 /* meaning there is a PORT E available but with only 4 pins */
case TIMERE0:
// timer E0 counts UP, but a value of 0 would still generate a '0' output because
// the output STARTS at a 1, and flips to 0 when the CTR reaches the CC register
// Similarly, a value of 255 would generate a '1'. see section 12.8.3 in the 'D' manual
if(bit == 1)
{
TCE0_CCA = val; // NOTE: these are 16-bit registers (but I'm in 8-bit mode so it's fine)
}
else if(bit == 2)
{
TCE0_CCB = val;
}
else if(bit == 4)
{
TCE0_CCC = val;
}
else if(bit == 8)
{
TCE0_CCD = val;
}
// this is a reminder that the low nybble should be assigned the correct value for single-slope PWM mode
// TCE0_CTRLB = TC_WGMODE_SS_gc; // single-slope PWM. NOTE: this counts UP, whereas the other timers count DOWN
TCE0_CTRLB |= (bit << 4); // enables output (0-3 only, but that's all PORT E has anyway)
// note that the 'enable' bits are in CTRLB and in upper nybble
break;
#endif // NUM_DIGITAL_PINS >= 18, 24
#endif // TCC4 check
case NOT_ON_TIMER:
default:
if (val < 128)
{
digitalWrite(pin, LOW);
}
else
{
digitalWrite(pin, HIGH);
}
}
}
}
#ifdef TCC4
void DoAnalogWriteForPort(TC4_t *port, uint8_t bit, uint8_t val)
{
uint8_t modeE, modeF;
modeE = port->CTRLE;
modeF = port->CTRLF;
if(bit == 1)
{
port->CCA = (port->CCA & 0xff00) | (val & 0xff);
modeE = (modeE & ~TC4_LCCAMODE_gm) | TC45_LCCAMODE_COMP_gc;
}
else if(bit == 2)
{
port->CCB = (port->CCB & 0xff00) | (val & 0xff);
modeE = (modeE & ~TC4_LCCBMODE_gm) | TC45_LCCBMODE_COMP_gc;
}
else if(bit == 4)
{
port->CCC = (port->CCC & 0xff00) | (val & 0xff);
modeE = (modeE & ~TC4_LCCCMODE_gm) | TC45_LCCCMODE_COMP_gc;
}
else if(bit == 8)
{
port->CCD = (port->CCD & 0xff00) | (val & 0xff);
modeE = (modeE & ~TC4_LCCDMODE_gm) | TC45_LCCDMODE_COMP_gc;
}
else if(bit == 16)
{
port->CCA = (port->CCA & 0xff) | ((val << 8) & 0xff00);
modeF = (modeF & ~TC4_HCCAMODE_gm) | TC45_HCCAMODE_COMP_gc;
}
else if(bit == 32)
{
port->CCB = (port->CCB & 0xff) | ((val << 8) & 0xff00);
modeF = (modeF & ~TC4_HCCBMODE_gm) | TC45_HCCBMODE_COMP_gc;
}
else if(bit == 64)
{
port->CCC = (port->CCC & 0xff) | ((val << 8) & 0xff00);
modeF = (modeF & ~TC4_HCCCMODE_gm) | TC45_HCCCMODE_COMP_gc;
}
else if(bit == 128)
{
port->CCD = (port->CCD & 0xff) | ((val << 8) & 0xff00);
modeF = (modeF & ~TC4_HCCDMODE_gm) | TC45_HCCDMODE_COMP_gc;
}
else
{
return;
}
port->CTRLE = modeE;
port->CTRLF = modeF;
// if(bit <= 8)
// {
// port->CTRLE = mode;
// }
// else
// {
// port->CTRLF = mode;
// }
}
#elif defined(TCC2)
void DoAnalogWriteForPort(TC2_t *port, uint8_t bit, uint8_t val)
{
// NOTE: timers C2 and D2 count DOWN, always. However, the output starts at zero
// and flips to 1 when CTR reaches the CMP value. So a value of 255 would be
// '1' and 0 would be '0', as is expected. See 'D' manual 13.6.2
if(bit == 1)
{
port->LCMPA = val;
}
else if(bit == 2)
{
port->LCMPB = val;
}
else if(bit == 4)
{
port->LCMPC = val;
}
else if(bit == 8)
{
port->LCMPD = val;
}
else if(bit == 16)
{
port->HCMPA = val;
}
else if(bit == 32)
{
port->HCMPB = val;
}
else if(bit == 64)
{
port->HCMPC = val;
}
else if(bit == 128)
{
port->HCMPD = val;
}
// this is a reminder that the low nybble should be assigned the correct value for single-slope PWM mode
// port->CTRLB = TC45_WGMODE_SINGLESLOPE_gc;
port->CTRLB |= bit; // enables output
}
#else // TCC0
void DoAnalogWriteForPort(TC0_t *port, uint8_t bit, uint8_t val)
{
// NOTE: timers C2 and D2 count DOWN, always. However, the output starts at zero
// and flips to 1 when CTR reaches the CMP value. So a value of 255 would be
// '1' and 0 would be '0', as is expected. See 'D' manual 13.6.2
if(bit == 1)
{
port->CCA = (port->CCA & 0xff00) | (val & 0xff);
}
else if(bit == 2)
{
port->CCB = (port->CCB & 0xff00) | (val & 0xff);
}
else if(bit == 4)
{
port->CCC = (port->CCC & 0xff00) | (val & 0xff);
}
else if(bit == 8)
{
port->CCD = (port->CCD & 0xff00) | (val & 0xff);
}
else if(bit == 16)
{
port->CCA = (port->CCA & 0xff) | ((val << 8) & 0xff00);
}
else if(bit == 32)
{
port->CCB = (port->CCB & 0xff) | ((val << 8) & 0xff00);
}
else if(bit == 64)
{
port->CCC = (port->CCC & 0xff) | ((val << 8) & 0xff00);
}
else if(bit == 128)
{
port->CCD = (port->CCD & 0xff) | ((val << 8) & 0xff00);
}
// this is a reminder that the low nybble should be assigned the correct value for single-slope PWM mode
// port->CTRLB = TC45_WGMODE_SINGLESLOPE_gc;
port->CTRLB |= bit; // enables output
}
#endif // TCC4, TCC2, TCC0

View File

@@ -0,0 +1,428 @@
/*
wiring_digital.c - digital input and output functions
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Modified 28 September 2010 by Mark Sproul
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
In some cases, the xmega updates make assumptions about the pin assignments.
See 'pins_arduino.h' for more detail.
*/
#define ARDUINO_MAIN
#include "wiring_private.h"
#include "pins_arduino.h"
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t sense = mode & INPUT_SENSE_MASK;
uint8_t invert = mode & INPUT_OUTPUT_INVERT;
volatile uint8_t *reg, /* *out,*/ *ctrl;
mode &= INPUT_OUTPUT_MASK; // remove 'sense' bits
if (port == NOT_A_PIN)
{
return;
}
reg = portModeRegister(port); // D manual section 11.12.1
if(sense == INPUT_SENSE_DISABLED && reg != &PORTR_DIR) // 'DISABLED'
{
sense = PORT_ISC_INPUT_DISABLE_gc; // bit values for 'INTPUT_DISABLED' (sic)
}
else if(sense == INPUT_SENSE_RISING)
{
sense = PORT_ISC_RISING_gc; // rising
}
else if(sense == INPUT_SENSE_FALLING)
{
sense = PORT_ISC_FALLING_gc; // falling
}
else if(sense == INPUT_SENSE_LEVEL)
{
sense = PORT_ISC_LEVEL_gc; // LOW level (except events, which use HIGH level)
}
else // if(sense == INPUT_SENSE_BOTH) all others including 'DEFAULT'
{
sense = PORT_ISC_BOTHEDGES_gc; // 'both rising and falling'
}
if(invert) // inverted bit value
{
sense |= _BV(PORT_INVEN_bp); // see 11.12.15 in D manual - 'invert' bit
}
// JWS: can I let the optimizer do this?
// reg = portModeRegister(port); // D manual section 11.12.1 (MOVED upwards, BBB)
// out = portOutputRegister(port); // D manual section 11.12.5 (not used - BBB)
ctrl = pinControlRegister(pin); // D manual section 11.12.15
uint8_t oldSREG = SREG;
cli(); // clear interrupt flag until I'm done assigning pin stuff
if (mode == INPUT)
{
*ctrl = sense | PORT_OPC_TOTEM_gc;
*reg &= ~bit;
}
else if (mode == INPUT_PULLUP)
{
*ctrl = sense | PORT_OPC_PULLUP_gc; // input pullup
*reg &= ~bit;
}
else if (mode == INPUT_AND_PULLUP)
{
*ctrl = sense | PORT_OPC_WIREDANDPULL_gc; // wired 'and' (open drain) with pullup
*reg &= ~bit;
}
else if (mode == INPUT_PULLDOWN)
{
*ctrl = sense | PORT_OPC_PULLDOWN_gc; // input pullDOWN
*reg &= ~bit;
}
else if (mode == INPUT_OR_PULLDOWN)
{
*ctrl = sense | PORT_OPC_WIREDORPULL_gc; // wired 'or' (open drain) with pulldown
*reg &= ~bit;
}
else if (mode == INPUT_BUS_KEEPER)
{
*ctrl = sense | PORT_OPC_BUSKEEPER_gc; // bus keeper
*reg &= ~bit;
}
else if (mode == OUTPUT_OR)
{
*ctrl = sense | PORT_OPC_WIREDOR_gc; // wired 'or' (open drain)
*reg |= bit;
}
else if (mode == OUTPUT_AND)
{
*ctrl = sense | PORT_OPC_WIREDAND_gc; // wired 'and' (open drain)
*reg |= bit;
}
else if (mode == OUTPUT_OR_PULLDOWN)
{
*ctrl = sense | PORT_OPC_WIREDORPULL_gc; // wired 'or' (open drain) with pulldown
*reg |= bit;
}
else if (mode == OUTPUT_AND_PULLUP)
{
*ctrl = sense | PORT_OPC_WIREDANDPULL_gc; // wired 'and' (open drain) with pullup
*reg |= bit;
}
else // if(mode == OUTPUT) assume OUTPUT without open drain and/or nor pullup/down
{
*ctrl = sense | PORT_OPC_TOTEM_gc; // 'totem pole' (the default)
*reg |= bit;
}
SREG = oldSREG;
}
// Forcing this inline keeps the callers from having to push their own stuff
// on the stack. It is a good performance win and only takes 1 more byte per
// user than calling. (It will take more bytes on the 168.)
//
// But shouldn't this be moved into pinMode? Seems silly to check and do on
// each digitalread or write.
//
// Mark Sproul:
// - Removed inline. Save 170 bytes on atmega1280
// - changed to a switch statment; added 32 bytes but much easier to read and maintain.
// - Added more #ifdefs, now compiles for atmega645
//
//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
//static inline void turnOffPWM(uint8_t timer)
// BBB - added 'bit' parameter for xmega - it's a bit MASK, not a bit number
// use the result from digitalPinToBitMask(pin) for 'bit'
static void turnOffPWM(uint8_t timer, uint8_t bit)
{
#ifdef TCC4 /* 'E' series and later that have TCC4 */
register uint8_t mode;
#endif // TCC4
switch (timer)
{
#ifdef TCC4 /* 'E' series and later that have TCC4 */
case TIMERC4:
if(bit == 1)
{
mode = (TCC4_CTRLE & ~TC4_LCCAMODE_gm);
}
else if(bit == 2)
{
mode = (TCC4_CTRLE & ~TC4_LCCBMODE_gm);
}
else if(bit == 4)
{
mode = (TCC4_CTRLE & ~TC4_LCCCMODE_gm);
}
else if(bit == 8)
{
mode = (TCC4_CTRLE & ~TC4_LCCDMODE_gm);
}
else if(bit == 16)
{
mode = (TCC4_CTRLF & ~TC4_HCCAMODE_gm);
}
else if(bit == 32)
{
mode = (TCC4_CTRLF & ~TC4_HCCBMODE_gm);
}
else if(bit == 64)
{
mode = (TCC4_CTRLF & ~TC4_HCCCMODE_gm);
}
else if(bit == 128)
{
mode = (TCC4_CTRLF & ~TC4_HCCDMODE_gm);
}
else
{
break;
}
if(bit <= 8)
{
TCC4_CTRLE = mode;
}
else
{
TCC4_CTRLF = mode;
}
break;
case TIMERD5:
if(bit == 1 || bit == 16)
{
mode = (TCD5_CTRLE & ~TC5_LCCAMODE_gm);
}
else if(bit == 2 || bit == 32)
{
mode = (TCD5_CTRLE & ~TC5_LCCBMODE_gm);
}
else if(bit == 4 || bit == 64)
{
mode = (TCD5_CTRLF & ~TC5_HCCAMODE_gm);
}
else if(bit == 8 || bit == 128)
{
mode = (TCD5_CTRLF & ~TC5_HCCBMODE_gm);
}
else
{
break;
}
// TODO: check to see if it was enabled AND the bit was configured properly for PWM
// AND was properly mapped (L vs H, REMAP register?)
if(bit == 1 || bit == 2 || bit == 16 || bit == 32)
{
TCD5_CTRLE = mode;
}
else
{
TCD5_CTRLF = mode;
}
break;
#else // everything else NOT an 'E' series
#ifndef TCC2 /* A1 series does not define this and I need TC0 */
case TIMERD2:
TCD0_CTRLB &= ~bit; // DISables PWM output
break;
case TIMERC2:
TCC0_CTRLB &= ~bit; // DISables PWM output
break;
#if NUM_DIGITAL_PINS > 22 /* which means we have PORT E but with 8 pins, not 4 */
case TIMERE2:
TCE0_CTRLB &= ~bit; // DISables PWM output
break;
#if NUM_DIGITAL_PINS > 30 /* which means we have PORT F */
case TIMERF2:
TCF0_CTRLB &= ~bit; // DISables PWM output
break;
#endif // NUM_DIGITAL_PINS > 30
#elif NUM_DIGITAL_PINS > 18 /* which means we have PORT E but only with 4 pins */
case TIMERE0:
TCE0_CTRLB &= ~(bit << 4); // DISables PWM output
// note that the 'enable' bits are in CTRLB and in upper nybble
break;
#endif // NUM_DIGITAL_PINS > 18, 22
#else // TCC2
case TIMERD2:
TCD2_CTRLB &= ~bit; // DISables PWM output
break;
case TIMERC2:
TCC2_CTRLB &= ~bit; // DISables PWM output
break;
#if NUM_DIGITAL_PINS > 22 /* which means we have PORT E but with 8 pins, not 4 */
case TIMERE2:
TCE2_CTRLB &= ~bit; // DISables PWM output
break;
#if NUM_DIGITAL_PINS > 30 /* which means we have PORT F */
case TIMERF2:
TCF2_CTRLB &= ~bit; // DISables PWM output
break;
#endif // NUM_DIGITAL_PINS > 30
#elif NUM_DIGITAL_PINS > 18 /* which means we have PORT E but only with 4 pins */
// TODO: 64d4 has 4 pins on PORT E. 128A1 has 8 pins on PORT E. determine which to use?
case TIMERE0:
TCE0_CTRLB &= ~(bit << 4); // DISables PWM output
// note that the 'enable' bits are in CTRLB and in upper nybble
break;
#endif // NUM_DIGITAL_PINS > 18, 22
#endif // TCC2
#endif // TCC4
}
}
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out, *ctrl;
if (port == NOT_A_PIN)
{
return;
}
ctrl = pinControlRegister(pin); // D manual section 11.12.15
if(*ctrl & _BV(PORT_INVEN_bp)) // inverted
{
val = !val; // invert the value (so it's consistent with the pin)
}
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
// TODO: move this feature to pinMode() like it should be
// or set a flag to be used with analogWrite()
// (for now it's probably faster just to call it)
if (timer != NOT_ON_TIMER)
{
turnOffPWM(timer, bit);
}
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW)
{
*out &= ~bit;
}
else
{
*out |= bit;
}
SREG = oldSREG;
}
int digitalRead(uint8_t pin)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *ctrl;
uint8_t bSet;
if (port == NOT_A_PIN)
{
return LOW;
}
// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
// TODO: move this feature to pinMode() like it should be
// or set a flag to be used with analogWrite()
// (for now it's probably faster just to call it)
if (timer != NOT_ON_TIMER)
{
turnOffPWM(timer, bit);
}
bSet = (*portInputRegister(port) & bit) ? true : false;
// if the 'invert' flag is on, I invert the digital value
// this is so that the result of 'digitalRead' and 'digitalWrite'
// are ALWAYS consistent with the actual pin level. Inversion is
// needed for proper interrupt control. So for the best consistency,
// the invert flag will only (really) be needed for LEVEL interrupts.
ctrl = pinControlRegister(pin); // D manual section 11.12.15
if(*ctrl & _BV(PORT_INVEN_bp)) // inverted
{
bSet = !bSet;
}
return bSet ? HIGH : LOW;
}

View File

@@ -0,0 +1,125 @@
/*
wiring_private.h - Internal header file.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
*/
#ifndef WiringPrivate_h
#define WiringPrivate_h
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdarg.h>
#include "Arduino.h"
// things that need to be defined in order for the code to compile
// definitions for ADC-related product signature row entries
#ifndef PRODSIGNATURES_ADCACAL0 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_ADCACAL0 _SFR_MEM8(0x0020)
#endif // PRODSIGNATURES_ADCACAL0
#ifndef PRODSIGNATURES_ADCACAL1 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_ADCACAL1 _SFR_MEM8(0x0021)
#endif // PRODSIGNATURES_ADCACAL1
#ifndef PRODSIGNATURES_ADCBCAL0 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_ADCBCAL0 _SFR_MEM8(0x0024)
#endif // PRODSIGNATURES_ADCBCAL0
#ifndef PRODSIGNATURES_ADCBCAL1 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_ADCBCAL1 _SFR_MEM8(0x0025)
#endif // PRODSIGNATURES_ADCBCAL1
// definitions for USB-related product signature row entries
#ifndef PRODSIGNATURES_USBCAL0 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_USBCAL0 _SFR_MEM8(0x001a)
#endif // PRODSIGNATURES_USBCAL0
#ifndef PRODSIGNATURES_USBCAL1 /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_USBCAL1 _SFR_MEM8(0x001b)
#endif // PRODSIGNATURES_USBCAL1
#ifndef PRODSIGNATURES_USBRCOSC /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_USBRCOSC _SFR_MEM8(0x001c)
#endif // PRODSIGNATURES_USBRCOSC
#ifndef PRODSIGNATURES_USBRCOSCA /* _MOST_ headers don't define this properly - see ATMel Studio headers */
#define PRODSIGNATURES_USBRCOSCA _SFR_MEM8(0x001d)
#endif // PRODSIGNATURES_USBRCOSCA
#ifndef ADCA_CH0_SCAN /* A1 headers don't define this properly */
#define ADCA_CH0_SCAN _SFR_MEM8(0x0226)
#define ADC_REFSEL_INTVCC2_gc (0x04<<4)
#define ADC_CH_GAIN_DIV2_gc (0x07<<2)
#endif // ADCA_CH0_SCAN
#ifndef ADC_REFSEL2_bm /* A1 headers don't define this properly, but A1U headers do [and others] */
#define ADC_REFSEL2_bm (1<<6) /* Reference Selection bit 2 mask. */
#define ADC_REFSEL2_bp 6 /* Reference Selection bit 2 position. */
#endif // ADC_REFSEL2_bm
#ifndef PORT_USART0_bm
#define PORT_USART0_bm 0x10 /* Usart0 bit mask for port remap register. */
#endif // PORT_USART0_bm
#ifdef __cplusplus
extern "C"{
#endif
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// NOTE: xmega is SO different that these need to be in pins_arduino.h
// some xmegas have 2 per port, others 1 per port, and the # of ports vary greatly
//#define EXTERNAL_INT_0 0
//#define EXTERNAL_INT_1 1
//#define EXTERNAL_INT_2 2
//#define EXTERNAL_INT_3 3
//#define EXTERNAL_INT_4 4
//#define EXTERNAL_INT_5 5
//#define EXTERNAL_INT_6 6
//#define EXTERNAL_INT_7 7
// CPU-specific definitions go into the 'pins_arduino.h' files anyway
//
//#if defined(SOME_CPU)
//#define EXTERNAL_NUM_INTERRUPTS 8
//#endif
typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
wiring_pulse.c - pulseIn() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#include "wiring_private.h"
#include "pins_arduino.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
}

View File

@@ -0,0 +1,55 @@
/*
wiring_shift.c - shiftOut() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#include "wiring_private.h"
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
}
return value;
}
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}

View File

@@ -0,0 +1,8 @@
## Override some platform.txt settings to create a .bin instead of a .hex file
## The two lines below can be uncommented to have the compiler create a .bin file instead of a .hex file
#compiler.elf2hex.flags=-O binary -R .eeprom
#recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
## Make a .bin version of the .hex file
## The line below can be uncommented to have a .bin file made as well as the .hex file
#recipe.hooks.objcopy.postobjcopy.00.pattern.windows="{compiler.path}{compiler.objcopy.cmd}" -I ihex "{build.path}/{build.project_name}.hex" -O binary "{build.path}/{build.project_name}.bin"

View File

@@ -0,0 +1,139 @@
#
# Customized for the Atmega328p and OrangeRX (XMEGA) multi 4-in-1 boards.
# Both are AVR boards but need different compiler and upload flags and parameters.
#
# For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
name=Multi 4-in-1 AVR
version=1.0.2
compiler.warning_flags=-w
compiler.warning_flags.none=-w
compiler.warning_flags.default=
compiler.warning_flags.more=-Wall
compiler.warning_flags.all=-Wall -Wextra
# Default "compiler.path" is correct, change only if you want to override the initial value
compiler.path={runtime.tools.avr-gcc.path}/bin/
compiler.c.cmd=avr-gcc
compiler.c.flags={board.compiler.c.flags}
compiler.c.elf.flags={compiler.warning_flags} {board.compiler.c.elf.flags}
compiler.c.elf.cmd=avr-gcc
compiler.S.flags={board.compiler.S.flags}
compiler.cpp.cmd=avr-g++
compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto
compiler.ar.cmd=avr-gcc-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=avr-objcopy
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
compiler.elf2hex.flags=-O ihex -R .eeprom
compiler.elf2hex.cmd=avr-objcopy
compiler.ldflags=
compiler.size.cmd=avr-size
# This can be overridden in boards.txt
build.extra_flags=
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.S.extra_flags=
compiler.cpp.extra_flags=
compiler.ar.extra_flags=
compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=
# AVR compile patterns
# --------------------
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Create archives
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
archive_file_path={build.path}/{archive_file}
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
## Create output files (.eep and .hex)
recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
## Save hex
recipe.output.tmp_file={build.project_name}.hex
recipe.output.save_file={board.recipe.output.save_file}
## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*
## Preprocessor
preproc.includes.flags=-w -x c++ -M -MG -MP
recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
preproc.macros.flags=-w -x c++ -E -CC
recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}"
## Post objcopy recipes
# Make a copy of the compiled binary with the version number in the file name
recipe.hooks.objcopy.postobjcopy.01.pattern.windows="{runtime.platform.path}/tools/win/do_version.bat" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board}
recipe.hooks.objcopy.postobjcopy.01.pattern.linux="{runtime.platform.path}/tools/linux/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board}
recipe.hooks.objcopy.postobjcopy.01.pattern.linux64="{runtime.platform.path}/tools/linux64/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board}
recipe.hooks.objcopy.postobjcopy.01.pattern.macosx="{runtime.platform.path}/tools/macosx/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board}
## Post savehex (export compiled binary) recipes
# If we're exporting the hex file, rename it with the version number
recipe.hooks.savehex.postsavehex.01.pattern.windows="{runtime.platform.path}/tools/win/do_version.bat" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board} EXPORT
recipe.hooks.savehex.postsavehex.01.pattern.linux="{runtime.platform.path}/tools/linux/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board} EXPORT
recipe.hooks.savehex.postsavehex.01.pattern.linux64="{runtime.platform.path}/tools/linux64/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board} EXPORT
recipe.hooks.savehex.postsavehex.01.pattern.macosx="{runtime.platform.path}/tools/macosx/do_version" "{build.path}" "{build.project_name}" "{build.source.path}" {build.board} EXPORT
# AVR Uploader/Programmers tools
# ------------------------------
tools.avrdude.path={runtime.tools.avrdude.path}
tools.avrdude.cmd.path={path}/bin/avrdude
tools.avrdude.config.path={board.tools.avrdude.config.path}
tools.avrdude.upload.params.verbose=-v
tools.avrdude.upload.params.quiet=-q -q
# tools.avrdude.upload.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
tools.avrdude.upload.verify=
tools.avrdude.upload.params.noverify=-V
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} {upload.verify} -p{build.mcu} -c{upload.protocol} "-P{serial.port}" -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
tools.avrdude.program.params.verbose=-v
tools.avrdude.program.params.quiet=-q -q
# tools.avrdude.program.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
tools.avrdude.program.verify=
tools.avrdude.program.params.noverify=-V
tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
tools.avrdude.erase.params.verbose=-v
tools.avrdude.erase.params.quiet=-q -q
tools.avrdude.erase.pattern={board.tools.avrdude.erase.pattern}
tools.avrdude.bootloader.params.verbose=-v
tools.avrdude.bootloader.params.quiet=-q -q
tools.avrdude.bootloader.pattern={board.tools.avrdude.bootloader.pattern}
tools.avrdude_remote.upload.pattern=/usr/bin/run-avrdude /tmp/sketch.hex {upload.verbose} -p{build.mcu}
# USB Default Flags
# Default blank usb manufacturer will be filled in at compile time
# - from numeric vendor ID, set to Unknown otherwise
build.usb_manufacturer="Unknown"
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'

View File

@@ -0,0 +1,71 @@
#!/bin/bash
BUILD_PATH=$1
PROJECT_NAME=$2
SKETCH_PATH=$3
MULTI_BOARD=$4
EXPORT_FLAG=$5
IFS== read MULTI_BOARD BOARD_VERSION <<< "$MULTI_BOARD"
case "$MULTI_BOARD" in
MULTI_NO_BOOT)
MULTI_TYPE=avr
;;
MULTI_FLASH_FROM_TX)
MULTI_TYPE=avr
;;
MULTI_STM32_NO_BOOT)
MULTI_TYPE=stm
;;
MULTI_STM32_FLASH_FROM_TX)
MULTI_TYPE=stm
;;
MULTI_ORANGERX)
MULTI_TYPE=orx
;;
esac
#echo "Build Path: $BUILD_PATH"
#echo "Sketch Path: $SKETCH_PATH"
#echo "Project Name: $PROJECT_NAME"
#echo "Multi Board: $MULTI_BOARD"
#echo "Multi Board Type: $MULTI_TYPE"
if [ -e "$BUILD_PATH/sketch/Multiprotocol.h" ]; then
MAJOR_VERSION=$(grep "VERSION_MAJOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MINOR_VERSION=$(grep "VERSION_MINOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
REVISION_VERSION=$(grep "VERSION_REVISION" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
PATCH_VERSION=$(grep "VERSION_PATCH" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
else
MULTI_VERSION=
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ $# -eq 5 ]; then
if [ $EXPORT_FLAG == "EXPORT" ]; then
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.hex" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.hex"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.bin" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.bin"
fi
fi
fi

View File

@@ -0,0 +1,71 @@
#!/bin/bash
BUILD_PATH=$1
PROJECT_NAME=$2
SKETCH_PATH=$3
MULTI_BOARD=$4
EXPORT_FLAG=$5
IFS== read MULTI_BOARD BOARD_VERSION <<< "$MULTI_BOARD"
case "$MULTI_BOARD" in
MULTI_NO_BOOT)
MULTI_TYPE=avr
;;
MULTI_FLASH_FROM_TX)
MULTI_TYPE=avr
;;
MULTI_STM32_NO_BOOT)
MULTI_TYPE=stm
;;
MULTI_STM32_FLASH_FROM_TX)
MULTI_TYPE=stm
;;
MULTI_ORANGERX)
MULTI_TYPE=orx
;;
esac
#echo "Build Path: $BUILD_PATH"
#echo "Sketch Path: $SKETCH_PATH"
#echo "Project Name: $PROJECT_NAME"
#echo "Multi Board: $MULTI_BOARD"
#echo "Multi Board Type: $MULTI_TYPE"
if [ -e "$BUILD_PATH/sketch/Multiprotocol.h" ]; then
MAJOR_VERSION=$(grep "VERSION_MAJOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MINOR_VERSION=$(grep "VERSION_MINOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
REVISION_VERSION=$(grep "VERSION_REVISION" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
PATCH_VERSION=$(grep "VERSION_PATCH" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
else
MULTI_VERSION=
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ $# -eq 5 ]; then
if [ $EXPORT_FLAG == "EXPORT" ]; then
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.hex" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.hex"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.bin" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.bin"
fi
fi
fi

View File

@@ -0,0 +1,71 @@
#!/bin/bash
BUILD_PATH=$1
PROJECT_NAME=$2
SKETCH_PATH=$3
MULTI_BOARD=$4
EXPORT_FLAG=$5
IFS== read MULTI_BOARD BOARD_VERSION <<< "$MULTI_BOARD"
case "$MULTI_BOARD" in
MULTI_NO_BOOT)
MULTI_TYPE=avr
;;
MULTI_FLASH_FROM_TX)
MULTI_TYPE=avr
;;
MULTI_STM32_NO_BOOT)
MULTI_TYPE=stm
;;
MULTI_STM32_FLASH_FROM_TX)
MULTI_TYPE=stm
;;
MULTI_ORANGERX)
MULTI_TYPE=orx
;;
esac
#echo "Build Path: $BUILD_PATH"
#echo "Sketch Path: $SKETCH_PATH"
#echo "Project Name: $PROJECT_NAME"
#echo "Multi Board: $MULTI_BOARD"
#echo "Multi Board Type: $MULTI_TYPE"
if [ -e "$BUILD_PATH/sketch/Multiprotocol.h" ]; then
MAJOR_VERSION=$(grep "VERSION_MAJOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MINOR_VERSION=$(grep "VERSION_MINOR" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
REVISION_VERSION=$(grep "VERSION_REVISION" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
PATCH_VERSION=$(grep "VERSION_PATCH" "$BUILD_PATH/sketch/Multiprotocol.h" | awk -v N=3 '{print $N}')
MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
else
MULTI_VERSION=
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$BUILD_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ $# -eq 5 ]; then
if [ $EXPORT_FLAG == "EXPORT" ]; then
if [ -e "$BUILD_PATH/$PROJECT_NAME.hex" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.hex" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.hex"
fi
if [ -e "$BUILD_PATH/$PROJECT_NAME.bin" ]; then
cp "$BUILD_PATH/$PROJECT_NAME.bin" "$SKETCH_PATH/multi-$MULTI_TYPE-$MULTI_VERSION.bin"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.hex" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.hex"
fi
if [ -e "$SKETCH_PATH/multi-$MULTI_TYPE.bin" ]; then
rm "$SKETCH_PATH/multi-$MULTI_TYPE.bin"
fi
fi
fi

View File

@@ -0,0 +1,79 @@
@ECHO OFF
SETLOCAL EnableDelayedExpansion
REM SET DEBUG=1
SET BUILD_PATH=%1
SET PROJECT_NAME=%2
SET SKETCH_PATH=%3
SET MULTI_BOARD=%4
SET BOARD_VERSION=%5
SET EXPORT_FLAG=%6
REM Remove double-quotes from the paths
SET BUILD_PATH=%BUILD_PATH:"=%
SET SKETCH_PATH=%SKETCH_PATH:"=%
IF %MULTI_BOARD%==MULTI_NO_BOOT SET MULTI_TYPE=avr
IF %MULTI_BOARD%==MULTI_FLASH_FROM_TX SET MULTI_TYPE=avr
IF %MULTI_BOARD%==MULTI_STM32_NO_BOOT SET MULTI_TYPE=stm
IF %MULTI_BOARD%==MULTI_STM32_FLASH_FROM_TX SET MULTI_TYPE=stm
IF %MULTI_BOARD%==MULTI_ORANGERX SET MULTI_TYPE=orx
IF DEFINED DEBUG (
ECHO.
ECHO Sketch Path: %SKETCH_PATH%
ECHO Multi Board: %MULTI_BOARD%
ECHO Multi Board Type: %MULTI_TYPE%
ECHO.
)
IF EXIST "%BUILD_PATH%\sketch\Multiprotocol.h" (
IF DEFINED DEBUG ECHO Getting Multi firmware version from "%BUILD_PATH%\sketch\Multiprotocol.h"
FOR /F "tokens=* usebackq" %%A in (`%SystemRoot%\system32\findstr.exe /C:"#define VERSION_MAJOR" "%BUILD_PATH%\sketch\Multiprotocol.h"`) DO FOR /F "tokens=3" %%i in ("%%A") do SET MAJOR_VERSION=%%i
FOR /F "tokens=* usebackq" %%B in (`%SystemRoot%\system32\findstr.exe /C:"#define VERSION_MINOR" "%BUILD_PATH%\sketch\Multiprotocol.h"`) DO FOR /F "tokens=3" %%i in ("%%B") do SET MINOR_VERSION=%%i
FOR /F "tokens=* usebackq" %%C in (`%SystemRoot%\system32\findstr.exe /C:"#define VERSION_REVISION" "%BUILD_PATH%\sketch\Multiprotocol.h"`) DO FOR /F "tokens=3" %%i in ("%%C") do SET REVISION_VERSION=%%i
FOR /F "tokens=* usebackq" %%D in (`%SystemRoot%\system32\findstr.exe /C:"#define VERSION_PATCH_LEVEL" "%BUILD_PATH%\sketch\Multiprotocol.h"`) DO FOR /F "tokens=3" %%i in ("%%D") do SET PATCH_VERSION=%%i
SET MULTI_VER=!MAJOR_VERSION!.!MINOR_VERSION!.!REVISION_VERSION!.!PATCH_VERSION!
) ELSE (
SET MULTI_VER=
)
IF DEFINED DEBUG (
ECHO.
ECHO Multi Firmware Version: %MULTI_VER%
ECHO.
)
REM Copy the compiled file to the sketch folder with the version number in the file name
IF EXIST "%BUILD_PATH%\%PROJECT_NAME%.hex" (
IF DEFINED DEBUG ECHO COPY "%BUILD_PATH%\%PROJECT_NAME%.hex" "%BUILD_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.hex" /Y
COPY "%BUILD_PATH%\%PROJECT_NAME%.hex" "%BUILD_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.hex" /Y >NUL
)
IF EXIST "%BUILD_PATH%\%PROJECT_NAME%.bin" (
IF DEFINED DEBUG ECHO COPY "%BUILD_PATH%\%PROJECT_NAME%.bin" "%BUILD_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.bin" /Y
COPY "%BUILD_PATH%\%PROJECT_NAME%.bin" "%BUILD_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.bin" /Y >NUL
)
IF "%EXPORT_FLAG%"=="EXPORT" (
REM Copy the compiled file to the sketch folder with the version number in the file name
IF EXIST "%BUILD_PATH%\%PROJECT_NAME%.hex" (
IF DEFINED DEBUG ECHO COPY "%BUILD_PATH%\%PROJECT_NAME%.hex" "%SKETCH_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.hex" /Y
COPY "%BUILD_PATH%\%PROJECT_NAME%.hex" "%SKETCH_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.hex" /Y >NUL
)
IF EXIST "%BUILD_PATH%\%PROJECT_NAME%.bin" (
IF DEFINED DEBUG ECHO COPY "%BUILD_PATH%\%PROJECT_NAME%.bin" "%SKETCH_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.bin" /Y
COPY "%BUILD_PATH%\%PROJECT_NAME%.bin" "%SKETCH_PATH%\multi-%MULTI_TYPE%-%MULTI_VER%.bin" /Y >NUL
)
IF EXIST "%SKETCH_PATH%\multi-%MULTI_TYPE%.bin" (
IF DEFINED DEBUG ECHO DEL "%SKETCH_PATH%\multi-%MULTI_TYPE%.bin"
DEL "%SKETCH_PATH%\multi-%MULTI_TYPE%.bin" >NUL
)
IF EXIST "%SKETCH_PATH%\multi-%MULTI_TYPE%.hex" (
IF DEFINED DEBUG ECHO DEL "%SKETCH_PATH%\multi-%MULTI_TYPE%.hex"
DEL "%SKETCH_PATH%\multi-%MULTI_TYPE%.hex" >NUL
)
)

View File

@@ -0,0 +1,702 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Updated for 'xmega' core by bob frazier, S.F.T. Inc. - http://mrp3.com/
X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A
The xmega code mods make a considerable number of assumptions
about the pin number assignments (as defined here):
DEFAULT MAPPING ('DIGITAL_IO_PIN_SHIFT' NOT DEFINED)
----------------------------------------------------
PORTD - digital 0-7
PORTC - digital 8-15
PORTE - digital 16-20
PORTR - digital 20-21 (built-in LED on PORTR pin 1, aka '21')
PORTA - analog 0-7, digital 22-29
PORTB - analog 8-11, digital 30-33
SPI is assumed to be on PORTC (pins 4-7)
Serial is implemented on PORTD, Serial2 on PORTC, both using pins 2,3 (no flow control)
PORTR pin 1 is assumed to be connected to an LED. Pin 1 is the 'built-in' LED, defined
as 'LED_BUILTIN', and is active HIGH.
Your Mileage May Vary, depending on your board layout. Some boards shift the
digital pin assignments by 2 so that digital I/O pin 0 is PORTD Rx, pin 13 is PORTC SCK, just
like the Arduino ATmega board. Then they align the physical pins so that a regular Arduino shield
will work, and assign PORTD 0-1 to 2 different digital I/O pin numbers (such as 20 and 21).
To facilitate that specific change, uncomment the #define for 'DIGITAL_IO_PIN_SHIFT', below.
Alternately you can create a separate version of this file with a different variant name,
such as 'xmega-compat', with the #define uncommented, stored in an appropriately named directory.
============================
HARDWARE SERIAL FLOW CONTROL
============================
This version of the xmega Arduino startup+support files supports HARDWARE FLOW CONTROL on BOTH serial ports via
RTS (output) and CTS (input). CTS is implemented as input from remote device's DTR. RTS is implemented as DTR output.
To implement RTS/CTS, use definitions similar to the following in your version of this header file
NOTE: RTS(DTR) will be configured as an output, active low (high tells sender to stop sending data to the UART)
CTS will be configured as an input, active low (high stops data from being sent out via UART)
CTS high to low transition causes an interrupt that may result in serial I/O (for faster response time).
// RTS(DTR) as GPIO 0 (port D pin 0)
#define SERIAL_0_RTS_PORT_NAME PORTD
#define SERIAL_0_RTS_PIN_INDEX 0
// CTS as GPIO 1 (port D pin 1)
#define SERIAL_0_CTS_PORT_NAME PORTD
#define SERIAL_0_CTS_PIN_INDEX 1
use similar definitions for serial 1, aka 'SERIAL_1_CTS_PORT'
NOTE: you can even use PORTA or PORTB pins for this, if you don't need to measure analog volts on those pins
X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A X M E G A
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <avr/pgmspace.h>
// for now, the default xmega uses a simple assignment of digital pin numbers, beginning with port D
// to accomodate a useful "compatibility" shield design, these pins can be shifted so that the pin
// that maps to 'digitalRead(0)' would be D2 rather than D0. This also puts 'Serial' on pins 0 and 1
// exactly like the Arduino UNO. For any other mapping, create your own 'pins_arduino.h' file.
//
#define DIGITAL_IO_PIN_SHIFT /* COMMENT THIS to disable the shifting of digital pin assignments for Arduino shield compatibility */
// default two-wire port is TWIC. '#define'ing USE_TWIC maps it to digital pins 20 and 21. Only valid with DIGITAL_IO_PIN_SHIFT '#define'd
#define USE_TWIC /* define this to re-map TWIC to digital pins 20 and 21, similar to an Arduino Mega2560. requires DIGITAL_IO_PIN_SHIFT */
#define NUM_DIGITAL_PINS 22
#define NUM_ANALOG_INPUTS 12
#define analogInputToDigitalPin(p) ((p < 12) ? (p) + 22 : -1)
#ifdef DIGITAL_IO_PIN_SHIFT
#ifdef USE_TWIC
#define digitalPinHasPWM(p) ((p) < 18 || (p) == 20 || (p) == 21) /* PORTC pins 0 and 1 are 20 and 21, respectively */
#else // USE_TWIC
#define digitalPinHasPWM(p) ((p) < 18 || (p) == 20 || (p) == 21) /* PORTD pins 0 and 1 are 20 and 21, respectively */
#endif // USE_TWIC
#else // no digital I/O pin shift
#define digitalPinHasPWM(p) ((p) < 20) /* port E pin 3 is the highest one that has PWM */
#endif // DIGITAL_IO_PIN_SHIFT
// this returns the DEFAULT INTERRUPT (in this case, interrupt 0) for any digital or analog pin
// If you choose a port's pin 2, it will be the same as using 'PORTn_INT0'
#define digitalPinToInterrupt(p) \
( pgm_read_byte(&port_to_int0_PGM[pgm_read_byte(&digital_pin_to_port_PGM[p])]) | \
( ((pgm_read_byte(&digital_pin_to_bit_mask_PGM[p]) - 2) & 7) << 5 ) )
// xmega-specific - Interrupt 'vector number' assignments:
// Interrupts are PORT-SPECIFIC, not pin specific.
// pin 2 on any port is always asynchronous (except for 'R' which doesn't have a pin 2)
// all other pins can manage synchronous interrupts. 'wakeup' from sleep mode
// and other async interrupts must be on a 'pin 2', on ports A through E
//
// Each port has 2 separate interrupt vectors. They can be assigned different pins.
// The same pin can also be assigned to both vectors on the same port, if desired.
#define PORTD_INT0 0
#define PORTD_INT1 1
#define PORTC_INT0 2
#define PORTC_INT1 3
#define PORTE_INT0 4
#define PORTE_INT1 5
#define PORTA_INT0 6
#define PORTA_INT1 7
#define PORTB_INT0 8
#define PORTB_INT1 9
#define PORTR_INT0 10
#define PORTR_INT1 11
#define EXTERNAL_NUM_INTERRUPTS 12 /* defined here instead of wiring_private.h - max value is 32 */
// was in wiring_external.h, moved here
#define EXTERNAL_INT_0 0
#define EXTERNAL_INT_1 1
#define EXTERNAL_INT_2 2
#define EXTERNAL_INT_3 3
#define EXTERNAL_INT_4 4
#define EXTERNAL_INT_5 5
#define EXTERNAL_INT_6 6
#define EXTERNAL_INT_7 7
#define EXTERNAL_INT_8 8
#define EXTERNAL_INT_9 9
#define EXTERNAL_INT_10 10
#define EXTERNAL_INT_11 11
// xmega 'D' series has 2 sets of UART and SPI.
// The default UART is assigned on Port D, pins PD2-3
// The default SPI is assigned on Port C, pins PC4-7
//
// Also there are multiple 2-wire ports, the default being assigned to PC0-1
// see definition for DEFAULT_TWI and USE_TWIC
//
// Standard GPIO pins are assigned as follows:
// PD0-7 Digital 0-7
// PC0-7 Digital 8-15
// PE0-3 digital 16-19
// PR0-1 digital 20-21
// PA0-7 analog A0-A7
// PB0-3 analog A8-A11
//
// '#define'ing DIGITAL_IO_PIN_SHIFT shifts this down by 2, and places PD0-1 on 20-21
// This is for Arduino 'atmega' compatibility with respect to existing shields, so that
// you don't have to re-map pin numbers with #defines in existing software that hard-codes them
// or makes assumptions about pin numbers vs functionality [except TWI won't ever match up]
//
// '#define'ing USE_TWIC puts PC0-1 on 20-21 (corresponding to TWI pins on later Arduinos)
//
//
// ALL PORT REMAP registers must be assigned to 0 (default mappings for pins)
// this puts PWM output on pins 0-3 for PORT E (the timers are split for C and D)
// Additionally, CLKOUT should be 0 (no clock outputs on any port/pin).
//
// TIMERS
// Timer 0 should be configured as 'Tx2' (for 8 PWM outputs) by default, essentially
// as a dual 8-bit timer, more or less compatible with the Arduino's 3 timers and
// supporting all 8 pins on ports C and D for PWM output. Port C's timer supports
// the system clock.
//
// See 'D' manual chapter 13 for more on this
// ------------------------------------------
// DEFINITIONS FOR SERIAL PORTS AND TWI PORTS
// ------------------------------------------
// TWI ports
#define DEFAULT_TWI TWIC /* note see definitions for SDA and SCL, below - alter accordingly */
// the XMega64D4 has two TWI ports
#define TWI_PORT0 TWIC
#define TWI_VECTOR_S0 TWIC_TWIS_vect
#define TWI_VECTOR_M0 TWIC_TWIM_vect
#define TWI_PORT1 TWIE
#define TWI_VECTOR_S1 TWIE_TWIS_vect
#define TWI_VECTOR_M1 TWIE_TWIM_vect
#define TWI_INTERFACE_COUNT 2
// obsolete - consider removal in all of them
//#define TWIC_VECT_ENABLE /* use this to select the correct interrupt vectors for default */
// serial port 0
#define SERIAL_0_PORT_NAME PORTD
#define SERIAL_0_USART_NAME USARTD0
#define SERIAL_0_USART_DATA USARTD0_DATA
#define SERIAL_0_RXC_ISR ISR(USARTD0_RXC_vect)
#define SERIAL_0_DRE_ISR ISR(USARTD0_DRE_vect)
//#define SERIAL_0_REMAP PORTD_REMAP /* define THIS to re-map the pins from 0-3 to 4-7 on serial port 0 */
#define SERIAL_0_REMAP_BIT 4 /* the bit needed to remap the port if SERIAL_0_REMAP is defined */
#define SERIAL_0_RX_PIN_INDEX 2 /* the pin number on the port, not the mapped digital pin number */
#define SERIAL_0_TX_PIN_INDEX 3 /* the pin number on the port, not the mapped digital pin number */
#define USARTD0_VECTOR_EXISTS
// serial port 1
#define SERIAL_1_PORT_NAME PORTC
#define SERIAL_1_USART_NAME USARTC0
#define SERIAL_1_USART_DATA USARTC0_DATA
#define SERIAL_1_RXC_ISR ISR(USARTC0_RXC_vect)
#define SERIAL_1_DRE_ISR ISR(USARTC0_DRE_vect)
//#define SERIAL_1_REMAP PORTC_REMAP /* define THIS to re-map the pins from 0-3 to 4-7 on serial port 1 */
#define SERIAL_1_REMAP_BIT 4 /* the bit needed to remap the port if SERIAL_1_REMAP is defined */
#define SERIAL_1_RX_PIN_INDEX 2 /* the pin number on the port, not the mapped digital pin number */
#define SERIAL_1_TX_PIN_INDEX 3 /* the pin number on the port, not the mapped digital pin number */
#define USARTC0_VECTOR_EXISTS
// For atmega/Arduino shield compatibility, with DIGITAL_IO_PIN_SHIFT defined
// typical board/pin layout might be like this (for shield pins):
//
// NOTE: this design/layout assumes USE_TWIC is defined, so TWI is on TWIC (port C pins 0/1)
//
// M M
// S I O T R
// A C S S S x x
// S S R G K O I S 2 2 T R
// C D E N 1 1 1 1 x x
// L A F D 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// ----o-o-o-o-o-o-o-o-o-o--o-o-o-o-o-o-o-o----
// P P P P P P P P P P P P P P P P
// C C C C C C C C C C D D D D D D
// 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2
//
//
// T O P V I E W
//
//
// P P P P P P
// A A A A A A
// 5 4 3 2 1 0
// ------------o-o-o-o-o-o-o-o--o-o-o-o-o-o----
// G I R 3 5 G G V A A A A A A
// N O E . V N N i 5 4 3 2 1 0
// D R S 3 D D n
// E E V
// F T
//
// As with the MEGA2560 and other 'mega' Arduino boards, additional connectors would
// break out the additional pins, with appropriate labeling. Additionally, there should
// be an LED on PORTR pin 1 for 'LED_BUILTIN'.
//
// This layout is based on the 'Rev 3' Arduino.
//
// NOTE - NO AREF: AREF is not connected. AREF is a bit of an issue on xmega because
// it DOES! NOT! WORK! THE! SAME! as it does on the ATmegaXXX and so you would need to
// (literally) steal one of the additional analog input pins to implement it. It's not
// impossible, or even THAT difficult. I'm just not doing it here.
#ifdef DIGITAL_IO_PIN_SHIFT // aka digital I/O pin 0 is PORTD pin 2
// SHIFTED I/O pins (atmega compatibility) - see xmega mod description in comment at top
// default SPI
static const uint8_t SS = 10;
static const uint8_t MOSI = 11;
static const uint8_t MISO = 12;
static const uint8_t SCK = 13;
// primary SPI on PC4-7
static const uint8_t SS0 = 10;
static const uint8_t MOSI0 = 11;
static const uint8_t MISO0 = 12;
static const uint8_t SCK0 = 13;
// secondary SPI on PD4-7
static const uint8_t SS1 = 2;
static const uint8_t MOSI1 = 3;
static const uint8_t MISO1 = 4;
static const uint8_t SCK1 = 5;
// default 2-wire on PC0,PC1 - TWIC
#ifdef USE_TWIC
static const uint8_t SDA = 20;
static const uint8_t SCL = 21;
#else // !USE_TWIC
static const uint8_t SDA = 6;
static const uint8_t SCL = 7;
#endif // USE_TWIC
// port-specific 2-wire
#ifdef USE_TWIC
static const uint8_t SDA0 = 20;
static const uint8_t SCL0 = 21;
#else // !USE_TWIC
static const uint8_t SDA0 = 6;
static const uint8_t SCL0 = 7;
#endif // USE_TWIC
static const uint8_t SDA1 = 14;
static const uint8_t SCL1 = 15;
// keep track of the indices for port R since its control register
// settings should be slightly different - D manual table 11-6
#define PR0 18
#define PR1 19
#else // no digital I/O pin shifting, PORTD pin 0 is digital I/O pin 0 (as it should be)
// default "no shift" pin assignments
// default SPI
static const uint8_t SS = 12;
static const uint8_t MOSI = 13;
static const uint8_t MISO = 14;
static const uint8_t SCK = 15;
// primary SPI on PC4-7
static const uint8_t SS0 = 12;
static const uint8_t MOSI0 = 13;
static const uint8_t MISO0 = 14;
static const uint8_t SCK0 = 15;
// secondary SPI on PD4-7
static const uint8_t SS1 = 4;
static const uint8_t MOSI1 = 5;
static const uint8_t MISO1 = 6;
static const uint8_t SCK1 = 7;
// default 2-wire on PC0,PC1 - TWIC (TWIE appears to be broken)
static const uint8_t SDA = 8;
static const uint8_t SCL = 9;
static const uint8_t SDA0 = 8;
static const uint8_t SCL0 = 9;
static const uint8_t SDA1 = 16;
static const uint8_t SCL1 = 17;
// keep track of the indices for port R since its control register
// settings should be slightly different - D manual table 11-6
#define PR0 20
#define PR1 21
#endif // DIGITAL_IO_PIN_SHIFT
// default 'status' LED on PR1
//static const uint8_t LED_BUILTIN = PR1;
#define LED_BUILTIN PR1 /* Arduino 1.06 uses #define, not a const uint8_t */
static const uint8_t A0 = 22;
static const uint8_t A1 = 23;
static const uint8_t A2 = 24;
static const uint8_t A3 = 25;
static const uint8_t A4 = 26;
static const uint8_t A5 = 27;
static const uint8_t A6 = 28;
static const uint8_t A7 = 29;
static const uint8_t A8 = 30;
static const uint8_t A9 = 31;
static const uint8_t A10 = 32;
static const uint8_t A11 = 33;
// on the xmega64d4, PA2, PB2, PC2, PD2, and PE2 are asynchronous ints. Others are 'synchronous' which means
// that they must be held in their 'interrupt state' long enough for the system to detect them. In any case
// all digital input pins can be use as interrupts, synchronous or otherwise.
#ifdef ARDUINO_MAIN
const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT, // 0
(uint16_t) &PORTA_DIR, // PA
(uint16_t) &PORTB_DIR, // PB
(uint16_t) &PORTC_DIR, // PC
(uint16_t) &PORTD_DIR, // PD
(uint16_t) &PORTE_DIR, // PE
(uint16_t) &PORTR_DIR, // PR
};
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT, // 0
(uint16_t) &PORTA_OUT, // PA
(uint16_t) &PORTB_OUT, // PB
(uint16_t) &PORTC_OUT, // PC
(uint16_t) &PORTD_OUT, // PD
(uint16_t) &PORTE_OUT, // PE
(uint16_t) &PORTR_OUT, // PR
};
const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PORT, // 0
(uint16_t) &PORTA_IN, // PA
(uint16_t) &PORTB_IN, // PB
(uint16_t) &PORTC_IN, // PC
(uint16_t) &PORTD_IN, // PD
(uint16_t) &PORTE_IN, // PE
(uint16_t) &PORTR_IN, // PR
};
const uint8_t PROGMEM port_to_int0_PGM[] = {
NOT_AN_INTERRUPT, // 0
PORTA_INT0, // PA
PORTB_INT0, // PB
PORTC_INT0, // PC
PORTD_INT0, // PD
PORTE_INT0, // PE
PORTR_INT0, // PR
};
// xmega has a per-pin config register as well. Normally these will be 00000111 for analog, 00000000 for digital 'totem pole'
// for 'INPUT_PULLUP' these will be 00011111
// bits 2:0 (trigger) 000 both edges 001 rising 010 falling 011 level 111 input buffer disabled
// note: 'input buffer disabled' required to use the 'IN' register (so default here)
// also port R does not support 'INTPUT_DISABLED' (sic) so use BOTHEDGES [0] instead
// bits 5:3 (out/pull) 000 TOTEM [normal], 001 bus keeper [sticky], 010 pulldown, 011 pullup,
// 100 wired 'or', 101 wired 'and', 110 wired 'or' pulldown, 111 wired 'and' pullup
// bit 6: "invert logic" (0 = normal, 1 = inverted)
// bit 7: unused, must be zero
// NOTE: PORTA through PORTE (PORTF?) support 'input buffer disabled' and this setting is recommended
// for analog inputs. PORTR apparently does NOT support this (set to zero?)
const uint16_t PROGMEM digital_pin_to_control_PGM[] = {
#ifndef DIGITAL_IO_PIN_SHIFT
(uint16_t) &PORTD_PIN0CTRL, // PD 0 ** 0 **
(uint16_t) &PORTD_PIN1CTRL, // PD 1 ** 1 **
#endif // DIGITAL_IO_PIN_SHIFT
// subtract 2 from the digital pin number if DIGITAL_IO_PIN_SHIFT is defined
(uint16_t) &PORTD_PIN2CTRL, // PD 2 ** 2 ** USARTD_RX ASYNC
(uint16_t) &PORTD_PIN3CTRL, // PD 3 ** 3 ** USARTD_TX
(uint16_t) &PORTD_PIN4CTRL, // PD 4 ** 4 **
(uint16_t) &PORTD_PIN5CTRL, // PD 5 ** 5 **
(uint16_t) &PORTD_PIN6CTRL, // PD 6 ** 6 **
(uint16_t) &PORTD_PIN7CTRL, // PD 7 ** 7 **
#if defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
(uint16_t) &PORTD_PIN0CTRL, // PD 0 ** 8 ** map PORTD pins 0/1 here if TWIC is used
(uint16_t) &PORTD_PIN1CTRL, // PD 1 ** 9 **
#else
(uint16_t) &PORTC_PIN0CTRL, // PC 0 ** 8 ** SDA
(uint16_t) &PORTC_PIN1CTRL, // PC 1 ** 9 ** SCL
#endif // defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
(uint16_t) &PORTC_PIN2CTRL, // PC 2 ** 10 ** ASYNC
(uint16_t) &PORTC_PIN3CTRL, // PC 3 ** 11 **
(uint16_t) &PORTC_PIN4CTRL, // PC 4 ** 12 ** SPI_SS
(uint16_t) &PORTC_PIN5CTRL, // PC 5 ** 13 ** SPI_MOSI
(uint16_t) &PORTC_PIN6CTRL, // PC 6 ** 14 ** SPI_MISO
(uint16_t) &PORTC_PIN7CTRL, // PC 7 ** 15 ** SPI_SCK
(uint16_t) &PORTE_PIN0CTRL, // PE 0 ** 16 ** SDA1
(uint16_t) &PORTE_PIN1CTRL, // PE 1 ** 17 ** SCL1
(uint16_t) &PORTE_PIN2CTRL, // PE 2 ** 18 ** ASYNC
(uint16_t) &PORTE_PIN3CTRL, // PE 3 ** 19 **
(uint16_t) &PORTR_PIN0CTRL, // PR 0 ** 20 **
(uint16_t) &PORTR_PIN1CTRL, // PR 1 ** 21 ** default LED
#ifdef DIGITAL_IO_PIN_SHIFT
#ifdef USE_TWIC
(uint16_t) &PORTC_PIN0CTRL, // PC 0 ** the new 20 ** SDA, SDA0
(uint16_t) &PORTC_PIN1CTRL, // PC 1 ** the new 21 ** SCL, SCL0
#else
(uint16_t) &PORTD_PIN0CTRL, // PD 0 ** the new 20 **
(uint16_t) &PORTD_PIN1CTRL, // PD 1 ** the new 21 **
#endif // USE_TWIC
#endif // DIGITAL_IO_PIN_SHIFT
(uint16_t) &PORTA_PIN0CTRL, // PA 0 ** 22 ** A0
(uint16_t) &PORTA_PIN1CTRL, // PA 1 ** 23 ** A1
(uint16_t) &PORTA_PIN2CTRL, // PA 2 ** 24 ** A2 ASYNC
(uint16_t) &PORTA_PIN3CTRL, // PA 3 ** 25 ** A3
(uint16_t) &PORTA_PIN4CTRL, // PA 4 ** 26 ** A4
(uint16_t) &PORTA_PIN5CTRL, // PA 5 ** 27 ** A5
(uint16_t) &PORTA_PIN6CTRL, // PA 6 ** 28 ** A6
(uint16_t) &PORTA_PIN7CTRL, // PA 7 ** 29 ** A7
(uint16_t) &PORTB_PIN0CTRL, // PB 0 ** 30 ** A8
(uint16_t) &PORTB_PIN1CTRL, // PB 1 ** 31 ** A9
(uint16_t) &PORTB_PIN2CTRL, // PB 2 ** 32 ** A10 ASYNC
(uint16_t) &PORTB_PIN3CTRL, // PB 3 ** 33 ** A11
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
// PORTLIST
// -------------------------------------------
#ifndef DIGITAL_IO_PIN_SHIFT
_PD, // PD 0 ** 0 **
_PD, // PD 1 ** 1 **
#endif // DIGITAL_IO_PIN_SHIFT
// subtract 2 from the digital pin number if DIGITAL_IO_PIN_SHIFT is defined
_PD, // PD 2 ** 2 ** USARTD_RX
_PD, // PD 3 ** 3 ** USARTD_TX
_PD, // PD 4 ** 4 **
_PD, // PD 5 ** 5 **
_PD, // PD 6 ** 6 **
_PD, // PD 7 ** 7 **
#if defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
_PD, // PD 0 ** 8 **
_PD, // PD 1 ** 9 **
#else
_PC, // PC 0 ** 8 ** SDA
_PC, // PC 1 ** 9 ** SCL
#endif // defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
_PC, // PC 2 ** 10 **
_PC, // PC 3 ** 11 **
_PC, // PC 4 ** 12 ** SPI_SS
_PC, // PC 5 ** 13 ** SPI_MOSI
_PC, // PC 6 ** 14 ** SPI_MISO
_PC, // PC 7 ** 15 ** SPI_SCK
_PE, // PE 0 ** 16 ** SDA
_PE, // PE 1 ** 17 ** SCL
_PE, // PE 2 ** 18 **
_PE, // PE 3 ** 19 **
_PR, // PR 0 ** 20 **
_PR, // PR 1 ** 21 ** default LED
#ifdef DIGITAL_IO_PIN_SHIFT
#ifdef USE_TWIC
_PC, // PC 0 ** the new 20 ** SDA
_PC, // PC 1 ** the new 21 ** SCL
#else
_PD, // PD 0 ** the new 20 **
_PD, // PD 1 ** the new 21 **
#endif // USE_TWIC
#endif // DIGITAL_IO_PIN_SHIFT
_PA, // PA 0 ** 22 ** A0
_PA, // PA 1 ** 23 ** A1
_PA, // PA 2 ** 24 ** A2
_PA, // PA 3 ** 25 ** A3
_PA, // PA 4 ** 26 ** A4
_PA, // PA 5 ** 27 ** A5
_PA, // PA 6 ** 28 ** A6
_PA, // PA 7 ** 29 ** A7
_PB, // PB 0 ** 30 ** A8
_PB, // PB 1 ** 31 ** A9
_PB, // PB 2 ** 32 ** A10
_PB, // PB 3 ** 33 ** A11
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
// PIN IN PORT
// -------------------------------------------
#ifndef DIGITAL_IO_PIN_SHIFT
_BV( 0 ), // PD 0 ** 0 **
_BV( 1 ), // PD 1 ** 1 **
#endif // DIGITAL_IO_PIN_SHIFT
// subtract 2 from the digital pin number if DIGITAL_IO_PIN_SHIFT is defined
_BV( 2 ), // PD 2 ** 2 ** USARTD_RX
_BV( 3 ), // PD 3 ** 3 ** USARTD_TX
_BV( 4 ), // PD 4 ** 4 **
_BV( 5 ), // PD 5 ** 5 **
_BV( 6 ), // PD 6 ** 6 **
_BV( 7 ), // PD 7 ** 7 **
#if defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
_BV( 0 ), // PD 0 ** 8 **
_BV( 1 ), // PD 1 ** 9 **
#else
_BV( 0 ), // PC 0 ** 8 ** SDA
_BV( 1 ), // PC 1 ** 9 ** SCL
#endif // defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
_BV( 2 ), // PC 2 ** 10 **
_BV( 3 ), // PC 3 ** 11 **
_BV( 4 ), // PC 4 ** 12 ** SPI_SS
_BV( 5 ), // PC 5 ** 13 ** SPI_MOSI
_BV( 6 ), // PC 6 ** 14 ** SPI_MISO
_BV( 7 ), // PC 7 ** 15 ** SPI_SCK
_BV( 0 ), // PE 0 ** 16 ** SDA
_BV( 1 ), // PE 1 ** 17 ** SCL
_BV( 2 ), // PE 2 ** 18 **
_BV( 3 ), // PE 3 ** 19 **
_BV( 0 ), // PR 0 ** 20 **
_BV( 1 ), // PR 1 ** 21 ** default LED
#ifdef DIGITAL_IO_PIN_SHIFT
#ifdef USE_TWIC
_BV( 0 ), // PC 0 ** the new 20 ** SDA
_BV( 1 ), // PC 1 ** the new 21 ** SCL
#else
_BV( 0 ), // PD 0 ** the new 20 **
_BV( 1 ), // PD 1 ** the new 21 **
#endif // USE_TWIC
#endif // DIGITAL_IO_PIN_SHIFT
_BV( 0 ), // PA 0 ** 22 ** A0
_BV( 1 ), // PA 1 ** 23 ** A1
_BV( 2 ), // PA 2 ** 24 ** A2
_BV( 3 ), // PA 3 ** 25 ** A3
_BV( 4 ), // PA 4 ** 26 ** A4
_BV( 5 ), // PA 5 ** 27 ** A5
_BV( 6 ), // PA 6 ** 28 ** A6
_BV( 7 ), // PA 7 ** 29 ** A7
_BV( 0 ), // PB 0 ** 30 ** A8
_BV( 1 ), // PB 1 ** 31 ** A9
_BV( 2 ), // PB 2 ** 32 ** A10
_BV( 3 ), // PB 3 ** 33 ** A11
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
// TIMERS
// -------------------------------------------
// for now 'NOT_ON_TIMER' for all - later, assign timers based
// on pins 0-3 being enabled as PWM out for ports A through E
// corresponding to timers A through D (see D manual sections 11.12.14,
// also see D manual sect 13.6 for using the 'compare' channel on 'TCx2' to generate
// a PWM output. Must select pin as output, _AND_ enable the 'compare' output
// for the appropriate pin. LCMPENx/HCMPENx registers to enable it.
#ifndef DIGITAL_IO_PIN_SHIFT
TIMERD2, // PD 0 ** 0 **
TIMERD2, // PD 1 ** 1 **
#endif // DIGITAL_IO_PIN_SHIFT
// subtract 2 from the digital pin number if DIGITAL_IO_PIN_SHIFT is defined
TIMERD2, // PD 2 ** 2 ** USARTD_RX
TIMERD2, // PD 3 ** 3 ** USARTD_TX
TIMERD2, // PD 4 ** 4 **
TIMERD2, // PD 5 ** 5 **
TIMERD2, // PD 6 ** 6 **
TIMERD2, // PD 7 ** 7 **
#if defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
TIMERD2, // PD 0 ** 8 **
TIMERD2, // PD 1 ** 9 **
#else
TIMERC2, // PC 0 ** 8 ** SDA
TIMERC2, // PC 1 ** 9 ** SCL
#endif // defined(DIGITAL_IO_PIN_SHIFT) && defined(USE_TWIC)
TIMERC2, // PC 2 ** 10 **
TIMERC2, // PC 3 ** 11 **
TIMERC2, // PC 4 ** 12 ** SPI_SS
TIMERC2, // PC 5 ** 13 ** SPI_MOSI
TIMERC2, // PC 6 ** 14 ** SPI_MISO
TIMERC2, // PC 7 ** 15 ** SPI_SCK
TIMERE0, // PE 0 ** 16 ** SDA
TIMERE0, // PE 1 ** 17 ** SCL
TIMERE0, // PE 2 ** 18 **
TIMERE0, // PE 3 ** 19 **
NOT_ON_TIMER, // PR 0 ** 20 **
NOT_ON_TIMER, // PR 1 ** 21 ** default LED
#ifdef DIGITAL_IO_PIN_SHIFT
#ifdef USE_TWIC
TIMERC2, // PC 0 ** the new 20 ** SDA
TIMERC2, // PC 1 ** the new 21 ** SCL
#else
TIMERD2, // PD 0 ** the new 20 **
TIMERD2, // PD 1 ** the new 21 **
#endif // USE_TWIC
#endif // DIGITAL_IO_PIN_SHIFT
NOT_ON_TIMER, // PA 0 ** 22 ** A0
NOT_ON_TIMER, // PA 1 ** 23 ** A1
NOT_ON_TIMER, // PA 2 ** 24 ** A2
NOT_ON_TIMER, // PA 3 ** 25 ** A3
NOT_ON_TIMER, // PA 4 ** 26 ** A4
NOT_ON_TIMER, // PA 5 ** 27 ** A5
NOT_ON_TIMER, // PA 6 ** 28 ** A6
NOT_ON_TIMER, // PA 7 ** 29 ** A7
NOT_ON_TIMER, // PB 0 ** 30 ** A8
NOT_ON_TIMER, // PB 1 ** 31 ** A9
NOT_ON_TIMER, // PB 2 ** 32 ** A10
NOT_ON_TIMER, // PB 3 ** 33 ** A11
};
#endif
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_MONITOR Serial
#define SERIAL_PORT_HARDWARE Serial
#define SERIAL_HARDWARE_OPEN Serial2
#endif

View File

@@ -0,0 +1,26 @@
#!/bin/bash
AVR_VERSION=$(grep "^version=[0-9].[0-9].[0-9]" "avr/platform.txt" | awk -F = '{ print $2 }')
STM_VERSION=$(grep "^version=[0-9].[0-9].[0-9]" "stm32/platform.txt" | awk -F = '{ print $2 }')
echo
echo "AVR Version: $AVR_VERSION"
echo "Creating archive 'package_multi_4in1_avr_board_v$AVR_VERSION.tar.gz'"
tar -czf ../Archives/package_multi_4in1_avr_board_v$AVR_VERSION.tar.gz --transform s/avr/package_multi_4in1_avr_board_v$AVR_VERSION/ avr/*
sleep 1s
echo
echo "Package: package_multi_4in1_avr_board_v$AVR_VERSION.tar.gz"
echo "SHA256: `(sha256sum ../Archives/package_multi_4in1_avr_board_v$AVR_VERSION.tar.gz | awk -v N=1 '{print $N}')`"
echo "Size: `(ls -al ../Archives/package_multi_4in1_avr_board_v$AVR_VERSION.tar.gz | awk -v N=5 '{print $N}')`"
echo
echo "STM Version: $STM_VERSION"
echo "Creating archive 'package_multi_4in1_stm32_board_v$STM_VERSION.tar.gz'"
tar -czf ../Archives/package_multi_4in1_stm32_board_v$STM_VERSION.tar.gz --transform s/stm32/package_multi_4in1_stm32_board_v$STM_VERSION/ stm32/*
sleep 1s
echo
echo "Package: package_multi_4in1_stm_board_v$STM_VERSION.tar.gz"
echo "SHA256: `(sha256sum ../Archives/package_multi_4in1_stm32_board_v$STM_VERSION.tar.gz | awk -v N=1 '{print $N}')`"
echo "Size: `(ls -al ../Archives/package_multi_4in1_stm32_board_v$STM_VERSION.tar.gz | awk -v N=5 '{print $N}')`"
echo
echo Done
echo

View File

@@ -0,0 +1,64 @@
# See: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
# See: http://code.google.com/p/arduino/wiki/Platforms
##############################################################
menu.upload_method=Upload method
menu.bootloader=Bootloader
##############################################################
## Multi 4-in-1 STM32
## --------------------------------------------------
multistm32f103c.name=Multi 4-in-1 (STM32F103CB)
multistm32f103c.vid.0=0x1EAF
multistm32f103c.pid.0=0x0004
multistm32f103c.build.variant=generic_stm32f103c
multistm32f103c.build.vect=VECT_TAB_ADDR=0x8000000
multistm32f103c.build.core=maple
multistm32f103c.build.board=MULTI_STM32_FLASH_FROM_TX=103
multistm32f103c.upload.use_1200bps_touch=false
multistm32f103c.upload.file_type=bin
multistm32f103c.upload.auto_reset=true
multistm32f103c.upload.tool=maple_upload
multistm32f103c.upload.protocol=maple_dfu
multistm32f103c.build.cpu_flags=-DMCU_STM32F103CB
multistm32f103c.build.ldscript=ld/jtag.ld
multistm32f103c.upload.maximum_size=131072
multistm32f103c.upload.maximum_data_size=20480
multistm32f103c.build.f_cpu=72000000L
multistm32f103c.build.flags.optimize=-Os
multistm32f103c.build.flags.ldspecs=
multistm32f103c.bootloader.tool=serial_upload
#---------------------------- UPLOAD METHODS ---------------------------
multistm32f103c.menu.upload_method.TxFlashMethod=Flash from Tx
multistm32f103c.menu.upload_method.TxFlashMethod.build.board=MULTI_STM32_FLASH_FROM_TX=103
multistm32f103c.menu.upload_method.TxFlashMethod.upload.tool=tx_upload
multistm32f103c.menu.upload_method.TxFlashMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
multistm32f103c.menu.upload_method.TxFlashMethod.build.vect=VECT_TAB_ADDR=0x8002000
multistm32f103c.menu.upload_method.TxFlashMethod.build.ldscript=ld/bootloader_20.ld
multistm32f103c.menu.upload_method.TxFlashMethod.bootloader.file=Multi4in1/StmMultiBoot.bin
multistm32f103c.menu.upload_method.DFUUploadMethod=Upload via USB
multistm32f103c.menu.upload_method.DFUUploadMethod.build.board=MULTI_STM32_NO_BOOT=103
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
multistm32f103c.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
multistm32f103c.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
multistm32f103c.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20.ld
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.altID=2
multistm32f103c.menu.upload_method.DFUUploadMethod.bootloader.file=Multi4in1/StmMultiUSB.bin
multistm32f103c.menu.upload_method.serialMethod=Upload via Serial (FTDI)
multistm32f103c.menu.upload_method.serialMethod.upload.protocol=maple_serial
multistm32f103c.menu.upload_method.serialMethod.upload.tool=serial_upload
multistm32f103c.menu.upload_method.serialMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG
multistm32f103c.menu.upload_method.serialMethod.build.board=MULTI_STM32_NO_BOOT=103
##############################################################

View File

@@ -0,0 +1,44 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
#ifndef _WIRISH_WPROGRAM_H_
#define _WIRISH_WPROGRAM_H_
#include "wirish.h"
void setup();
void loop();
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
void yield(void);
#ifdef __cplusplus
}
#endif // __cplusplus
#include "variant.h"
#endif

View File

@@ -0,0 +1,45 @@
/*
Client.h - Base class that provides Client
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef client_h
#define client_h
#include "Print.h"
#include "Stream.h"
#include "IPAddress.h"
class Client : public Stream {
public:
virtual int connect(IPAddress ip, uint16_t port) =0;
virtual int connect(const char *host, uint16_t port) =0;
virtual size_t write(uint8_t) =0;
virtual size_t write(const uint8_t *buf, size_t size) =0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
#endif

View File

@@ -0,0 +1,200 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file wirish/HardwareSerial.cpp
* @brief Wirish serial port implementation.
*/
#include "HardwareSerial.h"
#include <libmaple/libmaple.h>
#include <libmaple/gpio.h>
#include <libmaple/timer.h>
#include <libmaple/usart.h>
#if 0
#define DEFINE_HWSERIAL(name, n) \
HardwareSerial name(USART##n, \
BOARD_USART##n##_TX_PIN, \
BOARD_USART##n##_RX_PIN)
#define DEFINE_HWSERIAL_UART(name, n) \
HardwareSerial name(UART##n, \
BOARD_USART##n##_TX_PIN, \
BOARD_USART##n##_RX_PIN)
#ifdef SERIAL_USB
#if BOARD_HAVE_USART1
DEFINE_HWSERIAL(Serial1, 1);
#endif
#if BOARD_HAVE_USART2
DEFINE_HWSERIAL(Serial2, 2);
#endif
#if BOARD_HAVE_USART3
DEFINE_HWSERIAL(Serial3, 3);
#endif
#if BOARD_HAVE_UART4
DEFINE_HWSERIAL_UART(Serial4, 4);
#endif
#if BOARD_HAVE_UART5
DEFINE_HWSERIAL_UART(Serial5, 5);
#endif
#if BOARD_HAVE_USART6
DEFINE_HWSERIAL_UART(Serial6, 6);
#endif
#else
#if BOARD_HAVE_USART1
DEFINE_HWSERIAL(Serial, 1);
#endif
#if BOARD_HAVE_USART2
DEFINE_HWSERIAL(Serial1, 2);
#endif
#if BOARD_HAVE_USART3
DEFINE_HWSERIAL(Serial2, 3);
#endif
#if BOARD_HAVE_UART4
DEFINE_HWSERIAL_UART(Serial3, 4);
#endif
#if BOARD_HAVE_UART5
DEFINE_HWSERIAL_UART(Serial4, 5);
#endif
#if BOARD_HAVE_USART6
DEFINE_HWSERIAL_UART(Serial5, 6);
#endif
#endif
#endif
HardwareSerial::HardwareSerial(usart_dev *usart_device,
uint8 tx_pin,
uint8 rx_pin) {
this->usart_device = usart_device;
this->tx_pin = tx_pin;
this->rx_pin = rx_pin;
}
/*
* Set up/tear down
*/
#if STM32_MCU_SERIES == STM32_SERIES_F1
/* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict
* on this GPIO bit. */
static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) {
if (dev != NULL) {
timer_set_mode(dev, ch, TIMER_DISABLED);
}
}
#elif (STM32_MCU_SERIES == STM32_SERIES_F2) || \
(STM32_MCU_SERIES == STM32_SERIES_F4)
#define disable_timer_if_necessary(dev, ch) ((void)0)
#else
#warning "Unsupported STM32 series; timer conflicts are possible"
#endif
void HardwareSerial::begin(uint32 baud)
{
begin(baud,SERIAL_8N1);
}
/*
* Roger Clark.
* Note. The config parameter is not currently used. This is a work in progress.
* Code needs to be written to set the config of the hardware serial control register in question.
*
*/
void HardwareSerial::begin(uint32 baud, uint8_t config)
{
// ASSERT(baud <= this->usart_device->max_baud);// Roger Clark. Assert doesn't do anything useful, we may as well save the space in flash and ram etc
if (baud > this->usart_device->max_baud) {
return;
}
const stm32_pin_info *txi = &PIN_MAP[this->tx_pin];
const stm32_pin_info *rxi = &PIN_MAP[this->rx_pin];
disable_timer_if_necessary(txi->timer_device, txi->timer_channel);
usart_init(this->usart_device);
usart_config_gpios_async(this->usart_device,
rxi->gpio_device, rxi->gpio_bit,
txi->gpio_device, txi->gpio_bit,
config);
usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud);
usart_enable(this->usart_device);
}
void HardwareSerial::end(void) {
usart_disable(this->usart_device);
}
/*
* I/O
*/
int HardwareSerial::read(void) {
if(usart_data_available(usart_device) > 0) {
return usart_getc(usart_device);
} else {
return -1;
}
}
int HardwareSerial::available(void) {
return usart_data_available(this->usart_device);
}
/* Roger Clark. Added function missing from LibMaple code */
int HardwareSerial::peek(void)
{
return usart_peek(this->usart_device);
}
int HardwareSerial::availableForWrite(void)
{
/* Roger Clark.
* Currently there isn't an output ring buffer, chars are sent straight to the hardware.
* so just return 1, meaning that 1 char can be written
* This will be slower than a ring buffer implementation, but it should at least work !
*/
return 1;
}
size_t HardwareSerial::write(unsigned char ch) {
usart_putc(this->usart_device, ch);
return 1;
}
/* edogaldo: Waits for the transmission of outgoing serial data to complete (Arduino 1.0 api specs) */
void HardwareSerial::flush(void) {
while(!rb_is_empty(this->usart_device->wb)); // wait for TX buffer empty
while(!((this->usart_device->regs->SR) & (1<<USART_SR_TC_BIT))); // wait for TC (Transmission Complete) flag set
}

View File

@@ -0,0 +1,224 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file wirish/include/wirish/HardwareSerial.h
* @brief Wirish serial port interface.
*/
#ifndef _WIRISH_HARDWARESERIAL_H_
#define _WIRISH_HARDWARESERIAL_H_
#include <libmaple/libmaple_types.h>
#include "Print.h"
#include "boards.h"
#include "Stream.h"
/*
* IMPORTANT:
*
* This class documented "by hand" (i.e., not using Doxygen) in the
* leaflabs-docs/ repository.
*
* If you alter the public HardwareSerial interface, you MUST update
* the documentation accordingly.
*/
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE))
#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif
struct usart_dev;
/* Roger Clark
*
* Added config defines from AVR
* Note. The values will need to be changed to match STM32 USART config register values, these are just place holders.
*/
// Define config for Serial.begin(baud, config);
// Note. STM32 doesn't support as many different Serial modes as AVR or SAM cores.
// The word legth bit M must be set when using parity bit.
#define SERIAL_8N1 0B00000000
#define SERIAL_8N2 0B00100000
#define SERIAL_9N1 0B00001000
#define SERIAL_9N2 0B00101000
#define SERIAL_8E1 0B00001010
#define SERIAL_8E2 0B00101010
/* not supported:
#define SERIAL_9E1 0B00001010
#define SERIAL_9E2 0B00101010
*/
#define SERIAL_8O1 0B00001011
#define SERIAL_8O2 0B00101011
/* not supported:
#define SERIAL_9O1 0B00001011
#define SERIAL_9O2 0B00101011
*/
/* Roger Clark
* Moved macros from hardwareSerial.cpp
*/
#define DEFINE_HWSERIAL(name, n) \
HardwareSerial name(USART##n, \
BOARD_USART##n##_TX_PIN, \
BOARD_USART##n##_RX_PIN)
#define DEFINE_HWSERIAL_UART(name, n) \
HardwareSerial name(UART##n, \
BOARD_USART##n##_TX_PIN, \
BOARD_USART##n##_RX_PIN)
/* Roger clark. Changed class inheritance from Print to Stream.
* Also added new functions for peek() and availableForWrite()
* Note. AvailableForWrite is only a stub function in the cpp
*/
class HardwareSerial : public Stream {
public:
HardwareSerial(struct usart_dev *usart_device,
uint8 tx_pin,
uint8 rx_pin);
/* Set up/tear down */
void begin(uint32 baud);
void begin(uint32 baud,uint8_t config);
void end();
virtual int available(void);
virtual int peek(void);
virtual int read(void);
int availableForWrite(void);
virtual void flush(void);
virtual size_t write(uint8_t);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write;
/* Pin accessors */
int txPin(void) { return this->tx_pin; }
int rxPin(void) { return this->rx_pin; }
operator bool() { return true; }
/* Escape hatch into libmaple */
/* FIXME [0.0.13] documentation */
struct usart_dev* c_dev(void) { return this->usart_device; }
private:
struct usart_dev *usart_device;
uint8 tx_pin;
uint8 rx_pin;
protected:
#if 0
volatile uint8_t * const _ubrrh;
volatile uint8_t * const _ubrrl;
volatile uint8_t * const _ucsra;
volatile uint8_t * const _ucsrb;
volatile uint8_t * const _ucsrc;
volatile uint8_t * const _udr;
// Has any byte been written to the UART since begin()
bool _written;
volatile rx_buffer_index_t _rx_buffer_head;
volatile rx_buffer_index_t _rx_buffer_tail;
volatile tx_buffer_index_t _tx_buffer_head;
volatile tx_buffer_index_t _tx_buffer_tail;
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd
// instruction.
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
#endif
};
#ifdef SERIAL_USB
#if BOARD_HAVE_USART1
extern HardwareSerial Serial1;
#endif
#if BOARD_HAVE_USART2
extern HardwareSerial Serial2;
#endif
#if BOARD_HAVE_USART3
extern HardwareSerial Serial3;
#endif
#if BOARD_HAVE_UART4
extern HardwareSerial Serial4;
#endif
#if BOARD_HAVE_UART5
extern HardwareSerial Serial5;
#endif
#if BOARD_HAVE_USART6
extern HardwareSerial Serial6;
#endif
#else
#if BOARD_HAVE_USART1
extern HardwareSerial Serial;
#endif
#if BOARD_HAVE_USART2
extern HardwareSerial Serial1;
#endif
#if BOARD_HAVE_USART3
extern HardwareSerial Serial2;
#endif
#if BOARD_HAVE_UART4
extern HardwareSerial Serial3;
#endif
#if BOARD_HAVE_UART5
extern HardwareSerial Serial4;
#endif
#if BOARD_HAVE_USART6
extern HardwareSerial Serial5;
#endif
#endif
#endif

View File

@@ -0,0 +1,192 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
#include "HardwareTimer.h"
#include <libmaple/rcc.h>
#include "ext_interrupts.h" // for noInterrupts(), interrupts()
#include "wirish_math.h"
#include <board/board.h> // for CYCLES_PER_MICROSECOND
// TODO [0.1.0] Remove deprecated pieces
/*
* Evil hack to infer this->dev from timerNum in the HardwareTimer
* constructor. See:
*
* http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
* http://yosefk.com/c++fqa/function.html#fqa-33.2
*/
extern "C" {
static timer_dev **this_devp;
static rcc_clk_id this_id;
static void set_this_dev(timer_dev *dev) {
if (dev->clk_id == this_id) {
*this_devp = dev;
}
}
}
/*
* HardwareTimer routines
*/
HardwareTimer::HardwareTimer(uint8 timerNum) {
rcc_clk_id timerID = (rcc_clk_id)(RCC_TIMER1 + (timerNum - 1));
this->dev = NULL;
noInterrupts(); // Hack to ensure we're the only ones using
// set_this_dev() and friends. TODO: use a lock.
this_id = timerID;
this_devp = &this->dev;
timer_foreach(set_this_dev);
interrupts();
ASSERT(this->dev != NULL);
}
void HardwareTimer::pause(void) {
timer_pause(this->dev);
}
void HardwareTimer::resume(void) {
timer_resume(this->dev);
}
uint32 HardwareTimer::getPrescaleFactor(void) {
return timer_get_prescaler(this->dev) + 1;
}
void HardwareTimer::setPrescaleFactor(uint32 factor) {
timer_set_prescaler(this->dev, (uint16)(factor - 1));
}
uint16 HardwareTimer::getOverflow() {
return timer_get_reload(this->dev);
}
void HardwareTimer::setOverflow(uint16 val) {
timer_set_reload(this->dev, val);
}
uint16 HardwareTimer::getCount(void) {
return timer_get_count(this->dev);
}
void HardwareTimer::setCount(uint16 val) {
uint16 ovf = this->getOverflow();
timer_set_count(this->dev, min(val, ovf));
}
#define MAX_RELOAD ((1 << 16) - 1)
uint16 HardwareTimer::setPeriod(uint32 microseconds) {
// Not the best way to handle this edge case?
if (!microseconds) {
this->setPrescaleFactor(1);
this->setOverflow(1);
return this->getOverflow();
}
uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND;
uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1);
uint16 overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler);
this->setPrescaleFactor(prescaler);
this->setOverflow(overflow);
return overflow;
}
void HardwareTimer::setMode(int channel, timer_mode mode) {
timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode);
}
uint16 HardwareTimer::getCompare(int channel) {
return timer_get_compare(this->dev, (uint8)channel);
}
void HardwareTimer::setCompare(int channel, uint16 val) {
uint16 ovf = this->getOverflow();
timer_set_compare(this->dev, (uint8)channel, min(val, ovf));
}
void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) {
timer_attach_interrupt(this->dev, (uint8)channel, handler);
}
void HardwareTimer::detachInterrupt(int channel) {
timer_detach_interrupt(this->dev, (uint8)channel);
}
void HardwareTimer::enableDMA(int channel) {
timer_dma_enable_req(this->dev, (uint8)channel);
}
void HardwareTimer::disableDMA(int channel) {
timer_dma_disable_req(this->dev, (uint8)channel);
}
void HardwareTimer::refresh(void) {
timer_generate_update(this->dev);
}
void HardwareTimer::setMasterModeTrGo(uint32_t mode) {
this->dev->regs.bas->CR2 &= ~TIMER_CR2_MMS;
this->dev->regs.bas->CR2 |= mode;
}
/* CARLOS Changes to add encoder mode.*/
//direction of movement. (to be better described).
uint8 HardwareTimer::getDirection(){
return get_direction(this->dev);
}
//set if the encoder will count edges on one, which or both channels.
void HardwareTimer::setEdgeCounting(uint32 counting) {
(dev->regs).gen->SMCR = counting;//TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on
}
uint8 HardwareTimer::getEdgeCounting() {
return (dev->regs).gen->SMCR;
}
//set the polarity of counting... not sure how interesting this is..
void HardwareTimer::setPolarity(){}
/* -- Deprecated predefined instances -------------------------------------- */
HardwareTimer Timer1(1);
HardwareTimer Timer2(2);
HardwareTimer Timer3(3);
HardwareTimer Timer4(4);
#ifdef STM32_HIGH_DENSITY
HardwareTimer Timer5(5);
HardwareTimer Timer6(6);
HardwareTimer Timer7(7);
HardwareTimer Timer8(8);
#endif

View File

@@ -0,0 +1,383 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @brief Wirish timer class.
*/
#ifndef _WIRISH_HARDWARETIMER_H_
#define _WIRISH_HARDWARETIMER_H_
// TODO [0.1.0] Remove deprecated pieces, pick a better API
#include <libmaple/timer.h>
/** Timer mode. */
typedef timer_mode TimerMode;
//CARLOS
//defines for the ENCODER mode.
/**
* @brief Interface to one of the 16-bit timer peripherals.
*/
class HardwareTimer {
private:
timer_dev *dev;
public:
/**
* @brief Construct a new HardwareTimer instance.
* @param timerNum number of the timer to control.
*/
HardwareTimer(uint8 timerNum);
/**
* @brief Stop the counter, without affecting its configuration.
*
* @see HardwareTimer::resume()
*/
void pause(void);
/**
* @brief Resume a paused timer, without affecting its configuration.
*
* The timer will resume counting and firing interrupts as
* appropriate.
*
* Note that there is some function call overhead associated with
* using this method, so using it in concert with
* HardwareTimer::pause() is not a robust way to align multiple
* timers to the same count value.
*
* @see HardwareTimer::pause()
*/
void resume(void);
/**
* @brief Get the timer's prescale factor.
* @return Timer prescaler, from 1 to 65,536.
* @see HardwareTimer::setPrescaleFactor()
*/
uint32 getPrescaleFactor();
/**
* @brief Set the timer's prescale factor.
*
* The new value won't take effect until the next time the counter
* overflows. You can force the counter to reset using
* HardwareTimer::refresh().
*
* @param factor The new prescale value to set, from 1 to 65,536.
* @see HardwareTimer::refresh()
*/
void setPrescaleFactor(uint32 factor);
/**
* @brief Get the timer overflow value.
* @see HardwareTimer::setOverflow()
*/
uint16 getOverflow();
/**
* @brief Set the timer overflow (or "reload") value.
*
* The new value won't take effect until the next time the counter
* overflows. You can force the counter to reset using
* HardwareTimer::refresh().
*
* @param val The new overflow value to set
* @see HardwareTimer::refresh()
*/
void setOverflow(uint16 val);
/**
* @brief Get the current timer count.
*
* @return The timer's current count value
*/
uint16 getCount(void);
/**
* @brief Set the current timer count.
*
* @param val The new count value to set. If this value exceeds
* the timer's overflow value, it is truncated to the
* overflow value.
*/
void setCount(uint16 val);
/**
* @brief Set the timer's period in microseconds.
*
* Configures the prescaler and overflow values to generate a timer
* reload with a period as close to the given number of
* microseconds as possible.
*
* @param microseconds The desired period of the timer. This must be
* greater than zero.
* @return The new overflow value.
*/
uint16 setPeriod(uint32 microseconds);
/**
* @brief Configure a timer channel's mode.
* @param channel Timer channel, from 1 to 4
* @param mode Mode to set
*/
void setMode(int channel, timer_mode mode);
/**
* @brief Get the compare value for the given channel.
* @see HardwareTimer::setCompare()
*/
uint16 getCompare(int channel);
/**
* @brief Set the compare value for the given channel.
*
* @param channel the channel whose compare to set, from 1 to 4.
* @param compare The compare value to set. If greater than this
* timer's overflow value, it will be truncated to
* the overflow value.
*
* @see timer_mode
* @see HardwareTimer::setMode()
* @see HardwareTimer::attachInterrupt()
*/
void setCompare(int channel, uint16 compare);
/**
* @brief Attach an interrupt handler to the given channel.
*
* This interrupt handler will be called when the timer's counter
* reaches the given channel compare value.
*
* @param channel the channel to attach the ISR to, from 0 to 4.
* Channel 0 is for overflow interrupt (update interrupt).
* @param handler The ISR to attach to the given channel.
* @see voidFuncPtr
*/
void attachInterrupt(int channel, voidFuncPtr handler);
/**
* @brief Remove the interrupt handler attached to the given
* channel, if any.
*
* The handler will no longer be called by this timer.
*
* @param channel the channel whose interrupt to detach, from 0 to 4.
* Channel 0 is for overflow interrupt (update interrupt).
* @see HardwareTimer::attachInterrupt()
*/
void detachInterrupt(int channel);
/**
* @brief Reset the counter, and update the prescaler and overflow
* values.
*
* This will reset the counter to 0 in upcounting mode (the
* default). It will also update the timer's prescaler and
* overflow, if you have set them up to be changed using
* HardwareTimer::setPrescaleFactor() or
* HardwareTimer::setOverflow().
*
* @see HardwareTimer::setPrescaleFactor()
* @see HardwareTimer::setOverflow()
*/
void refresh(void);
// SYFRE
/**
* @brief Set the Master mode TRGO signal
* These bits allow to select the information to be sent in master mode to slave timers for
* synchronization (TRGO).
* mode:
* TIMER_CR2_MMS_RESET
* TIMER_CR2_MMS_ENABLE
* TIMER_CR2_MMS_UPDATE
* TIMER_CR2_MMS_COMPARE_PULSE
* TIMER_CR2_MMS_COMPARE_OC1REF
* TIMER_CR2_MMS_COMPARE_OC2REF
* TIMER_CR2_MMS_COMPARE_OC3REF
* TIMER_CR2_MMS_COMPARE_OC4REF
*/
void setMasterModeTrGo(uint32_t mode);
//CARLOS.
/*
added these functions to make sense for the encoder mode.
*/
//direction of movement. (to be better described).
uint8 getDirection();
//set if the encoder will count edges on one, which or both channels.
void setEdgeCounting(uint32 counting);
uint8 getEdgeCounting(); //not sure if needed.
//set the polarity of counting... not sure how interesting this is..
void setPolarity();
//add the filtering definition for the input channel.
/* Escape hatch */
/**
* @brief Enable/disable DMA request for the input channel.
*/
void enableDMA(int channel);
void disableDMA(int channel);
/**
* @brief Get a pointer to the underlying libmaple timer_dev for
* this HardwareTimer instance.
*/
timer_dev* c_dev(void) { return this->dev; }
/* -- The rest of this file is deprecated. --------------------------------- */
/** @brief Deprecated; use setMode(channel, mode) instead. */
void setChannelMode(int channel, timer_mode mode) {
setMode(channel, mode);
}
/** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */
void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); }
/** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */
void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); }
/** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */
void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); }
/** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */
void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); }
/** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */
uint16 getCompare1() { return getCompare(TIMER_CH1); }
/** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */
uint16 getCompare2() { return getCompare(TIMER_CH2); }
/** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */
uint16 getCompare3() { return getCompare(TIMER_CH3); }
/** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */
uint16 getCompare4() { return getCompare(TIMER_CH4); }
/** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */
void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); }
/** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */
void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); }
/** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */
void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); }
/** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */
void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); }
/** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */
void attachCompare1Interrupt(voidFuncPtr handler) {
attachInterrupt(TIMER_CH1, handler);
}
/** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */
void attachCompare2Interrupt(voidFuncPtr handler) {
attachInterrupt(TIMER_CH2, handler);
}
/** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */
void attachCompare3Interrupt(voidFuncPtr handler) {
attachInterrupt(TIMER_CH3, handler);
}
/** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */
void attachCompare4Interrupt(voidFuncPtr handler) {
attachInterrupt(TIMER_CH4, handler);
}
/** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */
void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); }
/** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */
void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); }
/** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */
void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); }
/** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */
void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); }
/** @brief Deprecated; use refresh() instead. */
void generateUpdate(void) { refresh(); }
};
/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */
#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer1;
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer2;
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer3;
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer4;
#if (STM32_MCU_SERIES == STM32_SERIES_F1) && defined(STM32_HIGH_DENSITY)
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer5;
/**
* @brief Deprecated.
*
* Pre-instantiated timer.
*/
extern HardwareTimer Timer8;
#endif
#endif

View File

@@ -0,0 +1,129 @@
/*
IPAddress.cpp - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <IPAddress.h>
#include <Print.h>
IPAddress::IPAddress()
{
_address.dword = 0;
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address.bytes[0] = first_octet;
_address.bytes[1] = second_octet;
_address.bytes[2] = third_octet;
_address.bytes[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address)
{
_address.dword = address;
}
IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));
}
bool IPAddress::fromString(const char *address)
{
// TODO: add support for "a", "a.b", "a.b.c" formats
uint16_t acc = 0; // Accumulator
uint8_t dots = 0;
while (*address)
{
char c = *address++;
if (c >= '0' && c <= '9')
{
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
}
else if (c == '.')
{
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
}
else
{
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}
IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));
return *this;
}
IPAddress& IPAddress::operator=(uint32_t address)
{
_address.dword = address;
return *this;
}
bool IPAddress::operator==(const uint8_t* addr) const
{
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
}
size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address.bytes[i], DEC);
n += p.print('.');
}
n += p.print(_address.bytes[3], DEC);
return n;
}
String IPAddress::toString()
{
String str = String(_address.bytes[0]);
str += ".";
str += String(_address.bytes[1]);
str += ".";
str += String(_address.bytes[2]);
str += ".";
str += String(_address.bytes[3]);
return str;
}

View File

@@ -0,0 +1,80 @@
/*
IPAddress.h - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef IPAddress_h
#define IPAddress_h
#include <stdint.h>
#include <WString.h>
#include <Printable.h>
// A class to make it easier to handle and pass around IP addresses
class IPAddress : public Printable {
private:
union {
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _address;
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address.bytes; };
public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);
bool fromString(const char *address);
bool fromString(const String &address) { return fromString(address.c_str()); }
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t() const { return _address.dword; };
bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
bool operator==(const uint8_t* addr) const;
// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address.bytes[index]; };
uint8_t& operator[](int index) { return _address.bytes[index]; };
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
virtual size_t printTo(Print& p) const;
String toString();
friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
};
const IPAddress INADDR_NONE(0,0,0,0);
#endif

View File

@@ -0,0 +1,322 @@
/*
* Print.cpp - Base class that provides print() and println()
* Copyright (c) 2008 David A. Mellis. All right reserved.
* Copyright (c) 2011 LeafLabs, LLC.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Modified 23 November 2006 by David A. Mellis
* Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com>
*/
#include "Print.h"
#include "wirish_math.h"
#include "limits.h"
#ifndef LLONG_MAX
/*
* Note:
*
* At time of writing (12 April 2011), the limits.h that came with the
* newlib we distributed didn't include LLONG_MAX. Because we're
* staying away from using templates (see /notes/coding_standard.rst,
* "Language Features and Compiler Extensions"), this value was
* copy-pasted from a println() of the value
*
* std::numeric_limits<long long>::max().
*/
#define LLONG_MAX 9223372036854775807LL
#endif
/*
* Public methods
*/
size_t Print::write(const char *str) {
size_t n = 0;
while (*str) {
write(*str++);
n++;
}
return n;
}
size_t Print::write(const void *buffer, uint32 size) {
size_t n = 0;
uint8 *ch = (uint8*)buffer;
while (size--) {
write(*ch++);
n++;
}
return n;
}
size_t Print::print(uint8 b, int base) {
return print((uint64)b, base);
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(char c) {
return write(c);
}
size_t Print::print(const char str[]) {
return write(str);
}
size_t Print::print(int n, int base) {
return print((long long)n, base);
}
size_t Print::print(unsigned int n, int base) {
return print((unsigned long long)n, base);
}
size_t Print::print(long n, int base) {
return print((long long)n, base);
}
size_t Print::print(unsigned long n, int base) {
return print((unsigned long long)n, base);
}
size_t Print::print(long long n, int base) {
if (n < 0) {
print('-');
n = -n;
}
return printNumber(n, base);
}
size_t Print::print(unsigned long long n, int base) {
return printNumber(n, base);
}
size_t Print::print(double n, int digits) {
return printFloat(n, digits);
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
return print(reinterpret_cast<const char *>(ifsh));
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
size_t n = print('\r');
n += print('\n');
return n;
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(char c) {
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(const char c[]) {
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(uint8 b, int base) {
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int n, int base) {
size_t s = print(n, base);
s += println();
return s;
}
size_t Print::println(unsigned int n, int base) {
size_t s = print(n, base);
s += println();
return s;
}
size_t Print::println(long n, int base) {
size_t s = print((long long)n, base);
s += println();
return s;
}
size_t Print::println(unsigned long n, int base) {
size_t s = print((unsigned long long)n, base);
s += println();
return s;
}
size_t Print::println(long long n, int base) {
size_t s = print(n, base);
s += println();
return s;
}
size_t Print::println(unsigned long long n, int base) {
size_t s = print(n, base);
s += println();
return s;
}
size_t Print::println(double n, int digits) {
size_t s = print(n, digits);
s += println();
return s;
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
#ifdef SUPPORTS_PRINTF
#include <stdio.h>
#include <stdarg.h>
// Work in progress to support printf.
// Need to implement stream FILE to write individual chars to chosen serial port
int Print::printf (__const char *__restrict __format, ...)
{
FILE *__restrict __stream;
int ret_status = 0;
va_list args;
va_start(args,__format);
ret_status = vfprintf(__stream, __format, args);
va_end(args);
return ret_status;
}
#endif
/*
* Private methods
*/
size_t Print::printNumber(unsigned long long n, uint8 base) {
unsigned char buf[CHAR_BIT * sizeof(long long)];
unsigned long i = 0;
size_t s=0;
if (n == 0) {
print('0');
return 1;
}
while (n > 0) {
buf[i++] = n % base;
n /= base;
}
for (; i > 0; i--) {
s += print((char)(buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
}
return s;
}
/* According to snprintf(),
*
* nextafter((double)numeric_limits<long long>::max(), 0.0) ~= 9.22337e+18
*
* This slightly smaller value was picked semi-arbitrarily. */
#define LARGE_DOUBLE_TRESHOLD (9.1e18)
/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS.
*
* This implementation is meant to be simple and not occupy too much
* code size. However, printing floating point values accurately is a
* subtle task, best left to a well-tested library function.
*
* See Steele and White 2003 for more details:
*
* http://kurtstephens.com/files/p372-steele.pdf
*/
size_t Print::printFloat(double number, uint8 digits) {
size_t s=0;
// Hackish fail-fast behavior for large-magnitude doubles
if (abs(number) >= LARGE_DOUBLE_TRESHOLD) {
if (number < 0.0) {
s=print('-');
}
s+=print("<large double>");
return s;
}
// Handle negative numbers
if (number < 0.0) {
s+=print('-');
number = -number;
}
// Simplistic rounding strategy so that e.g. print(1.999, 2)
// prints as "2.00"
double rounding = 0.5;
for (uint8 i = 0; i < digits; i++) {
rounding /= 10.0;
}
number += rounding;
// Extract the integer part of the number and print it
long long int_part = (long long)number;
double remainder = number - int_part;
s+=print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
s+=print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0) {
remainder *= 10.0;
int to_print = (int)remainder;
s+=print(to_print);
remainder -= to_print;
}
return s;
}

View File

@@ -0,0 +1,88 @@
/*
* Print.h - Base class that provides print() and println()
* Copyright (c) 2008 David A. Mellis. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com>
*/
#ifndef _WIRISH_PRINT_H_
#define _WIRISH_PRINT_H_
#include <libmaple/libmaple_types.h>
#include "WString.h"
#include "Printable.h"
enum {
BIN = 2,
OCT = 8,
DEC = 10,
HEX = 16
};
class Print {
public:
virtual size_t write(uint8 ch) = 0;
virtual size_t write(const char *str);
virtual size_t write(const void *buf, uint32 len);
size_t print(const String &);
size_t print(char);
size_t print(const char[]);
size_t print(uint8, int=DEC);
size_t print(int, int=DEC);
size_t print(unsigned int, int=DEC);
size_t print(long, int=DEC);
size_t print(unsigned long, int=DEC);
size_t print(long long, int=DEC);
size_t print(unsigned long long, int=DEC);
size_t print(double, int=2);
size_t print(const __FlashStringHelper *);
size_t print(const Printable&);
size_t println(void);
size_t println(const String &s);
size_t println(char);
size_t println(const char[]);
size_t println(uint8, int=DEC);
size_t println(int, int=DEC);
size_t println(unsigned int, int=DEC);
size_t println(long, int=DEC);
size_t println(unsigned long, int=DEC);
size_t println(long long, int=DEC);
size_t println(unsigned long long, int=DEC);
size_t println(double, int=2);
size_t println(const __FlashStringHelper *);
size_t println(const Printable&);
#ifdef SUPPORTS_PRINTF
// Roger Clark. Work in progress to add printf support
int printf(const char * format, ...);
#endif
Print() : write_error(0) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
protected:
void setWriteError(int err = 1) { write_error = err; }
private:
int write_error;
size_t printNumber(unsigned long long, uint8);
size_t printFloat(double, uint8);
};
#endif

View File

@@ -0,0 +1,40 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include <stdlib.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif

View File

@@ -0,0 +1,30 @@
/*
Server.h - Base class that provides Server
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef server_h
#define server_h
#include "Print.h"
class Server : public Print {
public:
virtual void begin() =0;
};
#endif

View File

@@ -0,0 +1,335 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
*/
#include "Arduino.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
// private method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
do {
c = read();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// private method to peek stream with timeout
int Stream::timedPeek()
{
int c;
_startMillis = millis();
do {
c = peek();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
int c;
while (1) {
c = timedPeek();
if (c < 0) return c; // timeout
if (c == '-') return c;
if (c >= '0' && c <= '9') return c;
read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, (char*)"");
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;
if( *target == 0)
return true; // return true if target is a null string
while( (c = timedRead()) > 0){
if(c != target[index])
index = 0; // reset index if any char does not match
if( c == target[index]){
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen){ // return true if all chars in the target match
return true;
}
}
if(termLen > 0 && c == terminator[termIndex]){
if(++termIndex >= termLen)
return false; // return false if terminate string found before target string
}
else
termIndex = 0;
}
return false;
}
// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}
// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;
c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == skipChar );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat()
{
return parseFloat(NO_SKIP_CHAR);
}
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar){
boolean isNegative = false;
boolean isFraction = false;
long value = 0;
int c;
float fraction = 1.0;
c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == skipChar)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1;
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length) {
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;
count++;
}
return count;
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
if (length < 1) return 0;
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c < 0 || c == terminator) break;
*buffer++ = (char)c;
index++;
}
return index; // return number of characters, not including null terminator
}
String Stream::readString()
{
String ret;
int c = timedRead();
while (c >= 0)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
String Stream::readStringUntil(char terminator)
{
String ret;
int c = timedRead();
while (c >= 0 && c != terminator)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
if (t->len <= 0)
return t - targets;
}
while (1) {
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
// the simple case is if we match, deal with that first.
if (c == t->str[t->index]) {
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do {
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0) {
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i) {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index) {
t->index++;
break;
}
// otherwise we just try the next index
} while (t->index);
}
}
// unreachable
return -1;
}

View File

@@ -0,0 +1,115 @@
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/
#ifndef Stream_h
#define Stream_h
#include <inttypes.h>
#include "Print.h"
// compatability macros for testing
/*
#define getInt() parseInt()
#define getInt(skipChar) parseInt(skipchar)
#define getFloat() parseFloat()
#define getFloat(skipChar) parseFloat(skipChar)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
class Stream : public Print
{
protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout
int timedPeek(); // private method to peek stream with timeout
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;
Stream() {_timeout=1000;}
// parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); }
// returns true if target string is found, false if timed out (see setTimeout)
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
// returns true if target string is found, false if timed out
bool find(char target) { return find (&target, 1); }
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
long parseInt(); // returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// integer is terminated by the first character that is not a digit.
float parseFloat(); // float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
String readStringUntil(char terminator);
protected:
long parseInt(char skipChar); // as above but the given skipChar is ignored
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float parseFloat(char skipChar); // as above but the given skipChar is ignored
struct MultiTarget {
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#endif

View File

@@ -0,0 +1,88 @@
/*
* Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* bjoern@cs.stanford.edu 12/30/2008
*/
#ifndef udp_h
#define udp_h
#include <Stream.h>
#include <IPAddress.h>
class UDP : public Stream {
public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop() =0; // Finish with the UDP socket
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() =0;
// Number of bytes remaining in the current packet
virtual int available() =0;
// Read a single byte from the current packet
virtual int read() =0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) =0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() =0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
#endif

View File

@@ -0,0 +1,180 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Character_h
#define Character_h
#include <ctype.h>
#ifdef __cplusplus
extern "C" {
#endif
// WCharacter.h prototypes
#if defined ( __GNUC__ )
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
inline boolean isAlpha(int c) __attribute__((always_inline));
inline boolean isAscii(int c) __attribute__((always_inline));
inline boolean isWhitespace(int c) __attribute__((always_inline));
inline boolean isControl(int c) __attribute__((always_inline));
inline boolean isDigit(int c) __attribute__((always_inline));
inline boolean isGraph(int c) __attribute__((always_inline));
inline boolean isLowerCase(int c) __attribute__((always_inline));
inline boolean isPrintable(int c) __attribute__((always_inline));
inline boolean isPunct(int c) __attribute__((always_inline));
inline boolean isSpace(int c) __attribute__((always_inline));
inline boolean isUpperCase(int c) __attribute__((always_inline));
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
#elif defined ( __ICCARM__ )
#endif
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline boolean isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline boolean isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline boolean isAscii(int c)
{
/* return ( isascii(c) == 0 ? false : true); */
return ( (c & ~0x7f) != 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline boolean isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline boolean isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline boolean isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline boolean isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline boolean isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline boolean isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline boolean isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline boolean isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline boolean isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline boolean isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
/* return toascii (c); */
return (c & 0x7f);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,35 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
#ifndef _WIRISH_WPROGRAM_H_
#define _WIRISH_WPROGRAM_H_
#include <wirish.h>
void setup();
void loop();
#endif

View File

@@ -0,0 +1,747 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "WString.h"
#include "itoa.h"
#include "avr/dtostrf.h"
/*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
String::String(const String &value)
{
init();
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
String::String(unsigned char value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base);
*this = buf;
}
String::String(int value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base);
*this = buf;
}
String::String(unsigned int value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base);
*this = buf;
}
String::String(long value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base);
*this = buf;
}
String::String(unsigned long value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base);
*this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::String(double value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::~String()
{
free(buffer);
}
/*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
void String::invalidate(void)
{
if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (PGM_P)pstr);
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void String::move(String &rhs)
{
if (buffer) {
if (rhs && capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}
String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{
return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, cstr);
len = newlen;
return 1;
}
unsigned char String::concat(const char *cstr)
{
if (!cstr) return 0;
return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return concat(buf, 1);
}
unsigned char String::concat(unsigned char num)
{
char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(float num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(double num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(const __FlashStringHelper * str)
{
if (!str) return 0;
int length = strlen_P((const char *) str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy_P(buffer + len, (const char *) str);
len = newlen;
return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}
char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}
/*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{
return indexOf(c, 0);
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) return -1;
const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
return temp - buffer;
}
int String::indexOf(const String &s2) const
{
return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
buffer[fromIndex + 1] = tempchar;
if (temp == NULL) return -1;
return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left >= len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}
/*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
}
void String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
}
void String::remove(unsigned int index){
// Pass the biggest integer as the count. The remove method
// below will take care of truncating it at the end of the
// string.
remove(index, (unsigned int)-1);
}
void String::remove(unsigned int index, unsigned int count){
if (index >= len) { return; }
if (count <= 0) { return; }
if (count > len - index) { count = len - index; }
char *writeTo = buffer + index;
len = len - count;
strncpy(writeTo, buffer + index + count,len - index);
buffer[len] = 0;
}
void String::toLowerCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
}
void String::toUpperCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
}
void String::trim(void)
{
if (!buffer || len == 0) return;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}
float String::toFloat(void) const
{
if (buffer) return float(atof(buffer));
return 0;
}

View File

@@ -0,0 +1,228 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String
{
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base=10);
explicit String(int, unsigned char base=10);
explicit String(unsigned int, unsigned char base=10);
explicit String(long, unsigned char base=10);
explicit String(unsigned long, unsigned char base=10);
explicit String(float, unsigned char decimalPlaces=2);
explicit String(double, unsigned char decimalPlaces=2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
String & operator += (const char *cstr) {concat(cstr); return (*this);}
String & operator += (char c) {concat(c); return (*this);}
String & operator += (unsigned char num) {concat(num); return (*this);}
String & operator += (int num) {concat(num); return (*this);}
String & operator += (unsigned int num) {concat(num); return (*this);}
String & operator += (long num) {concat(num); return (*this);}
String & operator += (unsigned long num) {concat(num); return (*this);}
String & operator += (float num) {concat(num); return (*this);}
String & operator += (double num) {concat(num); return (*this);}
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; }
char* begin() { return buffer; }
char* end() { return buffer + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void move(String &rhs);
#endif
};
class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num) : String(num) {}
StringSumHelper(double num) : String(num) {}
};
#endif // __cplusplus
#endif // String_class_h

View File

@@ -0,0 +1,29 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@bug.st>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
char fmt[20];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(sout, fmt, val);
return sout;
}

View File

@@ -0,0 +1,29 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@bug.st>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,44 @@
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1
#include <inttypes.h>
#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)
#define _SFR_BYTE(n) (n)
typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define strstr_P(a, b) strstr((a), (b))
#define strlen_P(a) strlen((a))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#endif

View File

@@ -0,0 +1,579 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @brief BIT[n] and binary literal defines, for Arduino
* compatibility.
*/
#ifndef _WIRISH_BIT_CONSTANTS_H_
#define _WIRISH_BIT_CONSTANTS_H_
#define BIT0 (1 << 0)
#define BIT1 (1 << 1)
#define BIT2 (1 << 2)
#define BIT3 (1 << 3)
#define BIT4 (1 << 4)
#define BIT5 (1 << 5)
#define BIT6 (1 << 6)
#define BIT7 (1 << 7)
#define BIT8 (1 << 8)
#define BIT9 (1 << 9)
#define BIT10 (1 << 10)
#define BIT11 (1 << 11)
#define BIT12 (1 << 12)
#define BIT13 (1 << 13)
#define BIT14 (1 << 14)
#define BIT15 (1 << 15)
#define BIT16 (1 << 16)
#define BIT17 (1 << 17)
#define BIT18 (1 << 18)
#define BIT19 (1 << 19)
#define BIT20 (1 << 20)
#define BIT21 (1 << 21)
#define BIT22 (1 << 22)
#define BIT23 (1 << 23)
#define BIT24 (1 << 24)
#define BIT25 (1 << 25)
#define BIT26 (1 << 26)
#define BIT27 (1 << 27)
#define BIT28 (1 << 28)
#define BIT29 (1 << 29)
#define BIT30 (1 << 30)
#define BIT31 (1 << 31)
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
#define B11 3
#define B011 3
#define B0011 3
#define B00011 3
#define B000011 3
#define B0000011 3
#define B00000011 3
#define B100 4
#define B0100 4
#define B00100 4
#define B000100 4
#define B0000100 4
#define B00000100 4
#define B101 5
#define B0101 5
#define B00101 5
#define B000101 5
#define B0000101 5
#define B00000101 5
#define B110 6
#define B0110 6
#define B00110 6
#define B000110 6
#define B0000110 6
#define B00000110 6
#define B111 7
#define B0111 7
#define B00111 7
#define B000111 7
#define B0000111 7
#define B00000111 7
#define B1000 8
#define B01000 8
#define B001000 8
#define B0001000 8
#define B00001000 8
#define B1001 9
#define B01001 9
#define B001001 9
#define B0001001 9
#define B00001001 9
#define B1010 10
#define B01010 10
#define B001010 10
#define B0001010 10
#define B00001010 10
#define B1011 11
#define B01011 11
#define B001011 11
#define B0001011 11
#define B00001011 11
#define B1100 12
#define B01100 12
#define B001100 12
#define B0001100 12
#define B00001100 12
#define B1101 13
#define B01101 13
#define B001101 13
#define B0001101 13
#define B00001101 13
#define B1110 14
#define B01110 14
#define B001110 14
#define B0001110 14
#define B00001110 14
#define B1111 15
#define B01111 15
#define B001111 15
#define B0001111 15
#define B00001111 15
#define B10000 16
#define B010000 16
#define B0010000 16
#define B00010000 16
#define B10001 17
#define B010001 17
#define B0010001 17
#define B00010001 17
#define B10010 18
#define B010010 18
#define B0010010 18
#define B00010010 18
#define B10011 19
#define B010011 19
#define B0010011 19
#define B00010011 19
#define B10100 20
#define B010100 20
#define B0010100 20
#define B00010100 20
#define B10101 21
#define B010101 21
#define B0010101 21
#define B00010101 21
#define B10110 22
#define B010110 22
#define B0010110 22
#define B00010110 22
#define B10111 23
#define B010111 23
#define B0010111 23
#define B00010111 23
#define B11000 24
#define B011000 24
#define B0011000 24
#define B00011000 24
#define B11001 25
#define B011001 25
#define B0011001 25
#define B00011001 25
#define B11010 26
#define B011010 26
#define B0011010 26
#define B00011010 26
#define B11011 27
#define B011011 27
#define B0011011 27
#define B00011011 27
#define B11100 28
#define B011100 28
#define B0011100 28
#define B00011100 28
#define B11101 29
#define B011101 29
#define B0011101 29
#define B00011101 29
#define B11110 30
#define B011110 30
#define B0011110 30
#define B00011110 30
#define B11111 31
#define B011111 31
#define B0011111 31
#define B00011111 31
#define B100000 32
#define B0100000 32
#define B00100000 32
#define B100001 33
#define B0100001 33
#define B00100001 33
#define B100010 34
#define B0100010 34
#define B00100010 34
#define B100011 35
#define B0100011 35
#define B00100011 35
#define B100100 36
#define B0100100 36
#define B00100100 36
#define B100101 37
#define B0100101 37
#define B00100101 37
#define B100110 38
#define B0100110 38
#define B00100110 38
#define B100111 39
#define B0100111 39
#define B00100111 39
#define B101000 40
#define B0101000 40
#define B00101000 40
#define B101001 41
#define B0101001 41
#define B00101001 41
#define B101010 42
#define B0101010 42
#define B00101010 42
#define B101011 43
#define B0101011 43
#define B00101011 43
#define B101100 44
#define B0101100 44
#define B00101100 44
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51
#define B00110011 51
#define B110100 52
#define B0110100 52
#define B00110100 52
#define B110101 53
#define B0110101 53
#define B00110101 53
#define B110110 54
#define B0110110 54
#define B00110110 54
#define B110111 55
#define B0110111 55
#define B00110111 55
#define B111000 56
#define B0111000 56
#define B00111000 56
#define B111001 57
#define B0111001 57
#define B00111001 57
#define B111010 58
#define B0111010 58
#define B00111010 58
#define B111011 59
#define B0111011 59
#define B00111011 59
#define B111100 60
#define B0111100 60
#define B00111100 60
#define B111101 61
#define B0111101 61
#define B00111101 61
#define B111110 62
#define B0111110 62
#define B00111110 62
#define B111111 63
#define B0111111 63
#define B00111111 63
#define B1000000 64
#define B01000000 64
#define B1000001 65
#define B01000001 65
#define B1000010 66
#define B01000010 66
#define B1000011 67
#define B01000011 67
#define B1000100 68
#define B01000100 68
#define B1000101 69
#define B01000101 69
#define B1000110 70
#define B01000110 70
#define B1000111 71
#define B01000111 71
#define B1001000 72
#define B01001000 72
#define B1001001 73
#define B01001001 73
#define B1001010 74
#define B01001010 74
#define B1001011 75
#define B01001011 75
#define B1001100 76
#define B01001100 76
#define B1001101 77
#define B01001101 77
#define B1001110 78
#define B01001110 78
#define B1001111 79
#define B01001111 79
#define B1010000 80
#define B01010000 80
#define B1010001 81
#define B01010001 81
#define B1010010 82
#define B01010010 82
#define B1010011 83
#define B01010011 83
#define B1010100 84
#define B01010100 84
#define B1010101 85
#define B01010101 85
#define B1010110 86
#define B01010110 86
#define B1010111 87
#define B01010111 87
#define B1011000 88
#define B01011000 88
#define B1011001 89
#define B01011001 89
#define B1011010 90
#define B01011010 90
#define B1011011 91
#define B01011011 91
#define B1011100 92
#define B01011100 92
#define B1011101 93
#define B01011101 93
#define B1011110 94
#define B01011110 94
#define B1011111 95
#define B01011111 95
#define B1100000 96
#define B01100000 96
#define B1100001 97
#define B01100001 97
#define B1100010 98
#define B01100010 98
#define B1100011 99
#define B01100011 99
#define B1100100 100
#define B01100100 100
#define B1100101 101
#define B01100101 101
#define B1100110 102
#define B01100110 102
#define B1100111 103
#define B01100111 103
#define B1101000 104
#define B01101000 104
#define B1101001 105
#define B01101001 105
#define B1101010 106
#define B01101010 106
#define B1101011 107
#define B01101011 107
#define B1101100 108
#define B01101100 108
#define B1101101 109
#define B01101101 109
#define B1101110 110
#define B01101110 110
#define B1101111 111
#define B01101111 111
#define B1110000 112
#define B01110000 112
#define B1110001 113
#define B01110001 113
#define B1110010 114
#define B01110010 114
#define B1110011 115
#define B01110011 115
#define B1110100 116
#define B01110100 116
#define B1110101 117
#define B01110101 117
#define B1110110 118
#define B01110110 118
#define B1110111 119
#define B01110111 119
#define B1111000 120
#define B01111000 120
#define B1111001 121
#define B01111001 121
#define B1111010 122
#define B01111010 122
#define B1111011 123
#define B01111011 123
#define B1111100 124
#define B01111100 124
#define B1111101 125
#define B01111101 125
#define B1111110 126
#define B01111110 126
#define B1111111 127
#define B01111111 127
#define B10000000 128
#define B10000001 129
#define B10000010 130
#define B10000011 131
#define B10000100 132
#define B10000101 133
#define B10000110 134
#define B10000111 135
#define B10001000 136
#define B10001001 137
#define B10001010 138
#define B10001011 139
#define B10001100 140
#define B10001101 141
#define B10001110 142
#define B10001111 143
#define B10010000 144
#define B10010001 145
#define B10010010 146
#define B10010011 147
#define B10010100 148
#define B10010101 149
#define B10010110 150
#define B10010111 151
#define B10011000 152
#define B10011001 153
#define B10011010 154
#define B10011011 155
#define B10011100 156
#define B10011101 157
#define B10011110 158
#define B10011111 159
#define B10100000 160
#define B10100001 161
#define B10100010 162
#define B10100011 163
#define B10100100 164
#define B10100101 165
#define B10100110 166
#define B10100111 167
#define B10101000 168
#define B10101001 169
#define B10101010 170
#define B10101011 171
#define B10101100 172
#define B10101101 173
#define B10101110 174
#define B10101111 175
#define B10110000 176
#define B10110001 177
#define B10110010 178
#define B10110011 179
#define B10110100 180
#define B10110101 181
#define B10110110 182
#define B10110111 183
#define B10111000 184
#define B10111001 185
#define B10111010 186
#define B10111011 187
#define B10111100 188
#define B10111101 189
#define B10111110 190
#define B10111111 191
#define B11000000 192
#define B11000001 193
#define B11000010 194
#define B11000011 195
#define B11000100 196
#define B11000101 197
#define B11000110 198
#define B11000111 199
#define B11001000 200
#define B11001001 201
#define B11001010 202
#define B11001011 203
#define B11001100 204
#define B11001101 205
#define B11001110 206
#define B11001111 207
#define B11010000 208
#define B11010001 209
#define B11010010 210
#define B11010011 211
#define B11010100 212
#define B11010101 213
#define B11010110 214
#define B11010111 215
#define B11011000 216
#define B11011001 217
#define B11011010 218
#define B11011011 219
#define B11011100 220
#define B11011101 221
#define B11011110 222
#define B11011111 223
#define B11100000 224
#define B11100001 225
#define B11100010 226
#define B11100011 227
#define B11100100 228
#define B11100101 229
#define B11100110 230
#define B11100111 231
#define B11101000 232
#define B11101001 233
#define B11101010 234
#define B11101011 235
#define B11101100 236
#define B11101101 237
#define B11101110 238
#define B11101111 239
#define B11110000 240
#define B11110001 241
#define B11110010 242
#define B11110011 243
#define B11110100 244
#define B11110101 245
#define B11110110 246
#define B11110111 247
#define B11111000 248
#define B11111001 249
#define B11111010 250
#define B11111011 251
#define B11111100 252
#define B11111101 253
#define B11111110 254
#define B11111111 255
#endif /* _BIT_CONSTANTS_H_ */

View File

@@ -0,0 +1,35 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/* Note: Use of this header file is deprecated. Use bit_constants.h
instead. */
#ifndef _WIRISH_BITS_H_
#define _WIRISH_BITS_H_
#include <bit_constants.h>
#endif

View File

@@ -0,0 +1,175 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file wirish/include/wirish/boards.h
* @author Bryan Newbold <bnewbold@leaflabs.com>,
* Marti Bolivar <mbolivar@leaflabs.com>
* @brief init() and board-specific pin information.
*/
#ifndef _WIRISH_BOARDS_H_
#define _WIRISH_BOARDS_H_
#include <libmaple/libmaple_types.h>
#include <wirish_types.h>
#include <board/board.h>
/* Set of all possible pin names; not all boards have all these (note
* that we use the Dx convention since all of the Maple's pins are
* "digital" pins (e.g. can be used with digitalRead() and
* digitalWrite()), but not all of them are connected to ADCs. */
enum {
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16,
D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31,
D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46,
D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61,
D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76,
D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91,
D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105,
D106, D107, D108, D109, D110, D111, };
/**
* @brief Maps each Maple pin to a corresponding stm32_pin_info.
* @see stm32_pin_info
*/
extern const stm32_pin_info PIN_MAP[];
/**
* @brief Pins capable of PWM output.
*
* Its length is BOARD_NR_PWM_PINS.
*/
extern const uint8 boardPWMPins[];
/**
* @brief Array of pins capable of analog input.
*
* Its length is BOARD_NR_ADC_PINS.
*/
extern const uint8 boardADCPins[];
/**
* @brief Pins which are connected to external hardware.
*
* For example, on Maple boards, it always at least includes
* PB1 for the LED. Its length is BOARD_NR_USED_PINS.
*/
extern const uint8 boardUsedPins[];
/**
* @brief Generic board initialization function.
*
* This function is called before main(). It ensures that the clocks
* and peripherals are configured properly for use with wirish, then
* calls boardInit().
*
* @see boardInit()
*/
void init(void);
/**
* @brief Board-specific initialization function.
*
* This function is called from init() after all generic board
* initialization has been performed. Each board is required to
* define its own.
*
* @see init()
*/
extern void boardInit(void);
/**
* @brief Test if a pin is used for a special purpose on your board.
* @param pin Pin to test
* @return true if the given pin is in boardUsedPins, and false otherwise.
* @see boardUsedPins
*/
bool boardUsesPin(uint8 pin);
/*
* Derived and default board definitions
*/
#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND
#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL)
#ifndef SYSTICK_RELOAD_VAL
#define SYSTICK_RELOAD_VAL (1000 * CYCLES_PER_MICROSECOND - 1)
#endif
#ifndef BOARD_BUTTON_PRESSED_LEVEL
#define BOARD_BUTTON_PRESSED_LEVEL HIGH
#endif
/**
* @brief Does the board break out a USART/UART's RX and TX pins?
*
* BOARD_HAVE_USART(n) is nonzero iff USARTn is available (n must be
* an integer literal, 1 through 6). Also see BOARD_HAVE_USART1, ...,
* BOARD_HAVE_UART4 (sic), etc.
*/
#define BOARD_HAVE_USART(n) (defined(BOARD_USART##n##_TX_PIN) && \
defined(BOARD_USART##n##_RX_PIN))
/** Feature test: nonzero iff the board has USART1. */
#define BOARD_HAVE_USART1 BOARD_HAVE_USART(1)
/** Feature test: nonzero iff the board has USART2, 0 otherwise. */
#define BOARD_HAVE_USART2 BOARD_HAVE_USART(2)
/** Feature test: nonzero iff the board has USART3, 0 otherwise. */
#define BOARD_HAVE_USART3 BOARD_HAVE_USART(3)
/** Feature test: nonzero iff the board has UART4, 0 otherwise. */
#define BOARD_HAVE_UART4 BOARD_HAVE_USART(4)
/** Feature test: nonzero iff the board has UART5, 0 otherwise. */
#define BOARD_HAVE_UART5 BOARD_HAVE_USART(5)
/** Feature test: nonzero iff the board has USART6, 0 otherwise. */
#define BOARD_HAVE_USART6 BOARD_HAVE_USART(6)
/**
* @brief Does the board break out a SPI peripheral's pins?
*
* BOARD_HAVE_SPI(n) is nonzero iff SPIn is available (n must be an
* integer literal: 1, 2, or 3). Also see BOARD_HAVE_SPI1,
* BOARD_HAVE_SPI2, BOARD_HAVE_SPI3. */
#define BOARD_HAVE_SPI(n) (defined(BOARD_SPI##n##_NSS_PIN) && \
defined(BOARD_SPI##n##_SCK_PIN) && \
defined(BOARD_SPI##n##_MISO_PIN) && \
defined(BOARD_SPI##n##_MOSI_PIN))
/** Feature test: nonzero iff the board has SPI1. */
#define BOARD_HAVE_SPI1 BOARD_HAVE_SPI(1)
/** Feature test: nonzero iff the board has SPI2. */
#define BOARD_HAVE_SPI2 BOARD_HAVE_SPI(2)
/** Feature test: nonzero iff the board has SPI3. */
#define BOARD_HAVE_SPI3 BOARD_HAVE_SPI(3)
/**
* @brief Feature test: nonzero iff the board has SerialUSB.
*/
//Roger Clark. Change so that BOARD_HAVE_SERIALUSB is always true, so that it can be controller by -DSERIAL_USB
#define BOARD_HAVE_SERIALUSB 1
/*(defined(BOARD_USB_DISC_DEV) && defined(BOARD_USB_DISC_BIT))*/
#endif

View File

@@ -0,0 +1,71 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2012 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file wirish/boards_private.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Private board support header.
*
* This file declares chip-specific variables and functions which
* determine how init() behaves. It is not part of the public Wirish
* API, and can change without notice.
*/
#ifndef _WIRISH_BOARDS_PRIVATE_H_
#define _WIRISH_BOARDS_PRIVATE_H_
#include <libmaple/rcc.h>
#include <libmaple/adc.h>
/* Makes the PIN_MAP rows more human-readable. */
#define PMAP_ROW(gpio_dev, gpio_bit, timer_dev, timer_ch, adc_dev, adc_ch) \
{ gpio_dev, timer_dev, adc_dev, gpio_bit, timer_ch, adc_ch }
namespace wirish {
namespace priv {
/*
* Chip-specific initialization data
*/
extern rcc_pll_cfg w_board_pll_cfg;
extern adc_prescaler w_adc_pre;
extern adc_smp_rate w_adc_smp;
/*
* Chip-specific initialization routines and helper functions.
*/
void board_reset_pll(void);
void board_setup_clock_prescalers(void);
void board_setup_gpio(void);
void board_setup_usb(void);
void series_init(void);
}
}
#endif

View File

@@ -0,0 +1,6 @@
/* We compile with nodefaultlibs, so we need to provide an error
* handler for an empty pure virtual function */
extern "C" void __cxa_pure_virtual(void) {
while(1)
;
}

View File

@@ -0,0 +1,90 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file wirish/ext_interrupts.cpp
* @brief Wiring-like interface for external interrupts
*/
#include "ext_interrupts.h"
#include <libmaple/gpio.h>
#include <libmaple/exti.h>
#include "boards.h"
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode);
void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) {
if (pin >= BOARD_NR_GPIO_PINS || !handler) {
return;
}
exti_trigger_mode outMode = exti_out_mode(mode);
exti_attach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit),
gpio_exti_port(PIN_MAP[pin].gpio_device),
handler,
outMode);
}
void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg,
ExtIntTriggerMode mode) {
if (pin >= BOARD_NR_GPIO_PINS || !handler) {
return;
}
exti_trigger_mode outMode = exti_out_mode(mode);
exti_attach_callback((exti_num)(PIN_MAP[pin].gpio_bit),
gpio_exti_port(PIN_MAP[pin].gpio_device),
handler,
arg,
outMode);
}
void detachInterrupt(uint8 pin) {
if (pin >= BOARD_NR_GPIO_PINS) {
return;
}
exti_detach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit));
}
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) {
switch (mode) {
case RISING:
return EXTI_RISING;
case FALLING:
return EXTI_FALLING;
case CHANGE:
return EXTI_RISING_FALLING;
}
// Can't happen
ASSERT(0);
return (exti_trigger_mode)0;
}

Some files were not shown because too many files have changed in this diff Show More