Compare commits

...

752 commits

Author SHA1 Message Date
Denis Knauf 1f53447813
Merge pull request #2 from iot-lab/pr/er-coap-dtls/tinydtls_and_er_coap_integration
Pr/er coap dtls/tinydtls and er coap integration
2018-03-10 22:34:41 +01:00
Denis Knauf 76ccd1ea13
Merge pull request #1 from osdomotics/master
level up
2018-03-10 22:29:08 +01:00
Harald Pichler 3f47cb300b change BUSY to PIN D14 2018-03-08 11:48:17 +01:00
Harald Pichler 0007835a5a bugfix timing 2018-03-08 11:24:20 +01:00
Harald Pichler c8bd1acde2 bugfix timing epaper 2018-03-07 09:25:14 +01:00
harald42 9d2f1715df bugfix init e-paper 2018-03-06 22:58:25 +01:00
harald42 02177f65e1 initial upload 2018-03-06 21:42:44 +01:00
harald42 46430fc77a initial upload 2018-03-05 21:28:35 +01:00
Harald 9da22fbec4
Merge pull request #12 from DenisKnauf/master
leds_off only provided, if PLATFORM_HAS_LEDS is 1, not if defined.
2018-03-02 08:24:53 +01:00
Denis Knauf ca431d2e46 leds_off only provided, if PLATFORM_HAS_LEDS is 1, not if defined. 2018-03-01 20:21:09 +01:00
Harald Pichler 3d255ed6f8 initial upload viewconfig 2018-02-28 16:28:46 +01:00
Christian Ratzenhofer 1c8b438bca Fixup osd examples, contiki prints panid and channel on boot 2018-02-14 18:49:37 +01:00
Christian Ratzenhofer 3de5c47802 pan ID and channel are defined on platform level, not example 2018-02-14 18:07:44 +01:00
Harald Pichler ea04534281 remove panid definition 2018-01-04 15:24:18 +01:00
Harald Pichler e62f254e7e bugfix now work with 8 sensors 2017-12-21 15:02:08 +01:00
Harald Pichler 9377759d3b initial upload 2017-12-20 12:02:58 +01:00
Harald Pichler 59b7f37e26 initial upload 2017-12-20 12:01:50 +01:00
Harald Pichler 7fd5b7a6a7 disable rpl quality 2017-12-20 11:40:37 +01:00
Harald Pichler 94f4b19460 update clock 2017-12-15 14:06:32 +01:00
Ralf Schlatterbeck eb68b98cf5 Also output smooth led on pin 3 2017-12-08 20:35:39 +01:00
harald42 196b169fbe remove unused code 2017-12-02 10:16:02 +01:00
Ralf Schlatterbeck d6618ade1a Add soft-blink LED example 2017-12-01 15:51:15 +01:00
Harald Pichler 9b901dd28e initial upload 2017-11-28 11:04:42 +01:00
Harald Pichler 713ffc33f2 add servo resource 2017-11-17 13:43:35 +01:00
Harald Pichler 2247c673fc add compile cpp files for resources 2017-11-17 13:04:38 +01:00
Harald Pichler a44c16a426 initial upload 2017-11-17 12:57:59 +01:00
Harald Pichler fb5fdca66a update readme 2017-11-16 16:20:05 +01:00
Harald Pichler 89d650d87b remove ifdef, merkur plattform have always battery cputemp and led possibility 2017-11-16 16:17:01 +01:00
Harald Pichler e0482d6d1b add arduino-settingsmanager to regression test 2017-11-16 14:29:35 +01:00
Ralf Schlatterbeck 81598323c6 Add Servo example 2017-11-09 11:07:36 +01:00
Harald Pichler 6695835808 bugfix compile error 2017-11-09 10:59:07 +01:00
Harald Pichler b929b419af initial upload 2017-11-09 08:39:35 +01:00
Marcus Priesch 80388188f7 fixed analog pin & compiling issues 2017-11-05 14:22:13 +01:00
Harald Pichler 502842a30b enable reciever always on 2017-10-20 11:19:46 +02:00
Harald Pichler aa9fc5d817 initial upload 2017-10-20 10:47:48 +02:00
Harald Pichler 1ee36e7429 make it possible to switch reviever always on at compile time 2017-10-19 16:00:03 +02:00
Harald Pichler 15039f6b5d cleanup code 2017-10-19 15:44:11 +02:00
Harald Pichler e93083073c expand to tree htu sensors 2017-10-19 14:28:10 +02:00
Harald Pichler 9355f678e3 rename htu to dhta ... c 2017-10-19 14:10:37 +02:00
Harald Pichler 4d90cd2e3f add dht sensor code 2017-10-19 11:35:46 +02:00
Harald Pichler da8cd47dea add arduino macro microsecondsToClockCycles 2017-10-19 11:34:06 +02:00
Harald Pichler e492974415 add ota resources 2017-10-16 16:01:43 +02:00
Harald Pichler 96c5d12e2a initial upload 2017-10-10 11:31:12 +02:00
Marcus Priesch 965ac84918 added 2017-10-10 00:39:53 +02:00
Harald Pichler 325e41ae6a print partition 2017-10-06 13:40:20 +02:00
Harald Pichler a9cb7ab7be Merge branch 'master' of https://github.com/osdomotics/osd-contiki 2017-10-06 13:34:48 +02:00
Harald Pichler 7fffc50d7c show acrive partition 2017-10-06 13:25:53 +02:00
Marcus Priesch 233cb02993 enabled rpl mesh routing 2017-10-05 17:01:09 +02:00
Marcus Priesch 54b72dcf64 update 2017-10-05 16:57:01 +02:00
Marcus Priesch 8c82ce0722 fixed some issues, added ota-update 2017-10-05 16:56:10 +02:00
Marcus Priesch 86596ac92f moved to apps folder 2017-10-05 16:53:26 +02:00
Marcus Priesch 259827b031 added coap:// links for firefox copper plugin 2017-10-05 16:45:30 +02:00
Harald Pichler 3479303454 enable rpl etx messurement 2017-10-02 16:15:16 +02:00
Harald Pichler 3fb61f7695 initial upload 2017-09-26 16:44:02 +02:00
Harald Pichler dd84558cd6 set default mcu sleep 2017-09-26 14:59:55 +02:00
Harald Pichler 297bd14f7b add enable aes hardwre 2017-09-26 14:15:53 +02:00
Harald Pichler 30de144aea save energy 2017-09-20 14:17:26 +02:00
Harald Pichler 13c22c0c71 cleanup code 2017-09-20 13:53:32 +02:00
Harald Pichler d4790c8ede bugfix set mcusleep value 2017-09-20 13:48:01 +02:00
Harald Pichler 5003aca5c7 add settings manager 2017-09-20 11:17:46 +02:00
Harald Pichler cfeb8036e0 bugfix thisplattform 2017-09-20 10:26:23 +02:00
Harald Pichler 2036cda4d9 add example and todos 2017-09-20 09:25:22 +02:00
Harald Pichler 29190681cc disable debug prints, remove rfchannel coap entry 2017-09-20 08:45:01 +02:00
Harald Pichler ba62fd2dd2 cleanup code and save memory 2017-09-20 06:22:07 +02:00
Harald Pichler ecdd101586 add rfsetings function 2017-09-19 16:40:22 +02:00
Harald Pichler 25d38eba2c remove s command from shell, add if typing disable mcusleep 2017-09-19 11:35:45 +02:00
Harald Pichler 927c0b8eac add start stop mcusleep 2017-09-18 15:05:39 +02:00
Harald Pichler 87f433d657 bugfix startup dont sleep 5sec. 2017-09-14 17:19:53 +02:00
Harald Pichler 0b24e047c5 add s command to disable mcusleep 2017-09-14 16:15:43 +02:00
Harald Pichler 31ec8687e4 add resources-common res-rfchannel 2017-09-13 16:50:53 +02:00
Harald Pichler 8b2ee08d55 add shell macconfig 2017-09-13 13:38:46 +02:00
Harald Pichler aaf1e8b2b1 initial upload 2017-09-12 16:28:05 +02:00
Harald Pichler 6694583291 cleanup code, move shell-merkur to apps/shell; move needed function from extended-rf-api to params 2017-09-12 14:39:38 +02:00
Harald Pichler fedd9cb0d7 bugfix set tx power from shell 2017-09-12 11:12:53 +02:00
Harald Pichler df2b297d91 bugix read tx power 2017-09-10 22:13:07 +02:00
Harald 4127d0993b Update README.md 2017-09-08 13:30:28 +02:00
Harald 11525b74ae Update README.md 2017-09-08 13:25:34 +02:00
Harald 8e23d07de4 Update README.md 2017-09-08 13:21:51 +02:00
Harald Pichler 5f8be3e6ea add Plattform documentation 2017-09-08 11:27:17 +02:00
Harald Pichler 07c21e6e7d add radio functions for settings radio parameter 2017-09-08 10:39:40 +02:00
Harald Pichler df282f348c cleanup code 2017-09-08 08:26:36 +02:00
Harald Pichler 3a560c79f9 change name saveparams to saverfparams 2017-09-07 21:07:24 +02:00
Harald Pichler 64b2750de3 set filter to standard 2017-09-07 16:01:42 +02:00
Harald Pichler a2f8424b74 add shell save parameter txpower, channel, panid 2017-09-07 11:44:54 +02:00
Harald Pichler f368875ea2 add params_save_channel 2017-09-06 16:54:56 +02:00
Harald Pichler 17e0b6f2cc add change cca thresholds 2017-09-05 22:48:57 +02:00
Harald Pichler 2ef7438131 add shell-merkur 2017-09-05 22:24:56 +02:00
Harald Pichler 8c5b66d715 work in progress -> rf settings shell 2017-09-05 16:38:55 +02:00
Harald Pichler 3f6cb4e795 Merge branch 'contiki' 2017-09-05 11:14:11 +02:00
Harald Pichler 7a6bab7b10 add shell comands 2017-09-01 11:18:20 +02:00
Harald Pichler 13c4934a37 bugfix settings mananger read EUI64 from bootloader 2017-08-31 16:06:15 +02:00
Harald Pichler 75e8c162ed initial upload settingsmanager example 2017-08-31 11:23:55 +02:00
Ralf Schlatterbeck 0c3a9c6b5a Fix OTA update
Image 0 did not work. We now get rid of bootloader_backup_irq_table and
do this manually: We may not write to address 0 while an image is
running. So for image 0 we write the lower 8 pages to the backup
address. For all other images (ony image 1 currently) we write to
*both*, the original address *and* the backup address. This is done
because some addresses in the lower 8 pages *are* used at the original
address and the bootloader doesn't (want to) know which addresses are
which.
There are more safeguards now: We refuse to write to the active or
boot_next image (if boot_next is not boot_default). We mark the uploaded
partition as not ok.
Needs latest bootloader with commit ID a5771ae033b57.
2017-08-27 15:00:04 +02:00
Harald Pichler 32afc08622 default programmer usb0 2017-08-24 13:56:24 +02:00
Harald Pichler d62fe15a26 bugfix upload to partition 0 2017-08-24 13:55:21 +02:00
Harald Pichler 3b56d718c6 bugfix make ota *.bin file 2017-08-23 13:19:42 +02:00
Harald Pichler 32bbd0cc71 add compile doku and fix compile warnings 2017-08-23 08:59:04 +02:00
Ralf Schlatterbeck 7ea0e3b933 Fix Makefiles, remove/fix flash targets
The target "flash" and related stuff is now in the platform makefiles.
2017-08-22 22:29:03 +02:00
Ralf Schlatterbeck 12ee7b7e39 Update README
Document resources and fix some outdated information.
2017-08-22 21:09:46 +02:00
Ralf Schlatterbeck cc48b88713 New method for determining active partition 2017-08-22 20:20:07 +02:00
Ralf Schlatterbeck 406fb7ea44 Add linker script
Also get rid of genbackupisr hack: We can achieve the same thing with
avr-objcopy which doesn't need additional software.
We use the new bootloader setting for irq-save area of 0x800.
2017-08-22 10:13:36 +02:00
Ralf Schlatterbeck edc7a59091 New make environment for new bootloader
Compatible with old bootloader. Adds an additional section with a copy
of the interrupt vector table to the end of the image. This is needed by
the new bootloader and should be ok for the old bootloader.

Note that for this to work, everybody needs python installed with
the IntelHex python package. On Linux this can be achieved with

pip install IntelHex
2017-08-20 20:57:17 +02:00
Ralf Schlatterbeck d890a492bb Set arduino LOOP_INTERVAL in project-conf.h 2017-08-20 19:42:42 +02:00
Ralf Schlatterbeck 3defa16553 Output min and max address on stderr 2017-08-20 19:41:34 +02:00
Ralf Schlatterbeck 6141e26999 Allow a second upload, reset state 2017-08-20 16:43:11 +02:00
Ralf Schlatterbeck dd9ba9e0ef Add missing resources.h 2017-08-20 15:09:22 +02:00
Ralf Schlatterbeck e3784fa9c7 Add query parameter to generic resouce macros
Modify all callback functions to use new signature.
ota-update now uses this to pass the partition to some get/put methods.
2017-08-20 15:01:30 +02:00
Ralf Schlatterbeck 954da749eb Factor irq methods
Now methods that need interrupts turned off are wrapped.
Make genbackupisr.py executable.
New resources for bootloader-related information.
2017-08-20 11:47:13 +02:00
Marcus Priesch 6eced34422 fixed size_t, irq 2017-08-20 00:12:57 +02:00
Marcus Priesch 140f43f4c1 work in progress 2017-08-19 22:11:13 +02:00
Ralf Schlatterbeck ed638a5f5a Add genbackupisr 2017-08-19 21:05:39 +02:00
Ralf Schlatterbeck b774d61713 First sketch of image uploader 2017-08-19 19:26:27 +02:00
Harald Pichler bfdae2a7a7 bugfix compile example settings-example 2017-08-16 16:13:34 +02:00
Marcus Priesch 0859e3442c added 2017-08-08 14:36:44 +02:00
Harald Pichler 5e20a17131 initial upload 2017-08-07 15:46:53 +02:00
Harald Pichler f576ef27ce update redme 2017-08-02 10:26:54 +02:00
Ralf Schlatterbeck c35be7c066 First stab at OTA-update
Introduce new testing-app example.
Add a new coap error code for blockwise transfer.
Add include-file for bootloader callbacks (jumptable).
Note that only the bootloader for osd-merkur-256 will support
OTA-update, the -128 simply has not enough flash memory, so only
in the -256 we have the bootloader functions in the jump-table
of the bootloader and in the bootloader-if.h include-file.
2017-07-31 13:26:29 +02:00
Marcus Priesch 1a57b55d8f added bootloader_write_page_to_flash symbol 2017-07-30 13:05:09 +02:00
Marcus Priesch 1384aad51a fixed leds 2017-07-30 13:04:56 +02:00
Ralf Schlatterbeck 181e2c436e Add description of new H-brigde breakout-board 2017-07-29 14:42:13 +02:00
Harald Pichler fd442fb9da set direction 2017-07-25 20:16:55 +02:00
Harald Pichler 4b1580cc70 init arduino pwm driver 2017-07-21 13:31:44 +02:00
Harald Pichler a6670d99a8 set speed 2017-07-20 17:00:16 +02:00
Harald Pichler 38430ac259 set speed 2017-07-20 16:26:38 +02:00
Harald Pichler 60c6495fa3 initial upload 2017-07-20 15:16:01 +02:00
Harald Pichler 578dbaa431 add joystick, add BB-L Bridge 2017-07-20 15:14:45 +02:00
Harald Pichler 223ea26eb4 add led bar 2017-07-20 14:03:42 +02:00
Harald Pichler c39e10b2e7 initial upload 2017-07-20 10:33:19 +02:00
Harald Pichler 5e15ec6488 bugfix store value to d_temp_s and enable debug prints as degfault 2017-05-04 16:29:55 +02:00
Ralf Schlatterbeck dca85a7b6b Add valve example
Used for gardena valves with 9V power supply.
2017-03-24 20:10:37 +01:00
Harald Pichler c56142ccec add save energie 2017-03-24 16:11:28 +01:00
Harald Pichler afde635051 initial upload 2017-03-24 11:08:45 +01:00
Gaëtan Harter c7de205029 er-coap/dtls: allow overwriting the default tinydtls specific functions 2017-03-23 17:23:22 +01:00
Gaëtan Harter 1addd8da3a apps/tinydtls: disable doxygen generation 2017-03-23 16:33:25 +01:00
Gaëtan Harter e24f500e57 er-rest-dtls: add rest dtls examples 2017-03-23 16:33:25 +01:00
Gaëtan Harter fcc4f6d39f er-coap-dtls: use tinydtls app if "WITH_DTLS_COAP" is set 2017-03-23 16:33:25 +01:00
Gaëtan Harter 59dc4413bb er-coap-dtls: rename wrongly name IDENTITY_"HINT"
It's not IDENTITY_HINT but only IDENTITY here.
IDENTITY_HINT is not handled in any ways.
2017-03-23 16:33:25 +01:00
Gaëtan Harter 612cb23759 er-coap: COPIED FROM CETIC 6LBR add cetic tinydtls 'er-coap' communication layer
I would rather have a different way of configuring the communication layer.
A way which would not require modifiying the er-coap application.

Maybe more like a "disable udp" communication layer thing.
And overwrite with something else.
2017-03-23 16:32:44 +01:00
Gaëtan Harter d94efe528a tinydtls: add tinydtls as an app submodule
Currently, I'm providing my version for the submodule, but patches have been
proposed upstream to make tinydtls work out of the box.
2017-03-23 16:30:27 +01:00
Gaëtan Harter 5640293e8f er-coap: separate the communication layer
This code was copied and adapted from: https://github.com/cetic/6lbr
Licensed under the same license as Contiki.
2017-03-23 15:33:50 +01:00
Harald Pichler 0e861e76a3 Merge branch 'master' of https://github.com/osdomotics/osd-contiki 2017-03-18 20:43:10 +01:00
Harald Pichler 918b20f3cf set loop to 30 2017-03-18 20:42:47 +01:00
Ralf Schlatterbeck 3545f1fab5 Update README and LICENSE
Add comments about new Github Terms of Service (new since 2017-03-01)
and clarify the purpose of this project, point to LICENSE file in
README.md
2017-03-17 19:32:51 +01:00
Harald Pichler 2942868799 bugfix format 2017-03-03 11:45:46 +01:00
Harald Pichler 362eadd821 bugfix format 2017-03-03 11:40:13 +01:00
Harald Pichler 14baf5df6c bugfix format 2017-03-03 11:37:09 +01:00
Harald Pichler c954d22d81 bugfix format 2017-03-03 11:29:32 +01:00
Harald Pichler f36183f2b5 Merge branch 'master' of https://github.com/osdomotics/osd-contiki 2017-03-03 11:26:28 +01:00
Harald Pichler 314c46b91a bugfix format 2017-03-03 11:24:32 +01:00
Harald Pichler 6af70ee511 bugfix warning -Wwrite-strings 2017-03-03 11:21:43 +01:00
Harald Pichler 7000323c74 bugfix format 2017-03-03 11:17:33 +01:00
Harald Pichler ae6375d900 add humidity resource, bugfix pressure string variable 2017-02-24 10:28:35 +01:00
Harald Pichler 2137a12971 Merge branch 'master' of https://github.com/osdomotics/osd-contiki 2017-02-24 10:07:20 +01:00
Harald Pichler 4151c09e2c cleanup code 2017-02-23 22:36:32 +01:00
Harald Pichler 6677fac2ab bugfix use bmp280 and not bme280 2017-02-23 22:22:40 +01:00
Harald Pichler 8e07bab71f initial upload 2017-02-23 16:48:37 +01:00
Harald Pichler 85f3814f67 add i2c address 2017-02-23 08:59:49 +01:00
Harald Pichler 42dee52e65 initial upload 2017-02-23 08:49:02 +01:00
Harald Pichler 352f078be7 initial upload 2017-02-22 14:53:05 +01:00
Harald Pichler 5ea65cab08 temperature convert time is to short set from 50ms to 60ms 2017-02-21 20:06:15 +01:00
Harald Pichler 201a8174c6 print buffer text and hex format 2017-02-01 16:17:48 +01:00
Harald Pichler 6a9b6ae77b initial upload 2017-02-01 11:26:50 +01:00
Harald Pichler 9fb2352b08 bugfix buffer overflow 2017-02-01 10:28:02 +01:00
Harald Pichler 2f8549aaae Merge branch 'contiki'
Conflicts:
	cpu/cc26xx-cc13xx/lib/cc13xxware
	cpu/cc26xx-cc13xx/lib/cc26xxware
2017-01-31 15:00:59 +01:00
Harald Pichler 1ec48fcf37 bugfix repalce the same tag 2016-12-16 13:03:44 +01:00
Harald Pichler 0812b89909 bugfix only one event if pressed 2016-12-09 15:59:22 +01:00
Harald Pichler d41197e1e7 add button code 2016-12-08 22:22:56 +01:00
Harald Pichler 52c26d31c4 initial upload 2016-12-07 09:20:49 +01:00
Harald Pichler 5fc05b102b add sencond button 2016-12-07 09:18:10 +01:00
Harald Pichler 95b8c2683e cleanup examples 2016-12-06 21:37:58 +01:00
Harald Pichler 994badaef9 cleanup code 2016-12-06 21:37:03 +01:00
Harald Pichler 16e6a20b31 add button function 2016-12-06 21:36:22 +01:00
Harald Pichler 353cfe723c initial upload 2016-12-06 21:32:33 +01:00
Harald Pichler 938aa0db71 bugfix type 2016-12-04 16:09:55 +01:00
Harald Pichler 4f7476c084 bugfix type 2016-12-04 15:49:14 +01:00
Harald Pichler f8a399d346 initial upload 2016-12-04 15:47:40 +01:00
Harald Pichler aa1670e5d4 add used serial lines 2016-12-04 15:45:09 +01:00
Harald Pichler 6a1a4b62a0 add more arduino osd examples 2016-11-15 09:37:06 +01:00
Harald Pichler f9f923d29c bugfix SPI 2016-11-15 09:36:30 +01:00
Harald Pichler b708fac68d Merge branch 'contiki' 2016-11-15 08:29:23 +01:00
Harald Pichler 9f40b0734c add rfid resources 2016-11-14 11:13:07 +01:00
Harald Pichler ceb4fb3298 initial upload 2016-11-14 07:44:34 +01:00
Harald Pichler 1398ff0de6 print date to serial1 2016-11-09 15:39:24 +01:00
Harald Pichler c666b18a12 add hardware serial1 to use with arduino api 2016-11-09 15:14:45 +01:00
Harald Pichler d2a1f8937e add coap resoure ip 2016-11-06 16:17:16 +01:00
Harald Pichler d8bb685989 bugfix post led/RGB 2016-11-05 19:34:07 +01:00
Harald Pichler 646bb077ef move res_red .. to resources folder 2016-11-04 08:40:58 +01:00
Harald Pichler d66e402cad bugfix linker problem mix c cpp function 2016-11-03 16:20:22 +01:00
Harald Pichler 5ea437c170 initial upload 2016-11-03 15:46:00 +01:00
Harald Pichler 20820a11e0 move rgb resource to resource folder 2016-11-03 11:27:42 +01:00
Harald Pichler d2a650f514 cleanup code 2016-11-03 08:38:21 +01:00
Harald Pichler 79b69334df cleanup code 2016-11-03 08:11:42 +01:00
Harald Pichler 0556557d8b remove unneeded code 2016-10-28 11:43:55 +02:00
Harald Pichler 17520dc4e0 add resource res_rgb 2016-10-27 14:17:26 +02:00
Harald Pichler e6dbb8c3f2 Merge branch 'master' into osd
Conflicts:
	examples/osd/triggerbaord/sketch.pde
2016-10-26 17:03:37 +02:00
Harald Pichler 54e676343f set reciever amplifier to -90dB if use nullmac 2016-10-20 15:41:26 +02:00
Harald Pichler 8891a0ec44 reduce power consumtion 2016-10-19 09:45:45 +02:00
Harald Pichler b7b3f0a33a add mcusleep set parameter to save energie 2016-10-19 08:32:21 +02:00
Harald Pichler ed1ae480f1 initial uplaod 2016-10-17 08:24:14 +02:00
Harald Pichler fd37296cdf more range, we have power 2016-10-17 08:22:38 +02:00
Harald Pichler 3b28df58da eliminate c++ string warnings 2016-10-17 08:20:16 +02:00
Harald Pichler 47760c57e6 add parameter to save more power 2016-10-16 22:08:18 +02:00
Harald Pichler 0fd28e0585 remove PT_YIELD to habe better ping sync 2016-10-16 22:02:54 +02:00
Harald Pichler a152a30958 add mac layer security 2016-10-13 12:41:02 +02:00
Harald Pichler e4ab78369e initial upload 2016-10-13 12:36:53 +02:00
Harald Pichler 8f5a033c48 move arduino app code to project 2016-10-12 10:16:41 +02:00
Harald Pichler 548bf32990 initial upload 2016-10-12 10:02:59 +02:00
Harald Pichler e410b2ddd2 add WCHaracter 2016-10-07 15:29:03 +02:00
Harald Pichler 34adab3210 remove redefine routing warning 2016-10-02 22:50:10 +02:00
Harald Pichler 9226facda8 remove warnings 2016-10-02 22:49:22 +02:00
Harald Pichler fa11a55a45 initial upload 2016-10-02 22:35:56 +02:00
Harald Pichler 5d76c0a6af add rgb resource 2016-10-02 22:32:58 +02:00
Harald Pichler dfea93b2ff add spi and eeprom arduino libs 2016-10-02 18:53:44 +02:00
Harald Pichler cfca07489d coap client test 2016-09-27 18:13:03 +02:00
Harald Pichler 8302b1f762 bugfix constrain return value 2016-09-27 17:03:15 +02:00
Harald Pichler ee5cd039a1 add ChainableLED 2016-09-27 09:51:26 +02:00
Harald Pichler a37fd79426 disable mcusleep 2016-09-26 21:06:14 +02:00
Harald Pichler 916bebd102 reduce power consumtion 2016-09-26 21:04:05 +02:00
Harald Pichler ae79061182 bugfix powercyle and sleep mcu timing 2016-09-23 14:59:30 +02:00
Harald Pichler a5b59e8cbb Merge branch 'contiki'
Conflicts:
	.gitmodules
	core/net/mac/contikimac/contikimac.c
	cpu/cc26xx-cc13xx/lib/cc13xxware
2016-09-21 21:09:29 +02:00
Harald Pichler 6f7e68c3d4 make it possible to config node as host in project.conf 2016-09-20 21:56:32 +02:00
Harald Pichler 2fd23f99ed config as hostnode, add coap client 2016-09-20 21:49:52 +02:00
Harald Pichler 8b1745214c bugfix answear speed 2016-09-20 21:22:11 +02:00
Harald Pichler 28f2b2caa8 add coap client function 2016-09-20 21:20:34 +02:00
Harald Pichler 5de29079ae bugfix switch netstack mode 2016-09-16 16:18:02 +02:00
Harald Pichler fd12dcccf0 bugfix minimal push button time 2016-09-16 14:31:38 +02:00
Harald Pichler c663bb527e add UIP_CONF_ROUTER to project.conf 2016-09-16 14:12:37 +02:00
Harald Pichler 5b288a5777 Merge branch 'osd' 2016-09-08 10:33:24 +02:00
Harald Pichler 34a9135f83 activate reciver on 2016-09-01 09:34:57 +02:00
Harald Pichler 37ea128d65 Merge branch 'osd'
Conflicts:
	cpu/avr/dev/button-sensor.c
2016-08-24 08:07:33 +02:00
Harald c7de6343d9 Merge pull request #5 from piccaso/max-age
Triggerboard: set max-age header
2016-08-24 07:54:13 +02:00
Flo eeb90bab77 gets rid of 'deprecated conversion from string constant to char*' 2016-08-24 00:59:47 +02:00
Harald Pichler ec34b8640c bugfix dallas remove first space 2016-08-23 20:51:21 +02:00
Flo 3af0cc460c set max-age header 2016-08-22 22:53:01 +02:00
Harald Pichler 0190c261e2 use led1_on 2016-08-22 22:15:41 +02:00
Harald Pichler 6cf4e147ed add noncoresec 2016-08-20 14:32:26 +02:00
Harald Pichler 8b887ca429 add button led bled to project 2016-08-20 14:09:44 +02:00
Harald Pichler a70a51acc2 fake return value to 0 for better range, function rf230_cca have a bug 2016-08-19 18:18:09 +02:00
Harald Pichler 1d2447d69d add noncorsec section 2016-08-18 17:30:39 +02:00
Harald Pichler 12e77a1e58 bugfix cca threshold 2016-08-18 17:26:37 +02:00
Harald Pichler 6c7dc58574 make it more flexible to user in other projects 2016-08-16 11:13:57 +02:00
Harald Pichler d3431a0b54 bugfix contiki mac layer droped packets 2016-08-16 11:11:32 +02:00
Harald Pichler 91fcc28b12 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd
Conflicts:
	cpu/avr/dev/button-sensor.c
2016-08-16 10:38:46 +02:00
Harald Pichler cf40f59843 add pin status 2016-08-15 20:22:49 +02:00
Harald Pichler 265d4e8723 shorter button deflipping time 2016-08-15 18:34:37 +02:00
Ralf Schlatterbeck 28cb276c70 Merge branch 'osd'
Conflicts:
	apps/arduino/arduino-process.c
	apps/arduino/arduino-process.h
	apps/json-resource/generic_resource.c
	apps/json-resource/generic_resource.h
	apps/time/Makefile.time
	apps/time/resource_gmtime.c
	apps/time/resource_timestamp.c
	apps/time/time.c
	apps/time/time_resource.h
	core/dev/leds.c
	core/lib/petsciiconv.c
	core/net/ip/resolv.c
	core/net/ip/slipdev.c
	core/net/ip/tcpip.c
	core/net/ipv4/uip.c
	core/net/ipv6/uip-ds6.c
	core/net/mac/contikimac/contikimac.c
	core/net/mac/frame802154.h
	core/net/mac/framer-802154.c
	core/net/mac/nullrdc.c
	core/net/rpl/rpl-dag.c
	core/net/rpl/rpl-ext-header.c
	core/net/rpl/rpl-icmp6.c
	core/net/rpl/rpl-mrhof.c
	core/net/rpl/rpl-of0.c
	core/net/rpl/rpl-timers.c
	core/net/rpl/rpl.c
	cpu/avr/Makefile.avr
	cpu/avr/dev/lanc111.c
	cpu/avr/radio/rf230bb/halbb.c
	dev/arduino/arduino-compat.h
	examples/osd/.gitignore
	examples/osd/arduino-dooralert/Makefile
	examples/osd/arduino-dooralert/flash.sh
	examples/osd/arduino-dooralert/run.sh
	examples/osd/arduino-dooralert/sketch.pde
	examples/osd/arduino-merkurboard/Makefile
	examples/osd/arduino-merkurboard/README.md
	examples/osd/arduino-merkurboard/flash.sh
	examples/osd/arduino-merkurboard/project-conf.h
	examples/osd/arduino-merkurboard/run.sh
	examples/osd/arduino-plantobserving/Makefile
	examples/osd/arduino-plantobserving/flash.sh
	examples/osd/arduino-plantobserving/project-conf.h
	examples/osd/arduino-plantobserving/run.sh
	examples/osd/arduino-plantobserving/sketch.pde
	examples/osd/arduino-roomalert/Makefile
	examples/osd/arduino-roomalert/flash.sh
	examples/osd/arduino-roomalert/run.sh
	examples/osd/arduino-roomalert/sketch.pde
	examples/osd/arduino-sketch/Makefile
	examples/osd/arduino-sketch/flash.sh
	examples/osd/arduino-sketch/led_pwm.h
	examples/osd/arduino-sketch/resource_led_pwm.c
	examples/osd/arduino-sketch/run.sh
	examples/osd/arduino-sketch/sketch.pde
	examples/osd/arduino-wateralert/Makefile
	examples/osd/arduino-wateralert/flash.sh
	examples/osd/arduino-wateralert/run.sh
	examples/osd/arduino-wateralert/sketch.pde
	examples/osd/climate/Makefile
	examples/osd/climate/er-example-server.c
	examples/osd/climate/flash.sh
	examples/osd/climate/project-conf.h
	examples/osd/climate/run.sh
	examples/osd/climate/server-only.csc
	examples/osd/climate2/Makefile
	examples/osd/climate2/er-example-server.c
	examples/osd/climate2/flash.sh
	examples/osd/climate2/project-conf.h
	examples/osd/climate2/run.sh
	examples/osd/climate2/server-only.csc
	examples/osd/dual-rgbw-actor/Makefile
	examples/osd/dual-rgbw-actor/flash.sh
	examples/osd/dual-rgbw-actor/run.sh
	examples/osd/dual-rgbw-actor/server-client.csc
	examples/osd/dual-rgbw-actor/server-only.csc
	examples/osd/embedd-vm-merkurboard/Makefile
	examples/osd/embedd-vm-merkurboard/embedd-vm-server.c
	examples/osd/embedd-vm-merkurboard/flash.sh
	examples/osd/embedd-vm-merkurboard/run.sh
	examples/osd/embedd-vm-merkurboard/server-only.csc
	examples/osd/er-rest-example-merkurboard/Makefile
	examples/osd/er-rest-example-merkurboard/README.md
	examples/osd/er-rest-example-merkurboard/er-example-client.c
	examples/osd/er-rest-example-merkurboard/er-example-server.c
	examples/osd/er-rest-example-merkurboard/er-plugtest-server.c
	examples/osd/er-rest-example-merkurboard/flash.sh
	examples/osd/er-rest-example-merkurboard/flashclient.sh
	examples/osd/er-rest-example-merkurboard/project-conf.h
	examples/osd/er-rest-example-merkurboard/run.sh
	examples/osd/er-rest-example-merkurboard/runclient.sh
	examples/osd/er-rest-example-merkurboard/server-client.csc
	examples/osd/light-actor/Makefile
	examples/osd/light-actor/er-example-server.c
	examples/osd/light-actor/flash.sh
	examples/osd/light-actor/pcintkey.c
	examples/osd/light-actor/project-conf.h
	examples/osd/light-actor/run.sh
	examples/osd/light-actor/server-only.csc
	examples/osd/light-shutter-control/Makefile
	examples/osd/light-shutter-control/flash.sh
	examples/osd/light-shutter-control/pcintkey.c
	examples/osd/light-shutter-control/run.sh
	examples/osd/light-shutter-control/server-only.csc
	examples/osd/merkurboard/Makefile
	examples/osd/merkurboard/README.md
	examples/osd/merkurboard/er-example-client.c
	examples/osd/merkurboard/er-example-server.c
	examples/osd/merkurboard/er-plugtest-server.c
	examples/osd/merkurboard/flash.sh
	examples/osd/merkurboard/flashclient.sh
	examples/osd/merkurboard/project-conf.h
	examples/osd/merkurboard/run.sh
	examples/osd/merkurboard/runclient.sh
	examples/osd/native-border-router/Makefile
	examples/osd/native-border-router/border-router-cmds.c
	examples/osd/native-border-router/border-router-cmds.h
	examples/osd/native-border-router/border-router-rdc.c
	examples/osd/native-border-router/border-router.c
	examples/osd/native-border-router/border-router.h
	examples/osd/native-border-router/project-conf.h
	examples/osd/native-border-router/slip-config.c
	examples/osd/native-border-router/slip-dev.c
	examples/osd/native-border-router/tun-bridge.c
	examples/osd/pingtheplug/Makefile
	examples/osd/pingtheplug/er-example-server.c
	examples/osd/pingtheplug/flash.sh
	examples/osd/pingtheplug/pcintkey.c
	examples/osd/pingtheplug/run.sh
	examples/osd/pingtheplug/server-only.csc
	examples/osd/pir-sensor/Makefile
	examples/osd/pir-sensor/flash.sh
	examples/osd/pir-sensor/run.sh
	examples/osd/pir-sensor/server-client.csc
	examples/osd/pir-sensor/server-only.csc
	examples/osd/powerbox/Makefile
	examples/osd/powerbox/er-example-server.c
	examples/osd/powerbox/flash.sh
	examples/osd/powerbox/run.sh
	examples/osd/powerbox/server-only.csc
	examples/osd/pwm-example/Makefile
	examples/osd/pwm-example/er-example-server.c
	examples/osd/pwm-example/flash.sh
	examples/osd/pwm-example/led_pwm.h
	examples/osd/pwm-example/resource_led_pwm.c
	examples/osd/pwm-example/run.sh
	examples/osd/rpl-border-router/Makefile
	examples/osd/rpl-border-router/border-router.c
	examples/osd/rpl-border-router/flash.sh
	examples/osd/rpl-border-router/project-conf.h
	examples/osd/rpl-border-router/run.sh
	examples/osd/rpl-border-router/slip-bridge.c
	examples/osd/runall.sh
	examples/osd/servo-sensor/Makefile
	examples/osd/servo-sensor/er-example-server.c
	examples/osd/servo-sensor/flash.sh
	examples/osd/servo-sensor/project-conf.h
	examples/osd/servo-sensor/run.sh
	examples/osd/servo-sensor/server-client.csc
	examples/osd/servo-sensor/server-only.csc
	examples/osd/slip-radio/Makefile
	examples/osd/slip-radio/flash.sh
	examples/osd/slip-radio/no-framer.c
	examples/osd/slip-radio/project-conf.h
	examples/osd/slip-radio/run.sh
	examples/osd/slip-radio/slip-net.c
	examples/osd/slip-radio/slip-radio-cc2420.c
	examples/osd/slip-radio/slip-radio-sky-sensors.c
	examples/osd/slip-radio/slip-radio.c
	examples/osd/slip-radio/slip-radio.h
	examples/osd/wallclock-time/Makefile
	examples/osd/wallclock-time/flash.sh
	examples/osd/wallclock-time/run.sh
	examples/osd/wirelessplug/Makefile
	examples/osd/wirelessplug/flash.sh
	examples/osd/wirelessplug/run.sh
	examples/osd/wirelessplug/server-client.csc
	examples/osd/wirelessplug/server-only.csc
	platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c
	platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c
	tools/tunslip6.c
2016-08-12 22:04:56 +02:00
Ralf Schlatterbeck 50a34d1235 Fix whitespace 2016-08-12 22:03:44 +02:00
Harald Pichler 70172a9eb8 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2016-08-12 07:50:23 +02:00
Harald Pichler 9408743938 move to arduino app 2016-08-12 07:50:17 +02:00
Harald Pichler 6e67d1415c shorter button flipping test 2016-08-12 07:46:30 +02:00
Harald Pichler c42a75d9d6 optimize power consumtion 2016-08-11 23:49:45 +02:00
Harald Pichler 6a2d13216a add mcu_sleep_off and on 2016-08-11 19:46:33 +02:00
Harald Pichler 542a921e3f initial uplaod 2016-08-11 14:04:29 +02:00
Harald Pichler 8402b1c151 initial upload, add button 2016-08-03 21:58:02 +02:00
Harald Pichler e534bcaa25 bugfix dht11 config 2016-07-04 20:26:06 +02:00
Harald Pichler 349f6bf429 Merge branch 'contiki' into osd 2016-06-29 09:04:54 +02:00
Harald Pichler d408da5be5 bugfix merge 2016-06-29 07:50:41 +02:00
Harald Pichler 3c8e91d74e cleanup confilicrts 2016-06-28 16:37:16 +02:00
Harald Pichler 978ef63002 cleanup debugpronts 2016-06-28 14:08:38 +02:00
Harald Pichler dfd8fdec4a initial upload 2016-05-20 11:18:19 +02:00
Harald Pichler 9a2494583d bugfix compile error tostrf 2016-05-20 09:11:11 +02:00
harald42 abc5db04b2 bugfix start i2c and printf 2016-05-18 08:17:47 +02:00
harald42 a95b0c9d46 add BH1750 sensor example 2016-05-17 16:43:11 +02:00
Harald Pichler 944f1b06d6 add led resource 2016-04-24 17:45:35 +02:00
Ralf Schlatterbeck 04bbba6c12 Multi-platform support, osd-merkur-{128,256}
Rename guhRF platform to osd-merkur-256, previous osd-merkur platform is
now osd-merkur-128. Also check that everything is consistent.
Add both platforms to the regression tests.
Move redundant files in platform dev directory of both platforms to
cpu/avr/dev. Note that this probably needs some rework. Already
discovered some inconsistency in io definitions of both devices in the
avr/io.h includes. Added a workaround in the obvious cases.
The platform makefiles now set correct parameters for bootloader and for
reading mac-address from flash memory.
Factor the flash programming into cpu/avr and platform/osd-merkur* and
rework *all* osd example makefiles to use the new settings. Also update
all the flash.sh and run.sh to use the new settings.
The suli ledstrip modules (and osd example) have also been removed.
2016-04-22 17:59:40 +02:00
Ralf Schlatterbeck 53dd2e5d16 Fix unused variable warning 2016-04-22 12:34:16 +02:00
Ralf Schlatterbeck 068f27d1c2 Fix integer overflow in RPL timeout expression 2016-04-22 12:31:21 +02:00
Boernsman 79df347afa added guhRF; added atmega256rfr2 support 2016-04-21 08:41:48 +02:00
harald42 9a3c6adf8d add mcu_sleep routines 2016-04-12 10:34:40 +02:00
Ralf Schlatterbeck 743245e230 Add 'x' prefix to time functions
.. to avoid name-clashes with (some) libraries. This now also should
make it work for the 'native' target (untested).
2016-03-29 17:48:59 +02:00
Ralf Schlatterbeck b2a289924b Fix type of get_header_content_type parameter 2016-03-28 17:25:30 +02:00
harald42 f2af0c7329 change default channel from 26 to 25 2016-03-16 15:00:46 +01:00
harald42 682df76b79 add cputem to common resources and example 2016-03-03 10:32:38 +01:00
Harald Pichler 5a5ed6b990 cleanup code 2016-02-27 22:16:02 +01:00
Harald Pichler 6bdae7d9ec cleanup code 2016-02-27 22:14:56 +01:00
Harald Pichler daf2191555 add arduino folder 2016-02-27 22:13:12 +01:00
Harald Pichler de928cd14e cleanup code 2016-02-27 22:10:53 +01:00
Ralf Schlatterbeck 6b40e88ecb Add cron functionality 2016-02-26 17:30:16 +01:00
Ralf Schlatterbeck c6165a3bcf Refactor GENERIC_RESOURCE macro
Now callback functions get the URI of the request, this allows to use a
single resource for multiple different URIs.
The is_json flag is now gone for the to-string function, instead the
macro has an is_str flag. If set this automagically produces quotes
around the string for json output.
Now from-string functions can return an error-code, 0 for success, -1
for error.
2016-02-26 17:13:48 +01:00
harald42 c7daa7c45d add linux documentaion 2016-02-25 13:58:07 +01:00
harald42 2df628aa4b bugfix native boarder router 2016-02-25 13:37:08 +01:00
harald42 9bb1f01905 update to new version 2016-02-25 13:25:24 +01:00
harald42 7d8254bd81 use uint32 for clock time 2016-02-25 09:32:21 +01:00
harald42 b462052bf5 CRLF will be replaced by LF 2016-02-25 08:20:41 +01:00
harald42 98e4451518 Merge branch 'contiki' into osd 2016-02-25 08:18:55 +01:00
harald42 e7f270cf37 crf replace by lf 2016-02-25 08:11:05 +01:00
harald42 a7b230a0b7 bugfix get macaddress 2016-02-24 08:29:24 +01:00
Harald Pichler 855bc65b8a initial upload 2016-02-23 20:32:53 +01:00
Harald Pichler 1e5163cbb3 bugfix remove testcode 2016-02-23 20:31:10 +01:00
Ralf Schlatterbeck de6477efa8 Fix run.sh scripts to use jumptable of bootloader
Otherwise a crash results with a bootloader compiled with a newer AVR
toolchain (e.g. Debian Jessie). If you still have an ages-old bootloader
without a jump-table, as a short-term measure you can revert this change
in your run.sh. As a long-term fix we recommend you get your bootloader
updated!
2016-02-19 17:32:09 +01:00
Ralf Schlatterbeck 0068611b4d Implement localtime
Now we manage a timezone and daylight-savings aware version of
localtime. We parse UNIX timezone strings. The default (active after the
first call to localtime or localtime_r) is CET/CEST, the timezone of
Europe/Vienna. The wallclock-time osd-example demonstrates how to set a
different timezone via the timezone resource.

Note: After startup no timezone is set. So in this state querying the
timezone resource will return an empty string. After first call to
localtime (if not timezone has been set via the timezone resource) a
query to timezone will return the default timezone string for CET/CEST.

The string returned by the localtime and utc timezones now also includes
the timezone name.

New fields tm_gmtoff and tm_zone were added to the tm structure. These
are available in BSD systems and when setting special compiler
definitions on Linux.

Note: the timezone offset information in the tm structure (tm_gmtoff)
as well as in the tz structure returned by gettimeofday (tz_minuteswest)
may be wrong sign, this code is largely untested.
2016-02-18 09:55:07 +01:00
Harald Pichler b8c5ee0e2b add Test code 2016-01-28 17:08:56 +01:00
Harald Pichler c09625704c add exponential 2016-01-25 22:39:52 +01:00
Harald Pichler f2fe41017b add linear lookup 2016-01-25 20:48:30 +01:00
Harald Pichler 681c514a18 add coap resourcen rgb 2016-01-25 20:41:26 +01:00
Harald Pichler 535194bcb4 add lookup table 2016-01-24 21:30:35 +01:00
Harald Pichler 44d4f855c6 add contiki combatibility 2016-01-24 16:04:37 +01:00
Harald Pichler 406d69a27c add RGBdriver 2016-01-23 17:49:51 +01:00
Harald Pichler 6fcdf21552 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2016-01-22 21:48:24 +01:00
Harald Pichler c381f81f57 add experimental code netstack 2016-01-22 21:46:35 +01:00
root e60fe15812 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2016-01-22 15:44:44 +01:00
Harald Pichler fce1b561da initial upload 2016-01-22 15:41:55 +01:00
harald 0c3eeed1bf add leds 2016-01-19 14:01:28 +01:00
Harald Pichler c2f9c584b9 at init set buzzer to low,at adc vonversion stop shedular dutycycle 2016-01-15 15:56:55 +01:00
Harald Pichler 428131e8a8 use dynamic sleep for loop 2016-01-06 21:57:29 +01:00
Harald Pichler 836a483f7e bugfix dallas coap resource 2016-01-06 21:39:35 +01:00
Harald Pichler d484585e39 bugfix scale 2015-12-22 06:37:40 +01:00
Harald Pichler c493bc6618 initial upload 2015-11-29 22:34:24 +01:00
Harald Pichler ba9d4ed578 add dallas ds1820 external sensor 2015-11-29 22:31:59 +01:00
Harald Pichler 67ed80e9fe move defines to servo.h 2015-11-28 18:45:15 +01:00
Harald Pichler 9b9958fb43 initial upload 2015-11-20 14:08:43 +01:00
Harald Pichler fd24ecd26e add index and struct for messured values 2015-10-11 15:30:30 +02:00
Harald Pichler e8471445ed add struct for sensors, add sketch.h 2015-10-11 15:22:49 +02:00
Harald Pichler 0a4938243e cleanup resources 2015-10-08 21:14:43 +02:00
Harald Pichler 4ff973a0cc mult. DS18B20 Temp demo 2015-10-07 16:14:00 +02:00
Harald Pichler 1a309e6632 bugfix project conf, do not sleep git add project-conf.h 2015-09-21 16:09:28 +02:00
Harald Pichler a2e70d49f3 remove first space from converted string 2015-09-16 10:31:52 +02:00
Harald Pichler 6b41f23d59 make mcusleep variable, use mcusleepcycle 2015-09-15 09:52:06 +02:00
Harald Pichler 7404e75213 bugfix float resources, save energy enabled 2015-09-14 16:55:18 +02:00
Harald Pichler e3ffbe36c8 bugfix printf and float 2015-09-14 10:51:16 +02:00
Harald Pichler 617d42663c add htu21d sensor and resources and set mesure inteval to 10 seconds 2015-09-11 21:41:24 +02:00
Ralf Schlatterbeck 7f09f96e88 Fix compile error
Wire.h is a C++ include-file and may not be within 'extern "C"'.
2015-09-11 15:10:28 +02:00
Harald Pichler 910dc981b5 initial upload 2015-09-04 14:04:11 +02:00
Harald Pichler 500078ef9a update to contiki 3.0 2015-08-26 16:01:57 +02:00
Harald Pichler 72c6c2c492 bugfix add status led 2015-05-21 22:14:39 +02:00
Harald Pichler 9b6bdd30b8 use all submodules 2015-05-21 21:31:18 +02:00
Harald Pichler 6a0d407806 Merge branch 'contiki' into osd 2015-05-19 10:54:55 +02:00
Harald Pichler 63e0d930aa add light actor 2015-05-18 15:33:45 +02:00
Harald Pichler 82d03d0ebf bugfix no framer 2015-05-15 20:59:59 +02:00
Harald Pichler 877bf27f5a Merge branch 'contiki' into osd 2015-05-15 20:48:26 +02:00
Harald Pichler b2847f4756 add coap18 2015-04-29 15:58:42 +02:00
Harald Pichler b97d6878c0 add coap18 2015-04-28 20:56:52 +02:00
Harald Pichler a1423c28fc add coap18 2015-04-28 19:53:43 +02:00
Harald Pichler 12fe0d8442 change to coap18 2015-04-22 14:18:10 +02:00
Harald Pichler 44c7cb348c add osd/servo-sensor/ for target osd-merkur 2015-04-07 10:16:46 +02:00
Harald b90acf2491 Merge pull request #2 from NoreSoft/osd
Osd - Servo-Example
2015-04-07 09:52:16 +02:00
David Rabel 29e62c4e20 SERVO_OFFSET deleted, SERVO_MIN added 2015-04-03 15:55:00 +02:00
David Rabel 41163406c2 Use OCR3 instead of OCR1 for servo 2015-04-03 15:49:17 +02:00
David Rabel 235f368340 Bugfix: missing braces added in serco_set() 2015-04-03 15:47:15 +02:00
David Rabel 65c50195c4 ressource handlers for servos corrected 2015-04-03 15:46:05 +02:00
David Rabel 0980393d22 Fix servo example 2015-04-03 14:31:25 +02:00
David Rabel 3ba9009f50 Use servo instead of t4-servo 2015-04-03 14:29:52 +02:00
Harald Pichler 560117e8f3 Merge branch 'contiki' into osd 2015-03-23 13:07:28 +01:00
Harald Pichler 0097d192be move dht11 define to project.conf 2015-03-23 13:03:32 +01:00
Harald Pichler d4656a26ff cleanup for test purpose 2015-02-18 10:29:19 +01:00
Harald Pichler d31ecbf486 Merge branch 'contiki' into osd 2015-02-18 10:04:47 +01:00
Harald Pichler 117f737f8d Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-02-10 20:17:36 +01:00
Harald Pichler 9dd81946d3 add coap 18 2015-02-10 20:16:51 +01:00
Harald Pichler 6730ec16c8 Merge branch 'contiki' into osd 2015-02-10 15:13:21 +01:00
Harald Pichler c30493e535 add Buzzer 2015-02-05 13:44:05 +01:00
Harald Pichler 98be2c25ea remove for test purose 2015-01-29 11:01:27 +01:00
Harald Pichler 0f109e3541 Merge branch 'contiki' into osd 2015-01-28 09:34:57 +01:00
Ralf Schlatterbeck 451e2df0f5 Fix IP-Address output (endianness!) 2015-01-27 16:41:30 +01:00
Ralf Schlatterbeck 5ff9b7c989 Don't re-init coap connection 2015-01-27 16:04:07 +01:00
Ralf Schlatterbeck 058ae7bae3 Alleged race-condition was a bug in receiver
Handling put-requests was missing a trailing \0 in the parsed string.
2015-01-27 10:43:03 +01:00
Ralf Schlatterbeck 16afb4b74c Workaround for race-condition 2015-01-27 10:06:22 +01:00
Ralf Schlatterbeck c8be130f2e Finally fix LED-Strip driver
.. and adapt led-strip.c to changed polarity (again).
2015-01-26 20:44:30 +01:00
Ralf Schlatterbeck 301d8d77bb Non-blocking send 2015-01-26 17:59:14 +01:00
Ralf Schlatterbeck 42f985a297 Add potentiometer app for setting led intensity 2015-01-26 17:27:12 +01:00
Ralf Schlatterbeck 1f3387cd44 Fix submodule URL 2015-01-25 21:06:04 +01:00
Ralf Schlatterbeck 050b55adae Fix LED_Strip_Suli submodule URL 2015-01-25 20:57:47 +01:00
Ralf Schlatterbeck a2357e648e Invert LED count, use fixed led driver 2015-01-25 19:04:04 +01:00
Ralf Schlatterbeck f6c158a139 Merge branch 'osd' of github.com:osdomotics/osd-contiki into osd 2015-01-25 18:32:07 +01:00
Ralf Schlatterbeck e946cd4c13 Add LED strip example
.. not yet working
2015-01-25 18:31:17 +01:00
Harald Pichler df220072f4 initial upload 2015-01-22 14:03:29 +01:00
Harald Pichler 801316badc update coap 18 macros 2015-01-22 14:01:36 +01:00
Harald Pichler 7b25177a3d Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-01-22 08:56:16 +01:00
Ralf Schlatterbeck baaa2c5741 Factor/Fix generic resources
Now the old GENERIC_RESOURCE macros works again (but usage has changed).
Common resources (battery, leds, radio) are now in resources-common.
2015-01-21 15:41:21 +01:00
Harald Pichler 75d577c9b5 blocksize 64 2015-01-21 15:08:23 +01:00
Harald Pichler 76e39b2b5d update coap 18 2015-01-21 14:46:36 +01:00
Harald Pichler ff29ab2c94 bugfix define framer and llsec 2015-01-16 22:22:16 +01:00
Harald Pichler 64e3ed0281 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-01-16 20:14:07 +01:00
Harald Pichler b3bf194b88 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-01-16 15:04:41 +01:00
Harald Pichler 000d37a7fc update modules remove llsec 2015-01-16 15:03:37 +01:00
Harald Pichler a8e8f54342 Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-01-16 14:19:15 +01:00
Harald Pichler 150aad4ad2 Merge branch 'contiki' into osd 2015-01-16 14:17:16 +01:00
Harald Pichler 4b9314cbde Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd 2015-01-13 20:49:38 +01:00
Harald Pichler 007cf1dbe3 Merge branch 'contiki' into osd 2015-01-13 13:14:11 +01:00
Harald Pichler a8728413b2 initial upload 2014-12-31 10:00:09 +01:00
Harald Pichler 2d52ca9051 inital upload 2014-12-31 09:56:05 +01:00
Harald Pichler 2d3cd057c4 initial upload 2014-12-31 09:55:31 +01:00
Harald Pichler d742fc4b76 changes for coap18 2014-12-31 09:53:24 +01:00
Harald Pichler 2b8aeee115 save energy 2014-12-29 13:05:50 +01:00
Harald Pichler fb473237ce bugfix modules 2014-12-29 11:02:51 +01:00
Harald Pichler 9efc5d41c1 Merge branch 'contiki' into osd 2014-12-29 08:20:00 +01:00
Harald Pichler 365fe31b02 coap 18 2014-12-29 08:16:47 +01:00
Harald Pichler aaaa0aa138 cleanup code, batterie value Volt 2014-12-29 08:11:51 +01:00
Harald Pichler a8c87e3f54 read better values 2014-12-29 08:10:10 +01:00
Harald Pichler df95393980 remove init pwm per default, switch moisture sensor on and off to save energy 2014-12-12 08:47:01 +01:00
Harald Pichler 76ea945fd7 add power save mode RDC_CONF_PT_YIELD_OFF 2014-12-09 16:42:45 +01:00
Harald Pichler 248a1e3882 add leds and battery 2014-12-09 14:36:06 +01:00
Harald Pichler a4b1e0138a add regression test 2014-12-07 22:43:57 +01:00
Harald Pichler cc0539ee90 remove unused examples 2014-12-07 21:55:43 +01:00
Harald Pichler fed6fe019c change to coap18 2014-12-07 21:39:46 +01:00
Harald Pichler 13aa2a1415 add coap18 2014-12-07 21:32:03 +01:00
Harald Pichler d6144bfebe cleanup makefile, add avr-size 2014-12-07 20:10:53 +01:00
Harald Pichler ed161d1905 NETSTACK_CONF_WITH_IPV6 2014-12-07 17:36:53 +01:00
Harald Pichler a02be51f08 Merge branch 'contiki' into osd 2014-12-07 15:24:00 +01:00
Harald Pichler 9c90608d3c bugfix hum temp 2014-11-28 14:04:39 +01:00
Harald Pichler 730d9e2d11 add battery 2014-11-27 15:01:07 +01:00
Harald Pichler 1dacefce01 add coap18 2014-11-27 14:07:14 +01:00
Harald Pichler 41f8a9c661 add coap18 2014-11-27 09:30:36 +01:00
Harald Pichler 698d8dce90 add coap18 2014-11-26 21:47:00 +01:00
Harald Pichler 824eca3b61 cleanup code, move ds1820 to resources 2014-11-26 17:12:34 +01:00
Harald Pichler 7a666307cf add coap 18 2014-11-26 16:46:13 +01:00
Harald Pichler 079e46f427 Merge branch 'contiki' into osd 2014-11-26 13:04:26 +01:00
Ralf Schlatterbeck b0a617b534 Merge branch 'contiki' into osd 2014-11-21 11:08:32 +01:00
Harald Pichler 9eb0c5466f initial uplaod 2014-11-21 09:44:25 +01:00
Harald Pichler 6167835689 use contiki mac 2014-11-20 16:32:22 +01:00
Harald Pichler e58322260f update llayer 2014-11-20 13:43:53 +01:00
Harald Pichler d8e0dd7005 update to coap rfc 2014-11-19 22:06:38 +01:00
Harald Pichler a86f137cf5 add module llsec 2014-11-19 15:10:10 +01:00
Harald Pichler 8966f7d509 update project to coap 13 2014-11-19 13:59:05 +01:00
Harald Pichler 0620eb86d0 initial upload 2014-11-19 13:58:56 +01:00
Harald Pichler 0c7328b59d initial upload 2014-11-19 13:58:50 +01:00
Harald Pichler dfaa8c0f32 initial upload 2014-11-19 13:58:32 +01:00
Harald Pichler 914f5b931b initial upload 2014-11-19 13:58:24 +01:00
Harald Pichler 1b40bccb00 initial upload 2014-11-19 13:58:02 +01:00
powermik 8bb7d82a2d UNSUPPORTED_MADIA_TYPE is a typo 2014-11-19 13:55:59 +01:00
Harald Pichler 21bbe79079 use Arduino like optotriac driver 2014-11-19 13:54:53 +01:00
Harald Pichler 026b961d5e simplify code, bugfixes PE3 2014-11-19 13:54:42 +01:00
Harald Pichler 5f18fc6955 set all colors to the same pin PE5 2014-11-19 13:54:35 +01:00
Harald Pichler 42d3b38c9c optriac sensors use Arduino API 2014-11-19 13:54:28 +01:00
Harald Pichler f7e987cbeb change port manipulation to ardino commands and lets change the pin at runtime possible 2014-11-19 13:54:22 +01:00
Ralf Schlatterbeck 1a1aaa883e Turn off JTAG in adc_init 2014-11-19 13:54:13 +01:00
Ralf Schlatterbeck ef06560465 Use PROCESS_PAUSE macro 2014-11-19 13:54:07 +01:00
Ralf Schlatterbeck 53cf5ab6cf Fix A0-A5 ADC constants, use in example sketch 2014-11-19 13:53:59 +01:00
Ralf Schlatterbeck fbe6ae6a60 Fix off-by-one error in digitalPinToTimer 2014-11-19 13:53:53 +01:00
Ralf Schlatterbeck ddbfd6712c Remove obsolet macro in example 2014-11-19 13:53:44 +01:00
Ralf Schlatterbeck abdf6f8c6b Refactor A/D conversion in adc.c
Now the necessary settings are in adc.h. Refactored to allow repeated
ADC reads without reinitialization. Arduino allows setting
analogReference, this is now also implemented.
ADC is now initialized to sane values in apps/arduino/arduino-process.c
dev/arduino/arduino-compat.h now has all hardware independent settings
for arduino (some moved from platform/osd-merkur/dev/hw-arduino.h).
turnOffPWM re-implemented with hw_timer, removed from wiring_digital.c
ADC-specific arduino stuff moved to arduino-compat.h
Arduinos wiring_analog no longer necessary.
arduino-sketch example now reads analog inputs 1 and 5 using analogRead.
2014-11-19 13:53:32 +01:00
Ralf Schlatterbeck f0ad042bfc Minor optimisations of timer init 2014-11-19 13:53:21 +01:00
Ralf Schlatterbeck d5284eebe1 Factor resources, fix time
Now there is a generic resource that can generate and parse
application/json as well as text/plain. It can be re-used, only the
from_string and to_string routines have to be written and the resource
properly set up. A new resource format is specified, see
GENERIC_RESOURCE in, e.g., examples/osd/pwm-example. This is now used in
all my examples, namely pwm-example, arduino-sketch, wallclock-time.

There was an off by one error for the month in time formatting (in
gmtime and localtime). And the leap-year computation was broken. Both
fixed now, so we get a correct date. For localtime we are still 2 hours
off because daylight saving isn't implemented yet.

Also renamed gmtime to utc.
2014-11-19 13:53:12 +01:00
Ralf Schlatterbeck 4f20df042f Fix leap year computation 2014-11-19 13:53:01 +01:00
Ralf Schlatterbeck fd54bc9ca4 Inline timer init functions, no static storage
Hardware init function profit a great deal from being inlined if the
given parameters are constant -- which is the common use-case, we could
probably call this for all timers and still have less overhead. The
hwtimer_pwm_ini (which calls hwtimer_ini) gets completely computed at
compile-time resulting only in the register settings of hwtimer_ini.

This is now possible because we get rid of static storage for the
max_ticks and instead compute this in hwtimer_pwm_max_ticks from the
timer register settings.
2014-11-19 13:52:42 +01:00
Ralf Schlatterbeck c46d6afa39 Make Arduino timer stuff work on Contiki
New discovery: Contiki also uses timer 0. With almost the same interface
as Arduino. So we now completely get rid of wiring.c (only the main
file, the other wiring_xxx stay) and implement Arduino timer, delay, etc
in terms of the corresponding Contiki routines. Verified that now delay
works as expected. The LED in examples/osd/arduino-sketch blinks!

Before this, the arduino_init routine in wiring.c destroyed the timer-0
initialization of contiki, making both, contiki timer implementation
*and* contiki timer implementation fail if the arduino_init routine was
called. Now both work.

Squashed with following bug-fix commit.
2014-11-19 13:50:58 +01:00
Ralf Schlatterbeck 08abd8807d Fixes for platform timer code
Some platforms are missing timer channels, this is now left to the
(missing) preprocessor definitions on those platforms, no
platform-specific defines needed anymore.
Also fix usage of timer counter register 3 (hardcoded) in
cpu/avr/dev/clock.c -- this code isn't used on many platforms as it
requires a very special quartz clock frequency but this now also uses
the platform timer specification.
2014-11-19 13:48:42 +01:00
Ralf Schlatterbeck b6be226e69 Add Arduino compatibility layer
We can now directly compile arduino sketches (.pde) files.
Arduino compatible analogWrite works now.
But there is still a long way to go, serial I/O and timer stuff (delay,
millis etc) currently don't work (not tested but I don't expect this to
work).
It can be used in an arduino sketch or in a normal contiki program.
We get a PWM frequency of 490.2 Hz (a period of 2.040 ms), that's
Arduino compatible. If you need different frequencies see native timer
usage in examples/osd/pwm-example
In a contiki program you have to call arduino_pwm_timer_init to
initialize the timer before pwm works. The arduino sketch wrapper
already does this.
For running a sketch, see examples/osd/arduino-sketch
2014-11-19 13:48:05 +01:00
Ralf Schlatterbeck b17934c491 Allow compilation of c++ files (extension .cpp) 2014-11-19 13:47:51 +01:00
Ralf Schlatterbeck cfec3c6e2d Initial implementation of avr hardware timer
Mainly for PWM use for now.
With example to set the LED to different brightness via COAP.
We switch the LED with 50 kHz (20µs) in this example.
2014-11-19 13:47:37 +01:00
Harald Pichler 5077010fc0 add i2c driver from Ingo 2014-11-19 13:46:58 +01:00
Harald Pichler 16fa63ebac bugfix read analog 2014-11-19 13:46:14 +01:00
Harald Pichler 4461dca8f2 set 0xABCD default panid 2014-11-19 13:46:07 +01:00
Ralf Schlatterbeck 4ceffb090d Make HW timer for contiki rtimer configurable
... and configure osd platform to use timer 5. With the new
configuration we can use timer 3 for generating hardware PWM.
2014-11-19 13:44:55 +01:00
Ralf Schlatterbeck b4fb8c3f52 Add wallclock time handling
New application and new example.
We use the built-in timer routines and add an offset to get the
wallclock time. The offset can be set by time-changing routines
(currently only settimeofday).
We also maintain an offset for timezone handling but this isn't
currently fully implemented.
2014-11-19 13:43:45 +01:00
Harald Pichler b886a1faaf initial upload 2014-11-19 13:43:19 +01:00
Harald Pichler 15bab74093 initial upload 2014-11-19 13:43:12 +01:00
Harald Pichler 465eb28382 cleanup code 2014-11-19 13:43:05 +01:00
Harald Pichler 38dbf611e6 add Arduino pin definition and commands 2014-11-19 13:42:57 +01:00
Harald Pichler 7c0cd36a77 bugfix define panid 2014-11-19 13:42:47 +01:00
Ralf Schlatterbeck 56f6f87c94 Allow changing bootloader_get_mac address
Current default in the Makefile is the *new* bootloader address.
But for backward compatibility we've modified the run*.sh files
to use the old address. The run*.sh also now explain how to change
the default.
2014-11-19 13:42:35 +01:00
Harald Pichler 1efbe0736a change resources to simple and make climate2 default 2014-11-19 13:42:13 +01:00
Harald Pichler d90e0d622d get s/button ->show button status 0/1 2014-11-19 13:42:05 +01:00
Harald Pichler c106898d2b add 0.5s delay between off and on 2014-11-19 13:41:54 +01:00
Harald Pichler 94d764e4cb add timer and shutter functionality 2014-11-19 13:41:48 +01:00
Harald Pichler 4d383eb923 change to port F6,F7 2014-11-19 13:41:18 +01:00
Harald Pichler 678891a1a9 change battery and cpttem format to xx.xx 2014-11-19 13:41:08 +01:00
Harald Pichler a656cf1dcd add shutter control resources, reset,timer 2014-11-19 13:41:00 +01:00
Harald Pichler 03a4081913 add contiki led, remove led1,led2 2014-11-19 13:40:52 +01:00
Harald Pichler 8905f35d72 simplify project-conf.h 2014-11-19 13:40:45 +01:00
Harald Pichler 26b1e874d6 bugfix statusled include 2014-11-19 13:40:38 +01:00
Harald Pichler affe81cc6d bugfix includes and names 2014-11-19 13:40:29 +01:00
Harald Pichler a16849120f adapt new names and api 2014-11-19 13:40:09 +01:00
Harald Pichler 1ca7b52217 remove not needed binary files 2014-11-19 13:39:43 +01:00
Harald Pichler 46df18ceb1 add /s/cputemp resource 2014-11-19 13:39:26 +01:00
Harald Pichler a90a6e0f65 add /p/name and p/model resource, remove info 2014-11-19 13:39:19 +01:00
Harald Pichler 964164b157 remove t4 driver at the moment, config problem 2014-11-19 13:39:11 +01:00
Marcus Priesch 630bd8e9e4 Factored to support configurable amount of pwm's, fixes 2014-11-19 13:38:58 +01:00
Marcus Priesch 85d29b6473 initial check in 2014-11-19 13:38:51 +01:00
Harald Pichler 088c7118e0 compile all osd-examples 2014-11-19 13:38:38 +01:00
Harald Pichler 4760891bb4 simplified led resource to one led actuator 2014-11-19 13:38:29 +01:00
Harald Pichler 425f348daa initial upload 2014-11-19 13:38:16 +01:00
Harald Pichler 11b13a7a7e remove link status and bugfix params.c 2014-11-19 13:37:41 +01:00
Harald Pichler f2bd00b660 add patch milligrad ds1820 from Jan-Benedict Glaw 2014-11-19 13:37:33 +01:00
Harald Pichler 9906e9736c temp and hum sensors values xxxx -> xx.xx 2014-11-19 13:37:21 +01:00
Harald Pichler e5baf940e7 add dhtxx temp coap 2014-11-19 13:37:13 +01:00
Harald Pichler 1b04a24022 config panid over defines 2014-11-19 13:37:06 +01:00
Harald Pichler 8b323633cd define new tria pins, configurable type ligt or shutter or plug 2014-11-19 13:36:58 +01:00
Harald Pichler 35668c8aed initial upload 2014-11-19 13:36:52 +01:00
Harald Pichler 7ea29294d7 cleanup code add coap13 support 2014-11-19 13:36:44 +01:00
Harald Pichler 2408af0b93 remove xmac config 2014-11-19 13:36:35 +01:00
Harald Pichler fd57fcef72 cleanup code, add coap13 support 2014-11-19 13:36:28 +01:00
Harald Pichler a9b36497f6 del unused files 2014-11-19 13:36:19 +01:00
Harald Pichler 3a3091c884 del unused file 2014-11-19 13:36:10 +01:00
Harald Pichler f7e4fb6499 code cleanup 2014-11-19 13:35:58 +01:00
Harald Pichler cc950ace98 cleanup code 2014-11-19 13:35:47 +01:00
Harald Pichler 96f1264120 remove old project use climate instead 2014-11-19 13:35:36 +01:00
Harald Pichler fa7920952f delete old example 2014-11-19 13:35:27 +01:00
Harald Pichler c3f00a7106 cleanup code 2014-11-19 13:35:18 +01:00
Harald Pichler 829cd2517d cleanup code 2014-11-19 13:35:10 +01:00
Harald Pichler ab16ebd4ea bugfix nbr name xmac 2014-11-19 13:35:04 +01:00
Harald Pichler 09813190aa 20 neighbors with status and routes 2014-11-19 13:34:55 +01:00
Harald Pichler 171c1290c3 update boarder router to new rpl tables 2014-11-19 13:34:47 +01:00
Harald Pichler dd917c3260 bugfix server client demo 2014-11-19 13:34:37 +01:00
Harald Pichler e2edd006d4 initial upload 2014-11-19 13:34:27 +01:00
Harald Pichler 837f70770a cleanup plattform defines, disable energest, radiostatistics 2014-11-19 13:34:20 +01:00
Harald Pichler 34d64b4eb0 bugfix blockmode, 8 Hz dutycyle as standard 2014-11-19 13:34:07 +01:00
Harald Pichler 1093989aef bugfix CS cast to uint8_t 2014-11-19 13:33:59 +01:00
Harald Pichler 29c7297591 bugfix RH03 sensor 2014-11-19 13:33:50 +01:00
Harald Pichler 45ede69308 add dht22 and RHT03 support 2014-11-19 13:33:40 +01:00
Harald Pichler 8f85f7fb0a bugfix new dresden module 32khz 2014-11-19 13:33:31 +01:00
Harald Pichler 7cc5312937 update coap13 2014-11-19 13:33:02 +01:00
Harald Pichler 666ca8436b bugfix wrong define 2014-11-19 13:32:53 +01:00
Harald Pichler cead1c7ce0 use batmon in battery_sensor 2014-11-19 13:32:41 +01:00
Harald Pichler ae732f4636 initial upload 2014-11-19 13:32:31 +01:00
Harald Pichler bd45ee7aea add coap 13 support 2014-11-19 13:32:23 +01:00
Harald Pichler d85ce4b42b initial upload 2014-11-19 13:32:12 +01:00
Harald Pichler decc9fcb0f bugfix buffers 2014-11-19 13:32:03 +01:00
Harald Pichler 21bd674622 bugfix buffers 2014-11-19 13:31:53 +01:00
Harald Pichler db823713eb bugfix packet loss
Conflicts:
	platform/osd-merkur/contiki-main.c
2014-11-19 13:31:33 +01:00
Harald Pichler 0881290bbc add coap 13 2014-11-19 13:24:58 +01:00
Harald Pichler 532063c422 bugfix compile error 2014-11-19 13:24:47 +01:00
Harald Pichler 89723ebfa8 bugfix hw_init() 2014-11-19 13:24:32 +01:00
Harald Pichler deea693f82 bugfix led button battery 2014-11-19 13:24:06 +01:00
Harald Pichler ba2e08aebf update to caop 13 2014-11-19 13:23:28 +01:00
Harald Pichler 48fff35bd9 update for new contiki fetch 2014-11-19 13:22:20 +01:00
Harald Pichler e9c033688b bugfix 2014-11-19 13:21:52 +01:00
Harald Pichler 15709add91 initial upload 2014-11-19 13:20:12 +01:00
Harald Pichler 1fc136d379 add BOOTLOADER_GET_MAC
Conflicts:
	platform/osd-merkur/params.h
2014-11-19 13:19:44 +01:00
Harald Pichler d5ca328050 initial upload 2014-11-19 13:14:29 +01:00
Harald Pichler b1e1ef1ffd periodic prints configurable 2014-11-19 13:14:20 +01:00
Harald Pichler 558184f106 remove unused code, bugfix const 2014-11-19 13:14:07 +01:00
Harald Pichler 3f9e1962a1 bugfix accept type const 2014-11-19 13:13:58 +01:00
Harald Pichler 909bdd2d90 bugfix pullup key_init 2014-11-19 13:13:50 +01:00
Harald Pichler d1bf2bbb69 add button logic 2014-11-19 13:13:41 +01:00
Harald Pichler a66fb13e4f cleanup debug prints 2014-11-19 13:13:09 +01:00
Harald Pichler 795580b6ae bugfix ->startup led red off 2014-11-19 13:12:51 +01:00
Harald Pichler 88ae1828f9 remove debug code 2014-11-19 13:12:43 +01:00
Harald Pichler 245d801862 add merkurboard coap client demo 2014-11-19 12:14:24 +01:00
Harald Pichler a4986b71dc add isr 2014-11-19 12:14:08 +01:00
Harald Pichler b992fc43cc etimer read buttons 2014-11-19 12:13:51 +01:00
Harald Pichler 617dfba4cb add pcint buttons 2014-11-19 12:13:33 +01:00
Andreas Reder 03b7dc8719 added run.sh and flash.sh 2014-11-19 12:13:09 +01:00
Harald Pichler 673b167f8f cleanup er-rest-example-merkurboard 2014-11-19 12:11:40 +01:00
Marcus Priesch 42c28e0bf7 timer4 servo pwm 2014-11-19 12:11:19 +01:00
Marcus Priesch 277f63d76a timer4 servo pwm 2014-11-19 12:10:09 +01:00
Harald Pichler 54114b0943 many bugfixes, add cputemp 2014-11-19 12:07:31 +01:00
Harald Pichler b33ea9659c add relay 2014-11-19 12:07:22 +01:00
Harald Pichler fbd4b0be9c add debug led code 2014-11-19 12:07:14 +01:00
Harald Pichler e645833a99 add light-actor 2014-11-19 12:06:54 +01:00
Harald Pichler 8c08364cad add servo example 2014-11-19 12:06:45 +01:00
Harald Pichler cb41c216e9 bugfix compile and flash 2014-11-19 12:06:34 +01:00
Harald Pichler f6fa014a1f add merkur board example 2014-11-19 12:06:23 +01:00
Harald Pichler 300716164c change plattform to osd-merkur 2014-11-19 12:05:54 +01:00
Harald Pichler c5a9a22e0f change plattform to osd-merkur 2014-11-19 12:05:46 +01:00
Harald Pichler 3c142b8bbb change plattform to osd-merkur 2014-11-19 12:05:35 +01:00
Harald Pichler 562434e90e change plattform to osd-merkur 2014-11-19 12:05:27 +01:00
Harald Pichler e9196aebb7 change plattform to osd-merkur 2014-11-19 12:05:19 +01:00
Harald Pichler 30b8d433f9 change plattform to osd-merkur 2014-11-19 12:05:12 +01:00
Harald Pichler 37d8ca16fe change plattform to osd-merkur 2014-11-19 12:05:03 +01:00
Harald Pichler 81e6734626 add climate example 2014-11-19 12:04:53 +01:00
Harald Pichler 715cfa3a75 add platform osd-merkur 2014-11-19 12:04:38 +01:00
Harald Pichler cd194ae1ab remove old files 2014-11-19 12:04:20 +01:00
Harald Pichler d00df76ada cleanup project 2014-11-19 12:04:04 +01:00
Harald Pichler 892de50059 cleanup code 2014-11-19 12:03:50 +01:00
Harald Pichler c4c92ea630 add button sensor with debug 2014-11-19 12:03:35 +01:00
Harald Pichler fc6055b420 initial upload 2014-11-19 12:03:04 +01:00
Harald Pichler ff15332aa5 change rt tag and disable energest and radio stat 2014-11-19 12:02:39 +01:00
Harald Pichler 808a249862 add battery sensor 2014-11-19 12:01:49 +01:00
Harald Pichler ab3f3c8644 setup 15 NBR 50 DS6-Route 2014-11-19 12:01:22 +01:00
Harald Pichler 2c172bfd31 update to latest version 2014-11-19 12:01:09 +01:00
Harald Pichler 30b5333123 remove if attribute 2014-11-19 12:00:59 +01:00
Harald Pichler c4d8e6a6e8 use ds1820.c from /dev directory 2014-11-19 12:00:28 +01:00
Harald Pichler 5ac3e3a220 new dht11 uri schema 2014-11-19 12:00:01 +01:00
Harald Pichler 9e2f71b7d8 add sensors, internal temperature, battery 2014-11-19 11:59:37 +01:00
Harald Pichler 3019a8e3ef add DHT11 humidity sensor 2014-11-19 11:58:21 +01:00
Harald Pichler a6a1a7b375 initial upload 2014-11-19 11:57:16 +01:00
Harald Pichler 17c7e35621 initial upload 2014-11-19 11:56:43 +01:00
harald42 19561efacb update project to coap 13 2014-11-14 15:59:22 +01:00
harald42 dfa4da2e98 initial upload 2014-11-14 11:02:45 +01:00
harald42 ee1759ba4a initial upload 2014-11-14 10:46:30 +01:00
harald42 114d7e883a Merge branch 'master' of https://github.com/osdomotics/osd-contiki 2014-10-23 11:07:48 +02:00
harald42 408d1cabfe initial upload 2014-10-23 11:06:25 +02:00
harald42 8ed94bf819 initial upload 2014-10-11 22:53:08 +02:00
Billy Everyteen 9f4f828976 initial upload 2014-09-18 15:08:55 +02:00
harald42 2ae3d60203 Merge pull request #1 from powermik/UNSUPPORTED_MADIA_TYPE
UNSUPPORTED_MADIA_TYPE is a typo
2014-08-05 07:17:04 +02:00
powermik d7a6d8560a UNSUPPORTED_MADIA_TYPE is a typo 2014-08-04 20:14:40 +02:00
Jim Paris e09abcaa96 Increase fixed filename sizes in SLIP tunnels
Long serial port names like
  /dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DN0038W8-if00-port0
cause crashes.  This is the simplest fix to avoid the problem.
2014-07-28 11:49:45 +02:00
harald fa53bc3241 use Arduino like optotriac driver 2014-07-15 13:35:31 +02:00
harald c25dc70d26 simplify code, bugfixes PE3 2014-07-15 08:23:33 +02:00
harald ccaae9cd5c set all colors to the same pin PE5 2014-07-15 08:20:46 +02:00
harald cead73a4d6 optriac sensors use Arduino API 2014-07-14 20:31:04 +02:00
harald ff8b6d933b change port manipulation to ardino commands and lets change the pin at runtime possible 2014-07-11 11:25:22 +02:00
Ralf Schlatterbeck 1aa694bba2 Turn off JTAG in adc_init 2014-06-30 14:25:33 +02:00
Ralf Schlatterbeck f61d0b2e1e Use PROCESS_PAUSE macro 2014-06-30 10:25:47 +02:00
Ralf Schlatterbeck 4b984153ab Fix A0-A5 ADC constants, use in example sketch 2014-06-30 10:24:49 +02:00
Ralf Schlatterbeck 60156d1c48 Fix off-by-one error in digitalPinToTimer 2014-06-29 18:06:48 +02:00
Ralf Schlatterbeck d8bc9f761c Remove obsolet macro in example 2014-06-29 17:32:00 +02:00
Ralf Schlatterbeck 77c02d58f8 Refactor A/D conversion in adc.c
Now the necessary settings are in adc.h. Refactored to allow repeated
ADC reads without reinitialization. Arduino allows setting
analogReference, this is now also implemented.
ADC is now initialized to sane values in apps/arduino/arduino-process.c
dev/arduino/arduino-compat.h now has all hardware independent settings
for arduino (some moved from platform/osd-merkur/dev/hw-arduino.h).
turnOffPWM re-implemented with hw_timer, removed from wiring_digital.c
ADC-specific arduino stuff moved to arduino-compat.h
Arduinos wiring_analog no longer necessary.
arduino-sketch example now reads analog inputs 1 and 5 using analogRead.
2014-06-29 17:26:15 +02:00
Ralf Schlatterbeck 6c06f43417 Minor optimisations of timer init 2014-06-29 17:12:13 +02:00
Ralf Schlatterbeck 4643c5d02d Factor resources, fix time
Now there is a generic resource that can generate and parse
application/json as well as text/plain. It can be re-used, only the
from_string and to_string routines have to be written and the resource
properly set up. A new resource format is specified, see
GENERIC_RESOURCE in, e.g., examples/osd/pwm-example. This is now used in
all my examples, namely pwm-example, arduino-sketch, wallclock-time.

There was an off by one error for the month in time formatting (in
gmtime and localtime). And the leap-year computation was broken. Both
fixed now, so we get a correct date. For localtime we are still 2 hours
off because daylight saving isn't implemented yet.

Also renamed gmtime to utc.
2014-06-27 22:25:51 +02:00
Ralf Schlatterbeck 9df7ab3875 Fix leap year computation 2014-06-27 22:10:19 +02:00
Ralf Schlatterbeck 72da6659ed Inline timer init functions, no static storage
Hardware init function profit a great deal from being inlined if the
given parameters are constant -- which is the common use-case, we could
probably call this for all timers and still have less overhead. The
hwtimer_pwm_ini (which calls hwtimer_ini) gets completely computed at
compile-time resulting only in the register settings of hwtimer_ini.

This is now possible because we get rid of static storage for the
max_ticks and instead compute this in hwtimer_pwm_max_ticks from the
timer register settings.
2014-06-26 20:37:34 +02:00
Ralf Schlatterbeck c5d25f5bfe Last minute bug-fix of arduino-sketch
... happens when not completing testing before pushing commit :-)
2014-06-26 19:07:48 +02:00
Ralf Schlatterbeck f0f5391409 Make Arduino timer stuff work on Contiki
New discovery: Contiki also uses timer 0. With almost the same interface
as Arduino. So we now completely get rid of wiring.c (only the main
file, the other wiring_xxx stay) and implement Arduino timer, delay, etc
in terms of the corresponding Contiki routines. Verified that now delay
works as expected. The LED in examples/osd/arduino-sketch blinks!

Before this, the arduino_init routine in wiring.c destroyed the timer-0
initialization of contiki, making both, contiki timer implementation
*and* contiki timer implementation fail if the arduino_init routine was
called. Now both work.
2014-06-26 18:37:13 +02:00
Ralf Schlatterbeck b6e20bf6c0 Fixes for platform timer code
Some platforms are missing timer channels, this is now left to the
(missing) preprocessor definitions on those platforms, no
platform-specific defines needed anymore.
Also fix usage of timer counter register 3 (hardcoded) in
cpu/avr/dev/clock.c -- this code isn't used on many platforms as it
requires a very special quartz clock frequency but this now also uses
the platform timer specification.
2014-06-26 18:00:30 +02:00
Ralf Schlatterbeck e65dabb119 Add Arduino compatibility layer
We can now directly compile arduino sketches (.pde) files.
Arduino compatible analogWrite works now.
But there is still a long way to go, serial I/O and timer stuff (delay,
millis etc) currently don't work (not tested but I don't expect this to
work).
It can be used in an arduino sketch or in a normal contiki program.
We get a PWM frequency of 490.2 Hz (a period of 2.040 ms), that's
Arduino compatible. If you need different frequencies see native timer
usage in examples/osd/pwm-example
In a contiki program you have to call arduino_pwm_timer_init to
initialize the timer before pwm works. The arduino sketch wrapper
already does this.
For running a sketch, see examples/osd/arduino-sketch
2014-06-26 11:00:01 +02:00
Ralf Schlatterbeck 87903b2e89 Allow compilation of c++ files (extension .cpp) 2014-06-26 08:37:19 +02:00
Ralf Schlatterbeck 5991c3e3db Initial implementation of avr hardware timer
Mainly for PWM use for now.
With example to set the LED to different brightness via COAP.
We switch the LED with 50 kHz (20µs) in this example.
2014-06-22 13:32:05 +02:00
harald d192553309 add i2c driver from Ingo 2014-06-21 21:30:48 +02:00
Benoît Thébaudeau db60afb2fb leds: Add the leds_set() function
The leds_set() function is added on top of leds_arch_set() in order to have a
means of displaying a pattern on a set of LEDs, while keeping the ENERGEST
information up to date, which would be missing with a direct call to
leds_arch_set().

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
2014-06-18 12:39:02 +02:00
Nicolas Tsiftes df0cc061f6 Do not copy more bytes than the filename string contains. 2014-06-18 11:37:34 +02:00
Rémy Léone a952a96b6e Closing doxygen groups
(cherry picked from commit 25c8b0835d)
2014-06-02 14:54:17 +02:00
harald 45dee77092 bugfix read analog 2014-06-02 13:46:54 +02:00
harald b398ab9288 set 0xABCD default panid 2014-06-02 13:44:54 +02:00
Ralf Schlatterbeck e88f60feee Make HW timer for contiki rtimer configurable
... and configure osd platform to use timer 5. With the new
configuration we can use timer 3 for generating hardware PWM.
2014-05-31 16:17:07 +02:00
Ralf Schlatterbeck 478d91ac53 Fix lots of compiler warnings 2014-05-31 15:52:33 +02:00
Ralf Schlatterbeck 47d1c2a74d Merge branch 'master' of github.com:osdomotics/osd-contiki 2014-05-29 17:37:00 +02:00
Ralf Schlatterbeck f48566d51f Add wallclock time handling
New application and new example.
We use the built-in timer routines and add an offset to get the
wallclock time. The offset can be set by time-changing routines
(currently only settimeofday).
We also maintain an offset for timezone handling but this isn't
currently fully implemented.
2014-05-29 17:31:19 +02:00
harald 0c29b2b7db initial upload 2014-05-27 11:34:10 +02:00
harald 2d424bd259 initial upload 2014-05-27 11:33:10 +02:00
harald 078faa39d4 cleanup code 2014-05-27 11:31:54 +02:00
harald 90ed9d14d2 add Arduino pin definition and commands 2014-05-22 16:25:15 +02:00
harald 2a63d0a972 bugfix define panid 2014-05-15 15:34:05 +02:00
Ralf Schlatterbeck be01bf77a9 Allow changing bootloader_get_mac address
Current default in the Makefile is the *new* bootloader address.
But for backward compatibility we've modified the run*.sh files
to use the old address. The run*.sh also now explain how to change
the default.
2014-05-13 16:56:59 +02:00
harald 0a5872e261 change resources to simple and make climate2 default 2014-05-08 13:04:27 +02:00
harald 5fcac26e80 get s/button ->show button status 0/1 2014-04-30 15:20:25 +02:00
harald 40bd9950d1 add 0.5s delay between off and on 2014-04-24 13:55:21 +02:00
harald 59bd18df7d add timer and shutter functionality 2014-04-23 16:13:58 +02:00
harald 598a0da30d change to port F6,F7 2014-04-23 16:13:23 +02:00
harald ac79f1b596 change battery and cpttem format to xx.xx 2014-04-16 09:31:48 +02:00
harald b0c8597dbc add shutter control resources, reset,timer 2014-04-15 17:29:05 +02:00
harald b6e0ef1d95 add contiki led, remove led1,led2 2014-04-15 07:27:33 +02:00
harald f77717158d simplify project-conf.h 2014-04-15 07:27:33 +02:00
harald f9d67ed10c bugfix statusled include 2014-04-15 07:27:33 +02:00
harald f40bf6d803 bugfix includes and names 2014-04-15 07:27:33 +02:00
harald 59713f6d3b adapt new names and api 2014-04-15 07:27:33 +02:00
harald 67dba47c23 remove not needed binary files 2014-04-15 07:27:33 +02:00
harald aa568a28a3 add /s/cputemp resource 2014-04-15 07:27:32 +02:00
harald f9abb44d6e add /p/name and p/model resource, remove info 2014-04-15 07:27:32 +02:00
harald 86cd1ec02f remove t4 driver at the moment, config problem 2014-04-15 07:27:32 +02:00
Marcus Priesch 992e54fe25 Factored to support configurable amount of pwm's, fixes 2014-04-15 07:27:32 +02:00
Marcus Priesch bf6f388691 initial check in 2014-04-15 07:27:32 +02:00
harald 67783600aa compile all osd-examples 2014-04-15 07:27:32 +02:00
harald 251abdda29 simplified led resource to one led actuator 2014-04-15 07:27:32 +02:00
harald d87287b745 initial upload 2014-04-15 07:27:32 +02:00
harald d8d0a507e1 remove link status and bugfix params.c 2014-04-15 07:27:32 +02:00
harald 11b7022ce6 add patch milligrad ds1820 from Jan-Benedict Glaw 2014-04-15 07:27:32 +02:00
harald 87028c1f60 temp and hum sensors values xxxx -> xx.xx 2014-04-15 07:27:32 +02:00
harald f8c298a495 add dhtxx temp coap 2014-04-15 07:27:32 +02:00
harald 51f179eacf config panid over defines 2014-04-15 07:27:32 +02:00
harald 1f586c7735 define new tria pins, configurable type ligt or shutter or plug 2014-04-15 07:27:32 +02:00
harald42 7d354d8a37 initial upload 2014-04-15 07:27:32 +02:00
harald42 2ddd2ba38a cleanup code add coap13 support 2014-04-15 07:27:32 +02:00
harald42 b50f4e2119 remove xmac config 2014-04-15 07:27:32 +02:00
harald42 806de3f204 cleanup code, add coap13 support 2014-04-15 07:27:32 +02:00
harald42 15167d541e del unused files 2014-04-15 07:27:31 +02:00
harald42 39a830d9a9 del unused file 2014-04-15 07:27:31 +02:00
harald42 116ce888c4 code cleanup 2014-04-15 07:27:31 +02:00
harald42 184dee491e cleanup code 2014-04-15 07:27:31 +02:00
harald42 4f05557905 remove old project use climate instead 2014-04-15 07:27:31 +02:00
harald42 1b56526fe0 delete old example 2014-04-15 07:27:31 +02:00
harald42 aac4fcc8e1 cleanup code 2014-04-15 07:27:31 +02:00
harald42 3c0908f2da cleanup code 2014-04-15 07:27:31 +02:00
harald42 1464292188 bugfix nbr name xmac 2014-04-15 07:27:31 +02:00
harald42 d3eb7da297 20 neighbors with status and routes 2014-04-15 07:27:31 +02:00
harald42 0a14fd6a18 update boarder router to new rpl tables 2014-04-15 07:27:31 +02:00
harald42 337be76b26 bugfix server client demo 2014-04-15 07:27:31 +02:00
harald42 da39da39dc initial upload 2014-04-15 07:27:31 +02:00
harald42 afa20ee0ae cleanup plattform defines, disable energest, radiostatistics 2014-04-15 07:27:31 +02:00
harald42 aea396e542 bugfix blockmode, 8 Hz dutycyle as standard 2014-04-15 07:27:31 +02:00
harald42 0ef2ce8e5c bugfix CS cast to uint8_t 2014-04-15 07:27:31 +02:00
harald42 7b46026b52 bugfix RH03 sensor 2014-04-15 07:27:31 +02:00
harald42 310234e0dc add dht22 and RHT03 support 2014-04-15 07:27:30 +02:00
harald42 7001e8fa33 bugfix new dresden module 32khz 2014-04-15 07:27:30 +02:00
harald a58322a62b with coap13 2014-04-15 07:27:30 +02:00
harald ffae9fce58 update coap13 2014-04-15 07:27:30 +02:00
harald42 4a981f1c47 bugfix wrong define 2014-04-15 07:27:30 +02:00
harald42 b6bea56c27 use batmon in battery_sensor 2014-04-15 07:27:30 +02:00
harald42 ff227b7a04 initial upload 2014-04-15 07:27:30 +02:00
harald42 7ee65e72a5 add coap 13 support 2014-04-15 07:27:30 +02:00
Harald Pichler 16c8c3853d initial upload 2014-04-15 07:27:30 +02:00
harald42 015a6a3c65 bugfix buffers 2014-04-15 07:27:30 +02:00
harald42 1968ebc626 bugfix buffers 2014-04-15 07:27:30 +02:00
harald42 58504df2c4 bugfix packet loss 2014-04-15 07:27:30 +02:00
Andreas Reder d5eda89c39 changed char c to signed char c to be compatible to armhf architecture 2014-04-15 07:27:30 +02:00
harald42 9c1b87bbb9 add coap 13 2014-04-15 07:27:30 +02:00
harald42 5c3303eef0 bugfix compile error 2014-04-15 07:27:30 +02:00
harald42 cd715cb222 bugfix hw_init() 2014-04-15 07:27:29 +02:00
harald42 2441cc38ee bugfix led button battery 2014-04-15 07:27:29 +02:00
harald42 11d4c9553e update to caop 13 2014-04-15 07:27:29 +02:00
harald42 312a88ad39 update for new contiki fetch 2014-04-15 07:27:29 +02:00
harald42 243fd6f11e bugfix binarys 2014-04-15 07:27:29 +02:00
harald42 ae7b37d1c3 add binarys 2014-04-15 07:27:29 +02:00
harald42 7478d719cf initial upload 2014-04-15 07:27:29 +02:00
harald42 611e358ad9 add BOOTLOADER_GET_MAC 2014-04-15 07:27:29 +02:00
harald42 b27469d218 initial upload 2014-04-15 07:27:29 +02:00
harald42 ec5210b562 periodic prints configurable 2014-04-15 07:27:29 +02:00
Harald Pichler 080eadc79b remove unused code, bugfix const 2014-04-15 07:27:29 +02:00
Harald Pichler ef5b9474fd bugfix accept type const 2014-04-15 07:27:29 +02:00
harald42 71f8352876 bugfix pullup key_init 2014-04-15 07:27:28 +02:00
harald42 c265e72b24 add button logic 2014-04-15 07:27:28 +02:00
harald42 8628af93e1 cleanup debug prints 2014-04-15 07:27:28 +02:00
Andreas Reder 19ec02773f corrected bug when changing panid 2014-04-15 07:27:28 +02:00
harald42 765129fde2 bugfix ->startup led red off 2014-04-15 07:27:28 +02:00
harald42 32d077790f remove debug code 2014-04-15 07:27:28 +02:00
harald42 cdf4da8461 add merkurboard coap client demo 2014-04-15 07:27:28 +02:00
harald42 797c3da239 add isr 2014-04-15 07:27:28 +02:00
harald42 25fb513164 etimer read buttons 2014-04-15 07:27:28 +02:00
harald42 ae3d5e4966 add pcint buttons 2014-04-15 07:27:28 +02:00
Andreas Reder 6184e5715b corrected border-router resources, added run.sh and flash.sh 2014-04-15 07:27:28 +02:00
harald42 d8d1550400 cleanup er-rest-example-merkurboard 2014-04-15 07:27:28 +02:00
harald42 7383f6708b timer4 servo pwm from Priesch Markus 2014-04-15 07:27:28 +02:00
harald42 3d10f4d0d1 timer4 servo pwm from Priesch Markus 2014-04-15 07:27:28 +02:00
harald42 0deca185bb many bugfixes, add cputemp 2014-04-15 07:27:28 +02:00
harald42 6d30a5b66e add relay 2014-04-15 07:27:28 +02:00
harald42 8cdf981c8f add debug led code 2014-04-15 07:27:27 +02:00
Andreas Reder 8d5f623b6a turned off debugging 2014-04-15 07:27:27 +02:00
Andreas Reder 85fb0b1e48 added info resource 2014-04-15 07:27:27 +02:00
Andreas Reder 3783d5f059 created osd native border router with coap server to get rpl table and change panid 2014-04-15 07:27:27 +02:00
andreas@reder.eu 86a6d88799 PARAMS_PANID is now defined in contiki-conf and no longer in params.h to be able
to change framer panid
2014-04-15 07:27:27 +02:00
andreas@reder.eu 46010cbbd6 bugfix: panid is now correctly loaded from eeprom and set in mac framer and radio on startup 2014-04-15 07:27:27 +02:00
AndreasReder 20e8eba08b changed slip-radio to be able to change panid over slip command 2014-04-15 07:27:27 +02:00
AndreasReder 033adfa678 changed mac framer to be able to change panid during runtime
example:
#include "net/mac/framer-802154.h"
uint16_t panid = 1234;
framer_802154_set_panid(panid);

attention: this only changes the framer panid, you need to change
the radio panid too, e.g. with rf230_set_pan_addr on avr atmega128rfa1
2014-04-15 07:27:27 +02:00
harald42 057a3c3345 add light-actor 2014-04-15 07:27:27 +02:00
harald42 bba7b84a15 add servo example 2014-04-15 07:27:27 +02:00
harald42 36e0dcf22f bugfix compile and flash 2014-04-15 07:27:27 +02:00
harald42 c8604b5a70 add merkur board example 2014-04-15 07:27:27 +02:00
harald42 43b9f7a23d remove platform/osd-er-lp24 2014-04-15 07:27:27 +02:00
harald42 2a495ace3b change plattform to osd-merkur 2014-04-15 07:27:27 +02:00
harald42 5ee13bf528 change plattform to osd-merkur 2014-04-15 07:27:27 +02:00
harald42 33639c15e1 change plattform to osd-merkur 2014-04-15 07:27:27 +02:00
harald42 618a516182 change plattform to osd-merkur 2014-04-15 07:27:26 +02:00
harald42 b6c7cc8672 change plattform to osd-merkur 2014-04-15 07:27:26 +02:00
harald42 4d93071bf9 change plattform to osd-merkur 2014-04-15 07:27:26 +02:00
harald42 6d0bdab9f0 change plattform to osd-merkur 2014-04-15 07:27:26 +02:00
harald42 7f776ee918 add climate example 2014-04-15 07:27:26 +02:00
harald42 a6634acc50 add platform osd-merkur 2014-04-15 07:27:26 +02:00
harald42 b31a3397e0 remove merkur 2014-04-15 07:27:26 +02:00
harald42 b6f96951be add merkur platform 2014-04-15 07:27:26 +02:00
harald42 23394cd1f5 remove old files 2014-04-15 07:27:26 +02:00
harald42 252454c016 remove debug, minimize code size 2014-04-15 07:27:26 +02:00
harald42 a2387f43af cleanup project 2014-04-15 07:27:26 +02:00
harald42 641aad70a9 initial upload 2014-04-15 07:27:26 +02:00
harald42 32ab451fff add pir sensor, sensor events 2014-04-15 07:27:26 +02:00
harald42 a1152fd96e cleanup code 2014-04-15 07:27:26 +02:00
harald42 356ea01a8d add button sensor with debug 2014-04-15 07:27:26 +02:00
harald42 48217bcf80 initial upload 2014-04-15 07:27:26 +02:00
harald42 104be3acfb initial upload 2014-04-15 07:27:26 +02:00
harald42 ac235b9c57 make easyer experiments 2014-04-15 07:27:25 +02:00
harald42 b2040a6cd9 change rt tag and disable energest and radio stat 2014-04-15 07:27:25 +02:00
harald42 2e35f2225d cleanup code 2014-04-15 07:27:25 +02:00
harald42 ff022fce05 add battery sensor 2014-04-15 07:27:25 +02:00
harald42 538bb6075c setup 15 NBR 50 DS6-Route 2014-04-15 07:27:25 +02:00
harald42 86c4214014 update to latest version 2014-04-15 07:27:25 +02:00
harald42 1f12531618 remove if attribute 2014-04-15 07:27:25 +02:00
harald42 65341d8d3b use ds1820.c from /dev directory 2014-04-15 07:27:25 +02:00
harald42 90885f2168 new dht11 uri schema 2014-04-15 07:27:25 +02:00
harald42 e92678a847 add sensors, internal temperature, battery 2014-04-15 07:27:25 +02:00
harald 17c93b259e add DHT11 humidity sensor 2014-04-15 07:27:25 +02:00
harald 56807ee75a initial upload 2014-04-15 07:27:25 +02:00
harald 2b7e7b8f8c bugfix ds1820 2014-04-15 07:27:25 +02:00
harald 92b835080b initial upload 2014-04-15 07:27:25 +02:00
1213 changed files with 151419 additions and 185 deletions

7
.gitmodules vendored
View file

@ -4,16 +4,15 @@
[submodule "tools/cc2538-bsl"] [submodule "tools/cc2538-bsl"]
path = tools/cc2538-bsl path = tools/cc2538-bsl
url = https://github.com/JelmerT/cc2538-bsl.git url = https://github.com/JelmerT/cc2538-bsl.git
[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"]
path = cpu/cc26xx-cc13xx/lib/cc26xxware
url = https://github.com/contiki-os/cc26xxware.git
[submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"] [submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"]
path = cpu/cc26xx-cc13xx/lib/cc13xxware path = cpu/cc26xx-cc13xx/lib/cc13xxware
url = https://github.com/contiki-os/cc13xxware.git url = https://github.com/contiki-os/cc13xxware.git
[submodule "platform/stm32nucleo-spirit1/stm32cube-lib"] [submodule "platform/stm32nucleo-spirit1/stm32cube-lib"]
path = platform/stm32nucleo-spirit1/stm32cube-lib path = platform/stm32nucleo-spirit1/stm32cube-lib
url = https://github.com/STclab/stm32nucleo-spirit1-lib url = https://github.com/STclab/stm32nucleo-spirit1-lib
[submodule "tools/sensniff"] [submodule "tools/sensniff"]
path = tools/sensniff path = tools/sensniff
url = https://github.com/g-oikonomou/sensniff.git url = https://github.com/g-oikonomou/sensniff.git
[submodule "apps/tinydtls"]
path = apps/tinydtls
url = https://github.com/iot-lab/armour-tinydtls.git

494
LICENSE
View file

@ -1,3 +1,37 @@
A note on Licensing (2017-03-17):
Github has recently (2017-03-01) changed their license terms:
https://help.github.com/articles/github-terms-of-service/
There were comments that this may violate some GPL and creative commons
licenses:
http://joeyh.name/blog/entry/removing_everything_from_github/
https://www.mirbsd.org/permalinks/wlog-10_e20170301-tg.htm
But also voices that don't see a problem:
https://www.earth.li/~noodles/blog/2017/03/github-tos-change.html
If your're german-speaking you may also want to read the two Heise
articles:
https://www.heise.de/developer/meldung/GitHub-eckt-mit-neuen-Nutzungsbedingungen-an-3647980.html
https://www.heise.de/developer/meldung/FSF-aeussert-sich-zu-den-GitHub-Nutzungsbedingungen-3657040.html
We trust that the problematic part in section D.5:
"If you set your pages and repositories to be viewed publicly, you grant
each User of GitHub a nonexclusive, worldwide license to access your
Content through the GitHub Service, and to use, display and perform your
Content, and to reproduce your Content solely on GitHub as permitted
through GitHub's functionality." that the part "solely on GitHub as
permitted through GitHub's functionality" also applies to "display and
perform your Content". If the latter part of the sentence would stand
alone it could be interpreted that we would grant *everybody*
essentially an unlimited license (which we cannot because the authors
from whom we forked applied other licenses). This interpretation is
further supported by the fact that Github writes "You may grant further
rights if you adopt a license." that in fact the statements above only
apply to the rendering on Github.
Note that in the following we have two licenses, the 3-clause BSD and
the LGPL license in short:
- Contiki OS (and our modification to it) are 3-clause BSD
- Our Arduino compatibility Layer on top of Contiki OS is LGPL
Contiki is licensed under the 3-clause BSD license. This license gives Contiki is licensed under the 3-clause BSD license. This license gives
everyone the right to use and distribute the code, either in binary or everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in source code format, as long as the copyright license is retained in
@ -36,3 +70,463 @@ of license. The license text is:
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
Arduino-compatibility layer if not otherwise noted is under the
following license:
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

View file

@ -105,7 +105,7 @@ CONTIKI_SOURCEFILES += $(CONTIKIFILES)
CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/llsec net/mac net/rime \ CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/llsec net/mac net/rime \
net/rpl sys cfs ctk lib/ctk loader . } net/rpl sys cfs ctk lib/ctk loader . }
oname = ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}} oname = ${patsubst %.cpp,%.o,${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}}
CONTIKI_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CONTIKI_SOURCEFILES)}} CONTIKI_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CONTIKI_SOURCEFILES)}}
@ -156,16 +156,18 @@ endif
### Verbosity control. Use make V=1 to get verbose builds. ### Verbosity control. Use make V=1 to get verbose builds.
ifeq ($(V),1) ifeq ($(V),1)
TRACE_CC = TRACE_CC =
TRACE_LD = TRACE_CXX =
TRACE_AR = TRACE_LD =
TRACE_AS = TRACE_AR =
TRACE_AS =
Q= Q=
else else
TRACE_CC = @echo " CC " $< TRACE_CC = @echo " CC " $<
TRACE_LD = @echo " LD " $@ TRACE_CXX = @echo " CXX " $<
TRACE_AR = @echo " AR " $@ TRACE_LD = @echo " LD " $@
TRACE_AS = @echo " AS " $< TRACE_AR = @echo " AR " $@
TRACE_AS = @echo " AS " $<
Q=@ Q=@
endif endif
@ -184,8 +186,9 @@ CONTIKI_CPU_DIRS_CONCAT = ${addprefix $(CONTIKI_CPU)/, \
SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \
$(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) $(EXTERNALDIRS) ${dir $(target_makefile)} $(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) $(EXTERNALDIRS) ${dir $(target_makefile)}
vpath %.c $(SOURCEDIRS) vpath %.c $(SOURCEDIRS)
vpath %.S $(SOURCEDIRS) vpath %.cpp $(SOURCEDIRS)
vpath %.S $(SOURCEDIRS)
CFLAGS += ${addprefix -I,$(SOURCEDIRS) $(CONTIKI)} CFLAGS += ${addprefix -I,$(SOURCEDIRS) $(CONTIKI)}
@ -203,7 +206,7 @@ endif
ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),clean)
-include ${addprefix $(OBJECTDIR)/,$(CONTIKI_SOURCEFILES:.c=.d) \ -include ${addprefix $(OBJECTDIR)/,$(CONTIKI_SOURCEFILES:.c=.d) \
$(PROJECT_SOURCEFILES:.c=.d)} $(PROJECT_OBJECTFILES:.o=.d)}
endif endif
### See http://make.paulandlesley.org/autodep.html#advanced ### See http://make.paulandlesley.org/autodep.html#advanced
@ -242,6 +245,13 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
@$(FINALIZE_DEPENDENCY) @$(FINALIZE_DEPENDENCY)
endif endif
ifndef CUSTOM_RULE_CPP_TO_OBJECTDIR_O
$(OBJECTDIR)/%.o: %.cpp | $(OBJECTDIR)
$(TRACE_CXX)
$(Q)$(CXX) $(CFLAGS) -MMD -c $< -o $@
@$(FINALIZE_DEPENDENCY)
endif
ifndef CUSTOM_RULE_S_TO_OBJECTDIR_O ifndef CUSTOM_RULE_S_TO_OBJECTDIR_O
$(OBJECTDIR)/%.o: %.S | $(OBJECTDIR) $(OBJECTDIR)/%.o: %.S | $(OBJECTDIR)
$(TRACE_AS) $(TRACE_AS)
@ -254,6 +264,12 @@ ifndef CUSTOM_RULE_C_TO_O
$(Q)$(CC) $(CFLAGS) -c $< -o $@ $(Q)$(CC) $(CFLAGS) -c $< -o $@
endif endif
ifndef CUSTOM_RULE_CPP_TO_O
%.o: %.cpp
$(TRACE_CXX)
$(Q)$(CXX) $(CFLAGS) -c $< -o $@
endif
ifndef CUSTOM_RULE_C_TO_CO ifndef CUSTOM_RULE_C_TO_CO
%.co: %.c %.co: %.c
@ -288,6 +304,25 @@ endif
%.flashprof: %.$(TARGET) %.flashprof: %.$(TARGET)
$(NM) -S -td --size-sort $< | grep -i " [t] " | cut -d' ' -f2,4 $(NM) -S -td --size-sort $< | grep -i " [t] " | cut -d' ' -f2,4
viewconf:
@echo "----------------- Make variables: --------------"
@echo "##### \"TARGET\": ________________________________ $(TARGET)"
@echo "##### \"BOARD\": _________________________________ $(BOARD)"
@echo "##### \"MAKE_MAC\": ______________________________ $(MAKE_MAC)"
@echo "##### \"MAKE_NET\": ______________________________ $(MAKE_NET)"
@echo "##### \"MAKE_ROUTING\": __________________________ $(MAKE_ROUTING)"
ifdef MAKE_COAP_DTLS_KEYSTORE
@echo "##### \"MAKE_COAP_DTLS_KEYSTORE\": _______________ $(MAKE_COAP_DTLS_KEYSTORE)"
endif
@echo "----------------- C variables: -----------------"
$(Q)$(CC) $(CFLAGS) -E $(CONTIKI)/tools/viewconf.c | grep \#\#\#\#\#
@echo "------------------------------------------------"
@echo "'==' Means the flag is set to a given a value"
@echo "'->' Means the flag is unset, but will default to a given value"
@echo "'><' Means the flag is unset and has no default value"
@echo "To view more Make variables, edit $(CONTIKI)/Makefile.include, rule 'viewconf'"
@echo "To view more C variables, edit $(CONTIKI)/tools/viewconf.c"
# Don't treat %.$(TARGET) as an intermediate file because it is # Don't treat %.$(TARGET) as an intermediate file because it is
# in fact the primary target. # in fact the primary target.
.PRECIOUS: %.$(TARGET) .PRECIOUS: %.$(TARGET)
@ -297,6 +332,8 @@ endif
# the match-anything rule below instead. # the match-anything rule below instead.
%: %.c %: %.c
%: %.cpp
# Match-anything pattern rule to allow the project makefiles to # Match-anything pattern rule to allow the project makefiles to
# abstract from the actual binary name. It needs to contain some # abstract from the actual binary name. It needs to contain some
# command in order to be a rule, not just a prerequisite. # command in order to be a rule, not just a prerequisite.

View file

@ -1,8 +1,6 @@
The Contiki Operating System The Contiki Operating System
============================ ============================
[![Build Status](https://travis-ci.org/contiki-os/contiki.svg?branch=master)](https://travis-ci.org/contiki-os/contiki/branches)
Contiki is an open source operating system that runs on tiny low-power Contiki is an open source operating system that runs on tiny low-power
microcontrollers and makes it possible to develop applications that microcontrollers and makes it possible to develop applications that
make efficient use of the hardware while providing standardized make efficient use of the hardware while providing standardized
@ -17,3 +15,12 @@ and so on.
For more information, see the Contiki website: For more information, see the Contiki website:
[http://contiki-os.org](http://contiki-os.org) [http://contiki-os.org](http://contiki-os.org)
This fork of the Contiki Operating System adds support for our Merkur
Board, adds a lot of examples (with different hardware) and puts an
Arduino compatibility layer on top of Contiki-OS that allows Arduino
Sketches -- and a lot of drivers for Arduino compatible hardware -- to
run under Contiki-OS.
For the licensing terms (also in the light of recent debates of Github
changed Terms of Service on 2017-03-01) see the file LICENSE.

View file

@ -0,0 +1,2 @@
arduino_src = arduino-process.c

View file

@ -0,0 +1,4 @@
%.cpp: %.pde
echo '#include "Arduino.h"' > $@
echo '#include "$<"' >> $@

13
apps/arduino/README.md Normal file
View file

@ -0,0 +1,13 @@
Arduino Compatibility
=====================
This application contains hardware-independent implementations of
arduino compatibilty libraries and include files to be used with
contiki.
The whole arduino compatibility library is work in progress. Note that
features having to do with timers like `millis` and `delay` are
currently untested. In Arduino they use timer 0 of the AVR
microcontroller. It should be investigated to use the hardware timer
already in use by contiki (on the OSD-merkur platform this is currently
timer 5).

View file

@ -0,0 +1,183 @@
/*
* Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \addgroup Arduino Process
*
* This wraps the Arduino-API entry points `loop` and `setup` in a
* contiki process.
*
* If the normal contiki includes are used and resources initialized in
* `setup`, Contiki resources can be used in an arduino sketch.
*
* @{
*/
/**
* \file
* Wrapper for Arduino sketches
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
*/
#include <stdlib.h>
#include <string.h>
#include "arduino-process.h"
#include "hw_timer.h"
#include "adc.h"
#include "hw-arduino.h"
#include "contiki.h"
#include "project-conf.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(addr)
#endif
extern volatile uint8_t mcusleepcycle;
#if PLATFORM_HAS_BUTTON
#include "rest-engine.h"
#include "dev/button-sensor.h"
extern resource_t res_event, res_separate;
#endif /* PLATFORM_HAS_BUTTON */
volatile uint8_t mcusleepcycleval;
/* 0 dont sleep; 1 sleep */
uint8_t mcusleep;
/*-------------- enabled sleep mode ----------------------------------------*/
void
mcu_sleep_init(void)
{
mcusleepcycleval=mcusleepcycle;
mcu_sleep_disable(); // if a shell is active we can type
}
void
mcu_sleep_disable(void)
{
mcusleep=2;
mcu_sleep_off();
}
void
mcu_sleep_enable(void)
{
mcusleep=0;
}
void
mcu_sleep_on(void)
{
if(mcusleep == 0){
mcusleepcycle= mcusleepcycleval;
}
}
/*--------------- disable sleep mode ---------------------------------------*/
void
mcu_sleep_off(void)
{
mcusleepcycle=0;
}
/*---------------- set duty cycle value ------------------------------------*/
void
mcu_sleep_set(uint8_t value)
{
mcusleepcycleval= value;
// mcusleepcycle = mcusleepcycleval;
}
PROCESS(arduino_sketch, "Arduino Sketch Wrapper");
#ifndef LOOP_INTERVAL
#define LOOP_INTERVAL (1 * CLOCK_SECOND)
#endif
#define START_MCUSLEEP (10 * CLOCK_SECOND)
PROCESS_THREAD(arduino_sketch, ev, data)
{
static struct etimer loop_periodic_timer;
static struct etimer start_mcusleep_timer;
PROCESS_BEGIN();
adc_init ();
mcu_sleep_init ();
setup ();
/* Define application-specific events here. */
etimer_set(&loop_periodic_timer, LOOP_INTERVAL);
etimer_set(&start_mcusleep_timer, START_MCUSLEEP);
while (1) {
PROCESS_WAIT_EVENT();
#if PLATFORM_HAS_BUTTON
if(ev == sensors_event && data == &button_sensor) {
mcu_sleep_off();
PRINTF("*******BUTTON*******\n");
button ();
mcu_sleep_on();
}
#endif /* PLATFORM_HAS_BUTTON */
if(etimer_expired(&start_mcusleep_timer)) {
PRINTF("mcusleep_timer %d\n",mcusleep);
if(mcusleep == 1){
PRINTF("mcu sleep on\n");
mcu_sleep_enable();
mcu_sleep_on();
}
if (mcusleep > 0) {
mcusleep--;
}
etimer_reset(&start_mcusleep_timer);
}
if(etimer_expired(&loop_periodic_timer)) {
mcu_sleep_off();
loop ();
mcu_sleep_on();
etimer_reset(&loop_periodic_timer);
}
}
PROCESS_END();
}
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/
/** @} */

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \devgroup Arduino Process
*
* This wraps the Arduino-API entry points `loop` and `setup` in a
* contiki process.
*
* If the normal contiki includes are used and resources initialized in
* `setup`, Contiki resources can be used in an arduino sketch.
*
* @{
*/
/**
* \file
* Wrapper for Arduino sketches
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
*/
#include "contiki.h"
/*--------------- enable sleep mode ---------------------------------------*/
void mcu_sleep_enable(void);
/*--------------- disable sleep mode ---------------------------------------*/
void mcu_sleep_disable(void);
/*--------------- sleep mode on---------------------------------------*/
void mcu_sleep_on(void);
/*--------------- sleep mode off---------------------------------------*/
void mcu_sleep_off(void);
/*---------------- set sleep value ------------------------------------*/
void mcu_sleep_set(uint8_t value);
extern void loop (void);
extern void setup (void);
extern void arduino_init (void);
extern void button (void);
extern struct process arduino_sketch;
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/
/** @} */

View file

@ -4,3 +4,18 @@ er-coap_src = er-coap.c er-coap-engine.c er-coap-transactions.c \
# Erbium will implement the REST Engine # Erbium will implement the REST Engine
CFLAGS += -DREST=coap_rest_implementation CFLAGS += -DREST=coap_rest_implementation
ifeq ($(WITH_DTLS_COAP),1)
er-coap_src += er-coap-dtls.c
# Load tinydtls
APPS += tinydtls
$(CONTIKI)/apps/tinydtls/Makefile.tinydtls:
@echo " You should run 'git submodule update --init' to clone 'app/tinydtls'"
@exit 1
include $(CONTIKI)/apps/tinydtls/Makefile.tinydtls
PROJECTDIRS+=$(CONTIKI)/apps/tinydtls/aes $(CONTIKI)/apps/tinydtls/sha2 $(CONTIKI)/apps/tinydtls/ecc
else
er-coap_src += er-coap-udp.c
endif

View file

@ -0,0 +1,15 @@
#ifndef _ER_COAP_COMMUNICATION_H_
#define _ER_COAP_COMMUNICATION_H_
#include "contiki.h"
void
coap_init_communication_layer(uint16_t port);
void
coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length);
void
coap_handle_receive(void);
#endif

View file

@ -94,6 +94,7 @@ typedef enum {
NOT_FOUND_4_04 = 132, /* NOT_FOUND */ NOT_FOUND_4_04 = 132, /* NOT_FOUND */
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
REQUEST_ENTITY_INCOMPLETE_4_08 = 136, /* REQUEST_ENTITY_INCOMPLETE */
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */

161
apps/er-coap/er-coap-dtls.c Normal file
View file

@ -0,0 +1,161 @@
#include "contiki.h"
#include "contiki-net.h"
#include "er-coap.h"
#include "er-coap-engine.h"
#include "dtls.h"
#include <string.h>
#define DEBUG DEBUG_NONE
#include "dtls_debug.h"
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static struct dtls_context_t *dtls_ctx = NULL;
static dtls_handler_t coap_dtls_callback = {
.write = coap_dtls_send_to_peer,
.read = coap_dtls_read_from_peer,
.event = NULL,
#ifdef DTLS_PSK
.get_psk_info = coap_dtls_get_psk_info,
#endif
#ifdef DTLS_ECC
.get_ecdsa_key = NULL,
.verify_ecdsa_key = NULL,
#endif
};
/*-----------------------------------------------------------------------------------*/
void
coap_init_communication_layer(uint16_t port)
{
struct uip_udp_conn *udp_conn = NULL;
dtls_init();
dtls_set_log_level(DTLS_LOG_DEBUG);
udp_conn = udp_new(NULL, 0, NULL);
udp_bind(udp_conn, port);
dtls_ctx = dtls_new_context(udp_conn);
if(dtls_ctx) {
dtls_set_handler(dtls_ctx, &COAP_DTLS_CALLBACK);
}
/* new connection with remote host */
printf("COAP-DTLS listening on port %u\n", uip_ntohs(udp_conn->lport));
}
/*-----------------------------------------------------------------------------------*/
void
coap_send_message(uip_ipaddr_t *addr, uint16_t port,
uint8_t *data, uint16_t length)
{
session_t session;
dtls_session_init(&session);
uip_ipaddr_copy(&session.addr, addr);
session.port = port;
dtls_write(dtls_ctx, &session, data, length);
}
/*-----------------------------------------------------------------------------------*/
void
coap_handle_receive()
{
session_t session;
if(uip_newdata()) {
dtls_session_init(&session);
uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
session.port = UIP_UDP_BUF->srcport;
dtls_handle_message(dtls_ctx, &session, uip_appdata, uip_datalen());
}
}
/* DTLS Specific functions */
/*-----------------------------------------------------------------------------------*/
#ifdef DTLS_PSK
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identiy within this particular
* session. */
int
coap_dtls_get_psk_info(struct dtls_context_t *ctx, const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length)
{
struct keymap_t {
unsigned char *id;
size_t id_length;
unsigned char *key;
size_t key_length;
} psk[1] = {
{ (unsigned char *)DTLS_IDENTITY, DTLS_IDENTITY_LENGTH, (unsigned char *)DTLS_PSK_KEY_VALUE, DTLS_PSK_KEY_VALUE_LENGTH },
};
if(type == DTLS_PSK_IDENTITY) {
if(id_len) {
dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id);
}
if(result_length < psk[0].id_length) {
dtls_warn("cannot set psk_identity -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, psk[0].id, psk[0].id_length);
return psk[0].id_length;
} else if(type == DTLS_PSK_KEY) {
if(id) {
int i;
for(i = 0; i < sizeof(psk) / sizeof(struct keymap_t); i++) {
if(id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) {
if(result_length < psk[i].key_length) {
dtls_warn("buffer too small for PSK");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, psk[i].key, psk[i].key_length);
return psk[i].key_length;
}
}
}
} else {
return 0;
}
return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
}
#endif
/*-----------------------------------------------------------------------------------*/
int
coap_dtls_send_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len)
{
struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx);
uip_ipaddr_copy(&conn->ripaddr, &session->addr);
conn->rport = session->port;
uip_udp_packet_send(conn, data, len);
/* Restore server connection to allow data from any node */
memset(&conn->ripaddr, 0, sizeof(conn->ripaddr));
memset(&conn->rport, 0, sizeof(conn->rport));
return len;
}
/*-----------------------------------------------------------------------------------*/
int
coap_dtls_read_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len)
{
uip_len = len;
memmove(uip_appdata, data, len);
coap_receive(ctx);
return 0;
}

View file

@ -0,0 +1,47 @@
#ifndef COAP_DTLS_H_
#define COAP_DTLS_H_
/* Internal configuration of tinydtls for er-coap-dtls */
#if defined DTLS_CONF_IDENTITY && defined DTLS_CONF_IDENTITY_LENGTH
#define DTLS_IDENTITY DTLS_CONF_IDENTITY
#define DTLS_IDENTITY_LENGTH DTLS_CONF_IDENTITY_LENGTH
#else
#define DTLS_IDENTITY "Client_identity"
#define DTLS_IDENTITY_LENGTH 15
#endif
#if defined DTLS_CONF_PSK_KEY && defined DTLS_CONF_PSK_KEY_LENGTH
#define DTLS_PSK_KEY_VALUE DTLS_CONF_PSK_KEY
#define DTLS_PSK_KEY_VALUE_LENGTH DTLS_CONF_PSK_KEY_LENGTH
#else
#warning "DTLS: Using default secret key !"
#define DTLS_PSK_KEY_VALUE "secretPSK"
#define DTLS_PSK_KEY_VALUE_LENGTH 9
#endif
/* Structure that hold tinydtls callbacks, has type 'dtls_handler_t'. */
#ifndef COAP_DTLS_CALLBACK
#ifdef COAP_DTLS_CONF_CALLBACK
#define COAP_DTLS_CALLBACK COAP_DTLS_CONF_CALLBACK
#else /* COAP_DTLS_CONF_CALLBACK */
#define COAP_DTLS_CALLBACK coap_dtls_callback
#endif /* COAP_DTLS_CALLBACK */
/* Send 'data' to peer defined by session */
int coap_dtls_send_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len);
/* Read 'data' from peer */
int coap_dtls_read_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len);
#ifdef DTLS_PSK
/* Retrieve the key for given identity withing this session */
int coap_dtls_get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length);
#endif
#endif /* COAP_DTLS_H_ */

View file

@ -41,6 +41,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "er-coap-engine.h" #include "er-coap-engine.h"
#include "er-coap-communication.h"
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
@ -64,8 +65,8 @@ static service_callback_t service_cbk = NULL;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*- Internal API ------------------------------------------------------------*/ /*- Internal API ------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int int
coap_receive(void) coap_receive()
{ {
erbium_status_code = NO_ERROR; erbium_status_code = NO_ERROR;
@ -346,7 +347,7 @@ PROCESS_THREAD(coap_engine, ev, data)
PROCESS_YIELD(); PROCESS_YIELD();
if(ev == tcpip_event) { if(ev == tcpip_event) {
coap_receive(); coap_handle_receive();
} else if(ev == PROCESS_EVENT_TIMER) { } else if(ev == PROCESS_EVENT_TIMER) {
/* retransmissions are handled here */ /* retransmissions are handled here */
coap_check_transactions(); coap_check_transactions();
@ -482,6 +483,7 @@ const struct rest_implementation coap_rest_implementation = {
NOT_FOUND_4_04, NOT_FOUND_4_04,
METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_4_05,
NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_4_06,
REQUEST_ENTITY_INCOMPLETE_4_08,
REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_4_13,
UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_4_15,
INTERNAL_SERVER_ERROR_5_00, INTERNAL_SERVER_ERROR_5_00,

View file

@ -52,6 +52,7 @@ typedef coap_packet_t rest_request_t;
typedef coap_packet_t rest_response_t; typedef coap_packet_t rest_response_t;
void coap_init_engine(void); void coap_init_engine(void);
int coap_receive();
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*- Client Part -------------------------------------------------------------*/ /*- Client Part -------------------------------------------------------------*/

View file

@ -0,0 +1,42 @@
#include "contiki.h"
#include "contiki-net.h"
#include "er-coap-engine.h"
#include "er-coap-communication.h"
#include <string.h>
#define DEBUG DEBUG_NONE
#include "uip-debug.h"
static struct uip_udp_conn *udp_conn = NULL;
/*-----------------------------------------------------------------------------------*/
void
coap_init_communication_layer(uint16_t port)
{
/* new connection with remote host */
udp_conn = udp_new(NULL, 0, NULL);
udp_bind(udp_conn, port);
PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport));
}
/*-----------------------------------------------------------------------------------*/
void
coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length)
{
/* Configure connection to reply to client */
uip_ipaddr_copy(&udp_conn->ripaddr, addr);
udp_conn->rport = port;
uip_udp_packet_send(udp_conn, data, length);
PRINTF("-sent UDP datagram (%u)-\n", length);
/* Restore server connection to allow data from any node */
memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr));
udp_conn->rport = 0;
}
/*-----------------------------------------------------------------------------------*/
void
coap_handle_receive()
{
coap_receive();
}

View file

@ -44,6 +44,7 @@
#include "er-coap.h" #include "er-coap.h"
#include "er-coap-transactions.h" #include "er-coap-transactions.h"
#include "er-coap-communication.h"
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
@ -60,7 +61,6 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*- Variables ---------------------------------------------------------------*/ /*- Variables ---------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static struct uip_udp_conn *udp_conn = NULL;
static uint16_t current_mid = 0; static uint16_t current_mid = 0;
coap_status_t erbium_status_code = NO_ERROR; coap_status_t erbium_status_code = NO_ERROR;
@ -279,9 +279,7 @@ void
coap_init_connection(uint16_t port) coap_init_connection(uint16_t port)
{ {
/* new connection with remote host */ /* new connection with remote host */
udp_conn = udp_new(NULL, 0, NULL); coap_init_communication_layer(port);
udp_bind(udp_conn, port);
PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport));
/* initialize transaction ID */ /* initialize transaction ID */
current_mid = random_rand(); current_mid = random_rand();
@ -422,23 +420,6 @@ coap_serialize_message(void *packet, uint8_t *buffer)
return (option - buffer) + coap_pkt->payload_len; /* packet length */ return (option - buffer) + coap_pkt->payload_len; /* packet length */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void
coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
uint16_t length)
{
/* configure connection to reply to client */
uip_ipaddr_copy(&udp_conn->ripaddr, addr);
udp_conn->rport = port;
uip_udp_packet_send(udp_conn, data, length);
PRINTF("-sent UDP datagram (%u)-\n", length);
/* restore server socket to allow data from any node */
memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr));
udp_conn->rport = 0;
}
/*---------------------------------------------------------------------------*/
coap_status_t coap_status_t
coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
{ {

View file

@ -0,0 +1 @@
json-resource_src = generic_resource.c

View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/**
* \addtogroup Generic CoAP Resource Handler
*
* @{
*/
/**
* \file
* Generic CoAP Resource Handler
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "jsonparse.h"
#include "er-coap.h"
#include "generic_resource.h"
/* Error-handling macro */
# define BYE(_exp, _tag) \
do { \
PRINTF("Expect "_exp": %d\n",_tag); \
return -1; \
} while(0)
#define DEBUG 1
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
int8_t
json_parse_variable
(const uint8_t *bytes, size_t len, char *name, char *buf, size_t buflen)
{
int tag = 0;
struct jsonparse_state state;
struct jsonparse_state *parser = &state;
PRINTF ("PUT: len: %d, %s\n", len, (const char *)bytes);
jsonparse_setup (parser, (const char *)bytes, len);
if ((tag = jsonparse_next (parser)) != JSON_TYPE_OBJECT) {
BYE ("OBJECT", tag);
}
if ((tag = jsonparse_next (parser)) != JSON_TYPE_PAIR_NAME) {
BYE ("PAIR_NAME", tag);
}
while (jsonparse_strcmp_value (parser, name) != 0) {
tag = jsonparse_next (parser);
if (tag != JSON_TYPE_PAIR) {
BYE ("PAIR", tag);
}
tag = jsonparse_next (parser);
tag = jsonparse_next (parser);
if (tag != ',') {
BYE (",", tag);
}
tag = jsonparse_next (parser);
if (tag != JSON_TYPE_PAIR_NAME) {
BYE ("PAIR_NAME", tag);
}
}
tag = jsonparse_next (parser);
if (tag != JSON_TYPE_PAIR) {
BYE ("PAIR", tag);
}
tag = jsonparse_next (parser);
if (tag != JSON_TYPE_STRING) {
BYE ("STRING", tag);
}
jsonparse_copy_value (parser, buf, buflen);
return 0;
}
static const char *get_uri (void *request)
{
static char buf [MAX_URI_STRING_LENGTH];
const char *uri;
size_t len = coap_get_header_uri_path (request, &uri);
if (len > sizeof (buf) - 1) {
*buf = '\0';
} else {
strncpy (buf, uri, len);
buf [len] = '\0';
}
return buf;
}
static const char *get_query (void *request)
{
static char buf [MAX_QUERY_STRING_LENGTH];
const char *query;
size_t len = coap_get_header_uri_query (request, &query);
if (len > sizeof (buf) - 1) {
*buf = '\0';
} else {
strncpy (buf, query, len);
buf [len] = '\0';
}
return buf;
}
void generic_get_handler
( void *request
, void *response
, uint8_t *buffer
, uint16_t preferred_size
, int32_t *offset
, char *name
, int is_str
, size_t (*to_str)
( const char *name
, const char *uri
, const char *query
, char *buf, size_t bsize
)
)
{
int success = 1;
char temp [MAX_GET_STRING_LENGTH];
size_t len = 0;
unsigned int accept = -1;
const char *uri = get_uri (request);
const char *query = get_query (request);
REST.get_header_accept (request, &accept);
if ( accept != -1
&& accept != REST.type.TEXT_PLAIN
&& accept != REST.type.APPLICATION_JSON
)
{
success = 0;
REST.set_response_status (response, REST.status.NOT_ACCEPTABLE);
return;
}
// TEXT format
if (accept == REST.type.APPLICATION_JSON) {
len += snprintf
( temp + len
, sizeof (temp) - len
, "{\n \"%s\" : %s"
, name
, is_str ? "\"" : ""
);
if (len > sizeof (temp)) {
success = 0;
goto out;
}
len += to_str (name, uri, query, temp + len, sizeof (temp) - len);
if (len > sizeof (temp)) {
success = 0;
goto out;
}
len += snprintf
( temp + len
, sizeof (temp) - len
, "%s\n}\n"
, is_str ? "\"" : ""
);
if (len > sizeof (temp)) {
success = 0;
goto out;
}
} else { // TEXT Format
len += to_str (name, uri, query, temp + len, sizeof (temp) - len);
if (len > sizeof (temp)) {
success = 0;
goto out;
}
len += snprintf (temp + len, sizeof (temp) - len, "\n");
if (len > sizeof (temp)) {
success = 0;
goto out;
}
}
memcpy (buffer, temp, len);
REST.set_header_content_type (response, accept);
REST.set_response_payload (response, buffer, len);
out :
if (!success) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
}
}
void generic_put_handler
( void *request
, void *response
, uint8_t *buffer
, uint16_t preferred_size
, int32_t *offset
, char *name
, int (*from_str)
(const char *name, const char *uri, const char *query, const char *s)
)
{
int success = 1;
char temp [100];
size_t len = 0;
const uint8_t *bytes = NULL;
unsigned int c_ctype;
const char *uri = get_uri (request);
const char *query = get_query (request);
REST.get_header_content_type (request, &c_ctype);
if (from_str && (len = coap_get_payload (request, &bytes))) {
if (c_ctype == REST.type.TEXT_PLAIN) {
int l = MIN (len, sizeof (temp) - 1);
temp [sizeof (temp) - 1] = 0;
strncpy (temp, (const char *)bytes, l);
temp [l] = 0;
} else { // jSON Format
if (json_parse_variable (bytes, len, name, temp, sizeof (temp)) < 0) {
success = 0;
goto out;
}
}
if (from_str (name, uri, query, temp) < 0) {
success = 0;
} else {
REST.set_response_status (response, REST.status.CHANGED);
}
} else {
success = 0;
}
out:
if (!success) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
}
}
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/
/** @} */

View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/**
* \defgroup Generic CoAP Resource Handler
*
* This factors the boilerplate code necessary for defining a resource
* together with the necessary handler. Currently this supports
* text/plain and application/json and outputs the resource with its
* name in json format. This may change in the future as more CoRE
* standards (e.g. see RFC 6690) get defined.
*
* @{
*/
/**
* \file
* Generic CoAP Resource Handler
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*/
#define STR__(s) #s
#define STR_(s) STR__(s)
#define MAX_GET_STRING_LENGTH 100
#define MAX_URI_STRING_LENGTH 30
#define MAX_QUERY_STRING_LENGTH 30
/*
* A macro that extends the resource definition and also sets up the
* necessary handler function that calls format/parse routines that
* convert from/to string (fs and ts). The ts function needs to return
* the length written, similar to sprintf.
* The content type definitions ct="0 5" are text/plain and
* application/json, respectively, see rfc7252 Table 9 p. 91.
* Yes, this *is* a hack. But I hate boilerplate code.
*/
#define GENERIC_RESOURCE(name, title, unit, is_str, fs, ts) \
static void name##_get_handler \
( void *request \
, void *response \
, uint8_t *buffer \
, uint16_t ps \
, int32_t *offset \
) \
{ \
generic_get_handler \
(request, response, buffer, ps, offset, STR_(name), is_str, ts); \
} \
static void name##_put_handler \
( void *request \
, void *response \
, uint8_t *buffer \
, uint16_t ps \
, int32_t *offset \
) \
{ \
generic_put_handler \
(request, response, buffer, ps, offset, STR_(name), fs); \
} \
\
RESOURCE ( res_##name \
, "title=\"" STR_(title) "\"" \
";rt=UCUM:\"" STR_(unit) "\"" \
";ct=\"0 5\"" \
, (ts) ? name##_get_handler : NULL \
, NULL /* POST */ \
, (fs) ? name##_put_handler : NULL \
, NULL /* DELETE */ \
)
/* Ignore constant pointer tests above */
#pragma GCC diagnostic ignored "-Waddress"
/**
* \brief Parse a resource in json format
* \param bytes: Input string received via coap
* \param len: Length of input string
* \param name: Name to search in json input
* \param buf: Output buffer
* \param buflen: Output buffer length
* \return 0 for success, -1 for error
*
* If compiled with DEBUG also prints the error encountered
*/
extern int8_t json_parse_variable
(const uint8_t *bytes, size_t len, char *name, char *buf, size_t buflen);
/**
* \brief Generic coap GET resource handler
* \param name: The name of the variable in json
* \param to_str: Application method to format value for output;
* the function may chose to format differently for coap or text
* The other parameters are the same as a normal resource handler
* This helps avoid boilerplate code for request handlers
*
* The callback functions get the name of the parameter as a first
* argument, this allows to re-use the same function for different
* parameters. In addition it gets a buffer and the size of the buffer.
* It needs to return the number of bytes output, similar to sprintf.
*/
extern void generic_get_handler
( void *request
, void *response
, uint8_t *buffer
, uint16_t preferred_size
, int32_t *offset
, char *name
, int is_str
, size_t (*to_str)
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
);
/**
* \brief Generic coap PUT resource handler
* \param name: The name of the variable in json
* \param from_str: Application method to parse value from string
* and act on it, may be NULL in which case the resource only
* supports GET not PUT
* The other parameters are the same as a normal resource handler
* This helps avoid boilerplate code for request handlers
*
* The callback functions get the name of the parameter as a first
* argument, this allows to re-use the same function for different
* parameters. The from_str in addition gets the string to parse.
*/
extern void generic_put_handler
( void *request
, void *response
, uint8_t *buffer
, uint16_t preferred_size
, int32_t *offset
, char *name
, int (*from_str)
(const char *name, const char *uri, const char *query, const char *s)
);
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/
/** @} */

View file

@ -0,0 +1 @@
ota-update_src = res_bootloader.c res_reboot.c res_upload_image.c

View file

@ -0,0 +1,22 @@
extern resource_t res_upload_image;
extern resource_t res_part_count;
extern resource_t res_part_size;
extern resource_t res_boot_default;
extern resource_t res_boot_next;
extern resource_t res_active_part;
extern resource_t res_part_start;
extern resource_t res_part_ok;
extern resource_t res_reboot;
#define OTA_ACTIVATE_RESOURCES() \
static char resname[] = "ota/update";\
rest_activate_resource (&res_upload_image, resname);\
rest_activate_resource (&res_part_count, (char *)"ota/part_count");\
rest_activate_resource (&res_part_size, (char *)"ota/part_size");\
rest_activate_resource (&res_boot_default, (char *)"ota/boot_default");\
rest_activate_resource (&res_boot_next, (char *)"ota/boot_next");\
rest_activate_resource (&res_active_part, (char *)"ota/active_part");\
rest_activate_resource (&res_part_start, (char *)"ota/part_start");\
rest_activate_resource (&res_part_ok, (char *)"ota/part_ok");\
rest_activate_resource (&res_reboot, (char *)"ota/reboot");

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 2015, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Bootloader ressources
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "contiki.h"
#include "contiki-net.h"
#include "rest-engine.h"
#include "er-coap-engine.h"
#include "uiplib.h"
#include "generic_resource.h"
#include "bootloader_if.h"
#include "Arduino.h"
/*
* Resources to be activated need to be imported through the extern keyword.
* The build system automatically compiles the resources in the
* corresponding sub-directory.
*/
static size_t
part_count
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_part_count ());
}
GENERIC_RESOURCE
( part_count
, Partition Count
, count
, 0
, NULL
, part_count
);
static size_t
part_size
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_part_size ());
}
GENERIC_RESOURCE
( part_size
, Partition Size
, count
, 0
, NULL
, part_size
);
static size_t
get_boot_default
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_boot_default ());
}
static int
set_boot_default
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
bootloader_set_boot_default (tmp);
return 0;
}
GENERIC_RESOURCE
( boot_default
, Default boot partition
, count
, 0
, set_boot_default
, get_boot_default
);
static size_t
get_boot_next
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_boot_next ());
}
static int
set_boot_next
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
bootloader_set_boot_next (tmp);
return 0;
}
GENERIC_RESOURCE
( boot_next
, Next boot partition
, count
, 0
, set_boot_next
, get_boot_next
);
static size_t
get_active_part
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "%ld", bootloader_get_active_part ());
}
GENERIC_RESOURCE
( active_part
, Currently active partition
, count
, 0
, NULL
, get_active_part
);
/*
* Parse query info. We insist that the query starts with 'part='
* Then we parse the integer following the part= string and return the
* number. The number is always positive, if something goes wrong we
* return a negative number.
*/
static int get_query_partition (const char *query)
{
if (strncmp (query, "part=", 5)) {
return -1;
}
return strtoul (query + 5, NULL, 10);
}
static size_t
get_part_start
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
int idx = get_query_partition (query);
if (idx < 0) {
return snprintf (buf, bsize, "Invalid: \"%s\" use part=N query", query);
}
return snprintf (buf, bsize, "%ld", bootloader_get_part_start (idx));
}
GENERIC_RESOURCE
( part_start
, Start of partition
, count
, 0
, NULL
, get_part_start
);
static int
set_part_ok
(const char *name, const char *uri, const char *query, const char *s)
{
uint32_t tmp = strtoul (s, NULL, 10);
int idx = get_query_partition (query);
if (idx < 0) {
return -1;
}
if (tmp) {
bootloader_set_part_ok (idx);
} else {
bootloader_clr_part_ok (idx);
}
return 0;
}
static size_t
get_part_ok
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
int idx = get_query_partition (query);
if (idx < 0) {
return snprintf (buf, bsize, "Invalid: \"%s\" use part=N query", query);
}
return snprintf (buf, bsize, "%ld", bootloader_get_part_ok (idx));
}
GENERIC_RESOURCE
( part_ok
, Set/Clear Partition OK flag
, count
, 0
, set_part_ok
, get_part_ok
);

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2017, Marcus Priesch Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Reboot ressource
* \author
* Marcus Priesch <marcus@priesch.co.at>
*/
#include <stdio.h>
#include <string.h>
#include "contiki.h"
#include "er-coap-engine.h"
#include "generic_resource.h"
#include "dev/watchdog.h"
PROCESS(reboot_process, "reboot");
PROCESS_THREAD(reboot_process, ev, data)
{
static struct etimer etimer;
//PROCESS_EXITHANDLER(leds_off(LEDS_ALL);)
PROCESS_BEGIN();
//shell_output_str(&reboot_command,
// "Rebooting the node in four seconds...", "");
etimer_set(&etimer, CLOCK_SECOND * 4);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
//leds_on(LEDS_RED);
//etimer_reset(&etimer);
//PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
//leds_on(LEDS_GREEN);
//etimer_reset(&etimer);
//PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
//leds_on(LEDS_BLUE);
//etimer_reset(&etimer);
//PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
watchdog_reboot();
PROCESS_END();
}
static size_t
get_reboot
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
return snprintf (buf, bsize, "put 'OK' to reboot.");
}
static int
do_reboot
(const char *name, const char *uri, const char *query, const char *s)
{
if (strncmp (s, "OK", 2) == 0) {
process_start (&reboot_process, NULL);
return 0;
}
return 0;
}
GENERIC_RESOURCE
( reboot
, Reboot node
, count
, 0
, do_reboot
, get_reboot
);

View file

@ -0,0 +1,243 @@
/*
* Copyright (C) 2017, Marcus Priesch, Ralf Schlatterbeck
* with code from the res-plugtest-large-update.c by
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Over-the-air update using blockwise transfer
* \author
* Marcus Priesch <marcus@priesch.co.at>
* Ralf Schlatterbeck <rsc@runtux.com>
*/
#include <string.h>
#include "sys/cc.h"
#include "rest-engine.h"
#include "er-coap.h"
#include "contiki.h"
#include "contiki-net.h"
#include "er-coap.h"
#include "Arduino.h"
#include <avr/interrupt.h>
#include "bootloader_if.h"
#if 1
#include <stdio.h>
#define PRINTF(x) printf x
#else
#define PRINTF(x)
#endif
// We allocate this statically, otherwise we cannot flash a new image
// when ram is exhausted!
static uint8_t current_page [256];
static uint32_t current_offset = 0;
#define PAGESIZE (sizeof (current_page))
/*
* Note that the current code relies on the fact that the bootloader
* used only supports two images. This may change in the future. We
* mainly need to relax some of the checks and use a different algorithm
* for computing imgidx, the index of the partition to be overwritten.
* If the bootloader supports more than two partitions at some point we
* may want the uploader to explicitly define the partition to be used.
*/
static void
res_put_handler
( void *request
, void *response
, uint8_t *buffer
, uint16_t preferred_size
, int32_t *offset
)
{
coap_packet_t *const packet = (coap_packet_t *)request;
uint8_t *in_data = NULL;
size_t len = 0;
uint32_t partition_start = 0;
const uint32_t partition_size = bootloader_get_part_size ();
uint32_t imgidx = 0;
unsigned int ct = -1;
/* If the currently-booted partition is not the default partition we
* do not allow overwriting a partition: Neither the currently-booted
* one (this would crash) nor the only partition that is marked
* bootable. We also insist that boot_next == boot_default.
*/
if (bootloader_get_boot_default () != bootloader_get_boot_next ()) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
const char *error_msg = "Won't overwrite boot_next";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
if (bootloader_get_boot_default () != bootloader_get_active_part ()) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
const char *error_msg = "Won't overwrite current";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
imgidx = !bootloader_get_active_part ();
partition_start = bootloader_get_part_start (imgidx);
REST.get_header_content_type (request, &ct);
/* Require content_type APPLICATION_OCTET_STREAM */
if (ct != REST.type.APPLICATION_OCTET_STREAM) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
const char *error_msg = "ContentType";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
len = REST.get_request_payload (request, (const uint8_t **)&in_data);
PRINTF (("cur: %lu len: %lu, offset: %lu\n",
(uint32_t)current_offset, (uint32_t)len, (uint32_t)*offset));
PRINTF (("b1-offs: %lu, b1-size: %u, b1-num: %lu b1-more: %d b1-size1: %lu\n",
packet->block1_offset, packet->block1_size, packet->block1_num,
packet->block1_more, packet->size1));
if (len == 0 || NULL == in_data) {
REST.set_response_status (response, REST.status.BAD_REQUEST);
const char *error_msg = "NoPayload";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
/* if the block1_offset is 0 a new transmission has started */
if (!packet->block1_offset) {
current_offset = 0;
}
if (packet->block1_offset > current_offset) {
REST.set_response_status (response, REST.status.REQUEST_ENTITY_INCOMPLETE);
const char *error_msg = "OutOfSequence";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
/* Old packet or retransmission, immediately confirm */
if (packet->block1_offset && packet->block1_offset + len <= current_offset) {
REST.set_response_status (response, REST.status.CHANGED);
coap_set_header_block1
(response, packet->block1_num, 0, packet->block1_size);
return;
}
// FIXME: blocksize may be larger than our flash page size
if (len > PAGESIZE) {
REST.set_response_status (response, REST.status.INTERNAL_SERVER_ERROR);
const char *error_msg = "GRMPF: PageSize";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
// FIXME: blocksize may be larger than our flash page size
// So we should handle this case and repeatedly flash a block until the
// received data is written.
if (current_offset % PAGESIZE + len > PAGESIZE) {
REST.set_response_status (response, REST.status.INTERNAL_SERVER_ERROR);
const char *error_msg = "GRMPF: blocksize";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
// Should never happen, we test for < and > earlier.
if (packet->block1_offset != current_offset) {
REST.set_response_status (response, REST.status.INTERNAL_SERVER_ERROR);
const char *error_msg = "GRMPF: Offset";
REST.set_response_payload (response, error_msg, strlen (error_msg));
return;
}
if (packet->block1_offset + len > partition_size) {
REST.set_response_status
(response, REST.status.REQUEST_ENTITY_TOO_LARGE);
REST.set_response_payload
(response, buffer, sprintf ((char *)buffer, "%luB max.", partition_size));
return;
}
memcpy (current_page + current_offset % PAGESIZE, in_data, len);
/* Whenever an upload is started for a partition mark it as not ok */
if (current_offset == 0) {
PRINTF (("Clear partition_ok: %ld\n", imgidx));
bootloader_clr_part_ok (imgidx);
}
current_offset += len;
if (current_offset % PAGESIZE == 0) {
uint32_t dst_address = partition_start + current_offset - PAGESIZE;
/* Special case: Flash irq vectors to backup position */
if (current_offset - PAGESIZE < PART_IRQVEC_SIZE) {
/* Only for images not at position 0 write first PART_IRQVEC_SIZE
* bytes also to original position. For partition 0 it will be
* copied there anyway *and* we would crash if we wrote to the
* active memory!
*/
if (partition_start != 0) {
PRINTF (("Flashing: %lx to %lx\n", (uint32_t)PAGESIZE, dst_address));
bootloader_write_page_to_flash (dst_address, PAGESIZE, current_page);
}
/* Note: The partition_size returned by the bootloader does *NOT*
* include the PART_IRQVEC_SIZE
*/
dst_address = partition_start + partition_size
+ current_offset - PAGESIZE;
}
PRINTF (("Flashing: %lx to %lx\n", (uint32_t)PAGESIZE, dst_address));
bootloader_write_page_to_flash (dst_address, PAGESIZE, current_page);
} else if (!packet->block1_more) {
uint32_t dst_address =
partition_start + (current_offset / PAGESIZE) * PAGESIZE;
PRINTF (("Flashing: last %lx to %lx\n", (uint32_t)PAGESIZE, dst_address));
bootloader_write_page_to_flash (dst_address, PAGESIZE, current_page);
}
if (!packet->block1_more) {
// we are finished
bootloader_set_boot_next (imgidx);
current_offset = 0;
}
REST.set_response_status (response, REST.status.CHANGED);
coap_set_header_block1 (response, packet->block1_num, 0, packet->block1_size);
}
RESOURCE(
res_upload_image
, "title=\"Flash memory upgrade\";rt=\"block\""
, NULL
, NULL
, res_put_handler
, NULL
);

View file

@ -56,6 +56,7 @@ struct rest_implementation_status {
const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */ const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */
const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */ const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */
const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */ const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */
const unsigned int REQUEST_ENTITY_INCOMPLETE; /* REQUEST_ENTITY_INCOMPLETE_4_08, REQUEST_ENTITY_INCOMPLETE_408 */
const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */ const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */
const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */ const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */

View file

@ -49,7 +49,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "arduino-process.h"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS(serial_shell_process, "Contiki serial shell"); PROCESS(serial_shell_process, "Contiki serial shell");
@ -58,6 +58,8 @@ void
shell_default_output(const char *text1, int len1, const char *text2, int len2) shell_default_output(const char *text1, int len1, const char *text2, int len2)
{ {
int i; int i;
mcu_sleep_disable();
if(text1 == NULL) { if(text1 == NULL) {
text1 = ""; text1 = "";
len1 = 0; len1 = 0;
@ -89,6 +91,7 @@ void
shell_exit(void) shell_exit(void)
{ {
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_shell_process, ev, data) PROCESS_THREAD(serial_shell_process, ev, data)
{ {
@ -98,6 +101,7 @@ PROCESS_THREAD(serial_shell_process, ev, data)
while(1) { while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL); PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL);
mcu_sleep_disable();
shell_input(data, strlen(data)); shell_input(data, strlen(data));
} }

View file

@ -66,3 +66,11 @@ endif
ifeq ($(TARGET),z1) ifeq ($(TARGET),z1)
shell_src += shell-sky.c shell-exec.c shell_src += shell-sky.c shell-exec.c
endif endif
ifeq ($(TARGET),osd-merkur-256)
shell_src += shell-merkur.c
endif
ifeq ($(TARGET),osd-merkur-128)
shell_src += shell-merkur.c
endif

237
apps/shell/shell-merkur.c Normal file
View file

@ -0,0 +1,237 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Merkurboard-specific Contiki shell commands
* \author
* Harald Pichler <harald@the-develop.net>
*/
#include "contiki.h"
#include <stdio.h>
#include <stdlib.h> /* strtol */
#include "sys/cc.h"
#include "dev/radio.h"
#include "shell-merkur.h"
#include "params.h"
#include "arduino-process.h"
/*---------------------------------------------------------------------------*/
PROCESS(shell_txpower_process, "txpower");
SHELL_COMMAND(txpower_command,
"txpower",
"txpower <power>: change transmission power 0 (3dbm, default) to 15 (-17.2dbm)",
&shell_txpower_process);
PROCESS(shell_panid_process, "panid");
SHELL_COMMAND(panid_command,
"panid",
"panid <0xabcd>: change panid (default 0xabcd)",
&shell_panid_process);
PROCESS(shell_rfchannel_process, "rfchannel");
SHELL_COMMAND(rfchannel_command,
"rfchannel",
"rfchannel <channel>: change radio channel (11 - 26)",
&shell_rfchannel_process);
PROCESS(shell_ccathresholds_process, "ccathresholds");
SHELL_COMMAND(ccathresholds_command,
"ccathresholds",
"ccathresholds <threshold: change cca thresholds -91 to -61 dBm (default -77)",
&shell_ccathresholds_process);
PROCESS(shell_macconf_process, "macconf");
SHELL_COMMAND(macconf_command,
"macconf",
"macconf <conf>: change mac layer 0 -> do nothing; 1 -> Radio allways on",
&shell_macconf_process);
PROCESS(shell_saverfparam_process, "saverfparam");
SHELL_COMMAND(saverfparam_command,
"saverfparam",
"saverfparam <> save radio parameters txpower, channel, panid to eeprom settingsmanager",
&shell_saverfparam_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_txpower_process, ev, data)
{
radio_value_t value;
char buf[10];
const char *newptr;
PROCESS_BEGIN();
value = shell_strtolong(data, &newptr);
/* If no transmission power was given on the command line, we print
out the current txpower. */
if(newptr == data) {
if(get_param(RADIO_PARAM_TXPOWER, &value) == RADIO_RESULT_OK) {
}
} else {
set_param(RADIO_PARAM_TXPOWER, value);
}
snprintf(buf, sizeof(buf), "%3d", value);
shell_output_str(&txpower_command, "TX Power: ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_rfchannel_process, ev, data)
{
radio_value_t value;
char buf[10];
const char *newptr;
PROCESS_BEGIN();
value = shell_strtolong(data, &newptr);
/* If no channel was given on the command line, we print out the
current channel. */
if(newptr == data) {
if(get_param(RADIO_PARAM_CHANNEL, &value) == RADIO_RESULT_OK) {
}
} else {
set_param(RADIO_PARAM_CHANNEL, value);
}
snprintf(buf, sizeof(buf), "%d", value);
shell_output_str(&rfchannel_command, "Channel: ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_ccathresholds_process, ev, data)
{
radio_value_t value;
char buf[10];
const char *newptr;
PROCESS_BEGIN();
value = shell_strtolong(data, &newptr);
/* If no channel was given on the command line, we print out the
current channel. */
if(newptr == data) {
if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) {
}
} else {
set_param(RADIO_PARAM_CCA_THRESHOLD, value);
}
snprintf(buf, sizeof(buf), "%d dBm", value);
shell_output_str(&rfchannel_command, "CCA Threshold: ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_macconf_process, ev, data)
{
radio_value_t value;
char buf[10];
const char *newptr;
PROCESS_BEGIN();
value = shell_strtolong(data, &newptr);
/* If no transmission power was given on the command line, we print
out the current macconf. */
if(newptr == data) {
value = params_get_macconf();
} else {
params_set_macconf(value);
}
snprintf(buf, sizeof(buf), "%3d", value);
shell_output_str(&txpower_command, "macconf: ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_panid_process, ev, data)
{
radio_value_t value;
char buf[10];
char *newptr;
PROCESS_BEGIN();
value = strtol(data, &newptr, 0);
/* If no channel was given on the command line, we print out the
current channel. */
if(newptr == data) {
if(get_param(RADIO_PARAM_PAN_ID, &value) != RADIO_RESULT_OK) {
// printf("error: get_param RADIO_PARAM_PAN_ID\n");
}
} else {
set_param(RADIO_PARAM_PAN_ID, value);
}
snprintf(buf, sizeof(buf),"0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF);
shell_output_str(&panid_command, "panid: ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_saverfparam_process, ev, data)
{
PROCESS_BEGIN();
/* Save txpower */
params_save_txpower();
/* Save rfchannel */
params_save_channel();
/* Save ccathresholds */
// todo
/* Save panid */
params_save_panid();
/* Save macconf */
params_save_macconf();
shell_output_str(&rfchannel_command, "saverfparam done ", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_merkur_init(void)
{
// shell_ps_init();
shell_reboot_init();
shell_register_command(&txpower_command);
shell_register_command(&rfchannel_command);
shell_register_command(&ccathresholds_command);
shell_register_command(&panid_command);
shell_register_command(&macconf_command);
shell_register_command(&saverfparam_command);
// shell_register_command(&s_command);
}
/*---------------------------------------------------------------------------*/

47
apps/shell/shell-merkur.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Header file for Tmote Sky-specific Contiki shell commands
* \author
* harald pichler <harald@the-develop.net>
*/
#ifndef SHELL_MERKUR_H_
#define SHELL_MERKUR_H_
#include "shell.h"
void shell_merkur_init(void);
#endif /* SHELL_MERKUR_H_ */

2
apps/time/Makefile.time Normal file
View file

@ -0,0 +1,2 @@
time_src = time.c resource_gmtime.c resource_timestamp.c \
resource_timezone.c resource_crontab.c cron.c

20
apps/time/README Normal file
View file

@ -0,0 +1,20 @@
Timezones
=========
The new version supports time zones and daylight saving time (DST).
Currently we support only a single timezone. We use the UNIX timezone
format which is usually specified in an environment variable TZ.
Note that for timezone information you can have different
representation, either relative to Universal Time Coordinated (UTC) or
to International Atomic Time (TAI), the latter contains leap seconds.
Since most systems today use UTC *and* the clock of a microcontroller
is typically not accurate enough to care about leap seconds, we're using
timezone files relative to UTC.
Wikipedia has a very good treatment of the public timezone database in
https://en.wikipedia.org/wiki/Tz_database
The format of timezone strings is described in the Linux manual page
tzset(3). The timezone specification for Europe/Vienna is
CET-1CEST,M3.5.0,M10.5.0/3

118
apps/time/bitstring.h Normal file
View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Vixie.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)bitstring.h 5.2 (Berkeley) 4/4/90
*/
typedef unsigned char bitstr_t;
/* internal macros */
/* byte of the bitstring bit is in */
#define _bit_byte(bit) \
((bit) >> 3)
/* mask for the bit within its byte */
#define _bit_mask(bit) \
(1 << ((bit)&0x7))
/* external macros */
/* bytes in a bitstring of nbits bits */
#define bitstr_size(nbits) \
((((nbits) - 1) >> 3) + 1)
/* allocate a bitstring on the stack */
#define bit_decl(name, nbits) \
(name)[bitstr_size(nbits)]
/* is bit N of bitstring name set? */
#define bit_test(name, bit) \
((name)[_bit_byte(bit)] & _bit_mask(bit))
/* set bit N of bitstring name */
#define bit_set(name, bit) \
(name)[_bit_byte(bit)] |= _bit_mask(bit)
/* clear bit N of bitstring name */
#define bit_clear(name, bit) \
(name)[_bit_byte(bit)] &= ~_bit_mask(bit)
/* clear bits start ... stop in bitstring */
#define bit_nclear(name, start, stop) { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
register int _startbyte = _bit_byte(_start); \
register int _stopbyte = _bit_byte(_stop); \
if (_startbyte == _stopbyte) { \
_name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
(0xff << ((_stop&0x7) + 1))); \
} else { \
_name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
while (++_startbyte < _stopbyte) \
_name[_startbyte] = 0; \
_name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
} \
}
/* set bits start ... stop in bitstring */
#define bit_nset(name, start, stop) { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
register int _startbyte = _bit_byte(_start); \
register int _stopbyte = _bit_byte(_stop); \
if (_startbyte == _stopbyte) { \
_name[_startbyte] |= ((0xff << (_start&0x7)) & \
(0xff >> (7 - (_stop&0x7)))); \
} else { \
_name[_startbyte] |= 0xff << ((_start)&0x7); \
while (++_startbyte < _stopbyte) \
_name[_startbyte] = 0xff; \
_name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
} \
}
/* find first bit clear in name */
#define bit_ffc(name, nbits, value) { \
register bitstr_t *_name = name; \
register int _byte, _nbits = nbits; \
register int _stopbyte = _bit_byte(_nbits), _value = -1; \
for (_byte = 0; _byte <= _stopbyte; ++_byte) \
if (_name[_byte] != 0xff) { \
_value = _byte << 3; \
for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \
++_value, _stopbyte >>= 1); \
break; \
} \
*(value) = _value; \
}
/* find first bit set in name */
#define bit_ffs(name, nbits, value) { \
register bitstr_t *_name = name; \
register int _byte, _nbits = nbits; \
register int _stopbyte = _bit_byte(_nbits), _value = -1; \
for (_byte = 0; _byte <= _stopbyte; ++_byte) \
if (_name[_byte]) { \
_value = _byte << 3; \
for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \
++_value, _stopbyte >>= 1); \
break; \
} \
*(value) = _value; \
}

488
apps/time/cron.c Normal file
View file

@ -0,0 +1,488 @@
/**
* \file
* cron: Cron-like functionality
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
* \brief cron-like command scheduler
*
* Inspired by vixie's cron by Paul Vixie which is
* Copyright 1988,1990,1993,1994 by Paul Vixie
*
* Distribute freely, except: don't remove my name from the source or
* documentation (don't take credit for my work), mark your changes (don't
* get me blamed for your possible bugs), don't alter or remove this
* notice. May be sold if buildable source is provided to buyer. No
* warrantee of any kind, express or implied, is included with this
* software; use at your own risk, responsibility for damages (if any) to
* anyone resulting from the use of this software rests entirely with the
* user.
*
* Changes to make this work on a microcontroller by Ralf Schlatterbeck
* In fact this is mostly a rewrite but keeps central algorithms and
* some data structures of the original.
* The syntax is simplified, we don't support the @ notation (e.g.
* @hourly) and named entities (e.g. weekday names instead of numbers).
* Furthermore we can't send email and don't support environment
* variables. The called commands are functions registered via a
* registration mechanism before runtime.
* Copyright 2016 Ralf Schlatterbeck, distribute with the conditions
* given above.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include "contiki.h"
#include "cron.h"
#include "xtime.h"
#undef DEBUG
static struct cron_entry cron_entries [MAX_CRON_ENTRIES];
static struct cron_cmd cron_commands [MAX_CRON_COMMANDS];
static size_t cron_registered_entries = 0;
static size_t cron_registered_commands = 0;
static struct cron_entry *entry_freelist = NULL;
static struct cron_entry *entry_list = NULL;
typedef int64_t minute_t;
static xtime_t start_time;
static minute_t cron_clock_time;
/* Register a new cron command
* A command consists of a name (which must be unique, uniqueness is not
* enforced currently as registrations are done once at initialization
* time), a function to be called and a parameter.
*/
int cron_register_command
(const char *name, void (*function)(void *), void * parameter)
{
if (cron_registered_commands >= MAX_CRON_COMMANDS) {
return -1;
}
cron_commands [cron_registered_commands].name = name;
cron_commands [cron_registered_commands].function = function;
cron_commands [cron_registered_commands].parameter = parameter;
cron_registered_commands++;
return 0;
}
/*
* Allocate a new crontab entry.
* This allocates from the freelist and returns NULL if no more entries
* are available.
* Implementation note: If cron_registered_entries is 0 we first
* initialize the entry_freelist and the entry_list.
*/
struct cron_entry *allocate_cron_entry (void)
{
size_t n;
struct cron_entry *e;
if (cron_registered_entries == 0) {
entry_list = NULL;
entry_freelist = &cron_entries [0];
for (n=0; n < (MAX_CRON_ENTRIES - 1); n++) {
cron_entries [n].next = &cron_entries [n+1];
}
cron_entries [MAX_CRON_ENTRIES - 1].next = NULL;
}
if (cron_registered_entries >= MAX_CRON_ENTRIES) {
return NULL;
}
e = entry_freelist;
entry_freelist = e->next;
e->next = entry_list;
entry_list = e;
cron_registered_entries++;
return e;
}
void free_cron_entry (struct cron_entry *obsolete)
{
struct cron_entry *e;
assert (cron_registered_entries);
if (entry_list == obsolete) {
entry_list = obsolete->next;
obsolete->next = entry_freelist;
entry_freelist = obsolete;
cron_registered_entries--;
return;
}
for (e=entry_list; e; e=e->next) {
if (e->next == obsolete) {
e->next = obsolete->next;
obsolete->next = entry_freelist;
entry_freelist = obsolete;
cron_registered_entries--;
break;
}
}
assert (e != NULL);
}
struct cron_entry *get_cron_entry (size_t idx)
{
if (idx >= MAX_CRON_ENTRIES) {
return NULL;
}
return &cron_entries [idx];
}
/* Set the number in bits, return 0 on success -1 on error */
static int set_element (bitstr_t *bits, int low, int high, int n)
{
if (n < low || n > high) {
return -1;
}
bit_set (bits, (n - low));
return 0;
}
static const char *get_number (int *np, int high, const char *s)
{
char *endptr;
long l = strtol (s, &endptr, 10);
if (endptr == s || errno == ERANGE || l > high) {
return NULL;
}
*np = l;
return endptr;
}
static const char *get_range (bitstr_t *bits, int low, int high, const char *s)
{
int i;
int n1, n2, n3;
if (*s == '*') {
/* '*' means "first-last" but can be modified by /step */
n1 = low;
n2 = high;
if (*++s == '\0') {
return NULL;
}
} else {
s = get_number (&n1, high, s);
if (s == NULL || *s == '\0') {
return NULL;
}
if (*s != '-') {
if (set_element (bits, low, high, n1) < 0) {
return NULL;
}
return s;
} else {
if (*++s == '\0') {
return NULL;
}
s = get_number (&n2, high, s);
if (*s == '\0') {
return NULL;
}
}
}
if (*s == '/') {
if (*++s == '\0') {
return NULL;
}
s = get_number (&n3, high, s);
if (*s == '\0') {
return NULL;
}
} else {
n3 = 1;
}
/* Explicit check for sane values */
if (n1 < low || n1 > high || n2 < low || n2 > high) {
return NULL;
}
for (i=n1; i<=n2; i+=n3) {
if (set_element (bits, low, high, i) < 0) {
return NULL;
}
}
return s;
}
static const char *get_list (bitstr_t *bits, int low, int high, const char *s)
{
int done = 0;
bit_nclear (bits, 0, (high - low + 1));
while (!done) {
s = get_range (bits, low, high, s);
if (NULL == s) {
return NULL;
}
if (*s == ',') {
s++;
} else {
done = 1;
}
}
/* Skip white space */
while (s && isspace (*s)) {
s++;
}
return s;
}
/*
* Parse a single crontab entry on a single line.
* We get the line via CoAP.
* Returns 0 if parsed successfully, -1 on error.
* On error the err pointer is set to the error message.
*/
int parse_crontab_line
(const char *line, struct cron_entry *e, const char **err)
{
size_t n;
const char *s = line;
size_t cmd_len = 0;
e->flags &= ~VALID;
if (*s == '*') {
e->flags |= MIN_STAR;
}
s = get_list (e->minute, FIRST_MINUTE, LAST_MINUTE, s);
if (NULL == s || *s == '\0') {
*err = "minute";
return -1;
}
if (*s == '*') {
e->flags |= HR_STAR;
}
s = get_list (e->hour, FIRST_HOUR, LAST_HOUR, s);
if (NULL == s || *s == '\0') {
*err = "hour";
return -1;
}
if (*s == '*') {
e->flags |= DOM_STAR;
}
s = get_list (e->dom, FIRST_DOM, LAST_DOM, s);
if (NULL == s || *s == '\0') {
*err = "dom";
return -1;
}
s = get_list (e->month, FIRST_MONTH, LAST_MONTH, s);
if (NULL == s || *s == '\0') {
*err = "month";
return -1;
}
if (*s == '*') {
e->flags |= DOW_STAR;
}
s = get_list (e->dow, FIRST_DOW, LAST_DOW, s);
if (NULL == s || *s == '\0') {
*err = "dow";
return -1;
}
/* Make sundays equivalent */
if (bit_test (e->dow, 0) || bit_test (e->dow, 7)) {
bit_set (e->dow, 0);
bit_set (e->dow, 7);
}
/* strip whitespace at *end* of command
* by getting length without whitespace
*/
for (n=0; s [n]; n++) {
if (!isspace (s [n])) {
cmd_len = n + 1;
}
}
for (n=0; n<cron_registered_commands; n++) {
if ( cmd_len == strlen (cron_commands [n].name)
&& !strncmp (cron_commands [n].name, s, cmd_len)
)
{
e->cmd = &cron_commands [n];
break;
}
}
if (n == cron_registered_commands) {
*err = "command";
return -1;
}
e->flags |= VALID;
return 0;
}
static void set_time (void)
{
struct xtm *tm;
struct xtimeval tv;
xgettimeofday (&tv, NULL);
start_time = tv.tv_sec;
tm = xlocaltime (&start_time);
/* We adjust the time to GMT so we can catch DST changes */
cron_clock_time = (start_time + tm->tm_gmtoff) / (xtime_t)SECONDS_PER_MINUTE;
}
static void find_jobs (minute_t vtime, int do_wild, int do_nonwild)
{
xtime_t virtual_second = vtime * SECONDS_PER_MINUTE;
struct xtm *tm = xgmtime (&virtual_second);
int minute, hour, dom, month, dow;
struct cron_entry *e;
/* make 0-based values out of these so we can use them as indicies */
minute = tm->tm_min -FIRST_MINUTE;
hour = tm->tm_hour -FIRST_HOUR;
dom = tm->tm_mday -FIRST_DOM;
month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
dow = tm->tm_wday -FIRST_DOW;
#ifdef DEBUG
printf ("%d %d %d %d %d\n", minute, hour, dom, month, dow);
#endif
/* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
* first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
* on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this
* is why we keep 'e->dow_star' and 'e->dom_star'. yes, it's bizarre.
* like many bizarre things, it's the standard.
*/
for (e = entry_list; e; e = e->next) {
#ifdef DEBUG
if (e->flags & VALID) {
printf ("Checking entry %s\n", e->cmd->name);
}
printf ("valid: %d\n", (e->flags & VALID));
printf ("minute: %d\n", (bit_test (e->minute, minute)));
printf ("hour: %d\n", (bit_test (e->hour, hour)));
printf ("month %d\n", (bit_test (e->month, month)));
printf ("dom* %d\n", (e->flags & DOM_STAR));
printf ("dow* %d\n", (e->flags & DOW_STAR));
printf ("dow %d\n", (bit_test (e->dow, dow)));
printf ("dom %d\n", (bit_test (e->dom, dom)));
printf ("min* %d\n", (e->flags & MIN_STAR));
printf ("hr* %d\n", (e->flags & HR_STAR));
printf ("nonwild %d\n", (do_nonwild));
#endif
if ( (e->flags & VALID)
&& bit_test (e->minute, minute)
&& bit_test (e->hour, hour)
&& bit_test (e->month, month)
&& ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
? (bit_test (e->dow, dow) && bit_test (e->dom, dom))
: (bit_test (e->dow, dow) || bit_test (e->dom, dom))
)
)
{
if ( (do_nonwild && !(e->flags & (MIN_STAR | HR_STAR)))
|| (do_wild && (e->flags & (MIN_STAR | HR_STAR)))
)
{
printf ("Cron: calling \"%s\"\n", e->cmd->name);
e->cmd->function (e->cmd->parameter);
}
}
}
}
/*
* The cron callback function must be run regularly, at least once per
* minute.
* Implementation:
* Clocks are in minutes since the epoch (time() / 60).
* virtual_time is the time it *would* be if we are called promptly and
* nobody ever changed the clock. It is monotonically increasing...
* unless a timejump happens.
* time_running is the time we were last called. We determine
* initialization by checking time_running for -1.
* cron_clock_time is the current time for this run.
*/
void cron (void)
{
static minute_t time_running = -1;
static minute_t virtual_time = -1;
minute_t time_diff;
/*
* ... calculate how the current time differs from
* our virtual clock. Classify the change into one
* of 4 cases
*/
set_time ();
if (time_running == cron_clock_time) {
#ifdef DEBUG
printf ("time not reached\n");
#endif
return;
}
time_running = cron_clock_time;
time_diff = time_running - virtual_time;
#ifdef DEBUG
printf ("time_diff: %ld\n", (long)time_diff);
#endif
/* shortcut for the most common case */
if (time_diff == 1) {
virtual_time = time_running;
find_jobs (virtual_time, 1, 1);
} else {
int wakeup_kind = -1;
if (time_diff > -(3*MINUTE_COUNT)) {
wakeup_kind = 0;
}
if (time_diff > 0) {
wakeup_kind = 1;
}
if (time_diff > 5) {
wakeup_kind = 2;
}
if (time_diff > (3*MINUTE_COUNT)) {
wakeup_kind = 3;
}
#ifdef DEBUG
printf ("wakeup_kind: %d\n", wakeup_kind);
#endif
switch (wakeup_kind) {
/* time_diff is a small positive number (wokeup late)
* run jobs for each virtual minute until caught up.
*/
case 1:
do {
virtual_time++;
find_jobs (virtual_time, 1, 1);
} while (virtual_time < time_running);
break;
/* time_diff is a medium-sized positive number, for example
* because we went to DST. Run wildcard jobs once, then run any
* fixed-time jobs that would otherwise be skipped. If we use up
* our minute (possible, if there are a lot of jobs to run) go
* around the loop again so that wildcard jobs have a chance to
* run, and we do our housekeeping.
*/
case 2:
/* run wildcard jobs for current minute */
find_jobs (time_running, 1, 0);
/* run fixed-time jobs for each minute missed */
do {
virtual_time++;
find_jobs (virtual_time, 0, 1);
set_time ();
} while ( virtual_time < time_running
&& cron_clock_time == time_running
);
break;
/* time_diff is a small or medium-sized negative num, eg.
* because of DST ending. Just run the wildcard jobs. The
* fixed-time jobs probably have already run, and should not be
* repeated. virtual_time does not change until we are caught up.
*/
case 0:
find_jobs (time_running, 1, 0);
break;
/* Other: time has changed a *lot*, jump virtual time, and run
* everything
*/
default:
virtual_time = time_running;
find_jobs (time_running, 1, 1);
break;
}
}
}

91
apps/time/cron.h Normal file
View file

@ -0,0 +1,91 @@
/*
* Definitions for cron
* Inspired by vixie's cron by Paul Vixie which is
* Copyright 1988,1990,1993,1994 by Paul Vixie
*
* Distribute freely, except: don't remove my name from the source or
* documentation (don't take credit for my work), mark your changes (don't
* get me blamed for your possible bugs), don't alter or remove this
* notice. May be sold if buildable source is provided to buyer. No
* warrantee of any kind, express or implied, is included with this
* software; use at your own risk, responsibility for damages (if any) to
* anyone resulting from the use of this software rests entirely with the
* user.
* Changes to make this work on a microcontroller by Ralf Schlatterbeck
* In fact this is mostly a rewrite but keeps central algorithms of the
* original.
* Copyright 2016 Ralf Schlatterbeck, distribute with the conditions
* given above.
*/
#ifndef _cron_h_
#define _cron_h_
#include "bitstring.h"
#define SECONDS_PER_MINUTE 60
#define FIRST_MINUTE 0
#define LAST_MINUTE 59
#define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1)
#define FIRST_HOUR 0
#define LAST_HOUR 23
#define HOUR_COUNT (LAST_HOUR - FIRST_HOUR + 1)
#define FIRST_DOM 1
#define LAST_DOM 31
#define DOM_COUNT (LAST_DOM - FIRST_DOM + 1)
#define FIRST_MONTH 1
#define LAST_MONTH 12
#define MONTH_COUNT (LAST_MONTH - FIRST_MONTH + 1)
/* note on DOW: 0 and 7 are both Sunday, for compatibility reasons. */
#define FIRST_DOW 0
#define LAST_DOW 7
#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1)
#ifndef MAX_CRON_ENTRIES
#define MAX_CRON_ENTRIES 5
#endif
#ifndef MAX_CRON_COMMANDS
#define MAX_CRON_COMMANDS 5
#endif
struct cron_cmd {
const char *name;
void (*function)(void *);
void *parameter;
};
struct cron_entry {
struct cron_entry *next;
struct cron_cmd *cmd;
bitstr_t bit_decl(minute, MINUTE_COUNT);
bitstr_t bit_decl(hour, HOUR_COUNT);
bitstr_t bit_decl(dom, DOM_COUNT);
bitstr_t bit_decl(month, MONTH_COUNT);
bitstr_t bit_decl(dow, DOW_COUNT);
int flags;
#define DOM_STAR 0x01
#define DOW_STAR 0x02
#define WHEN_REBOOT 0x04
#define MIN_STAR 0x08
#define HR_STAR 0x10
#define VALID 0x20
};
extern int parse_crontab_line
(const char *line, struct cron_entry *e, const char **err);
extern int cron_register_command
(const char *name, void (*function)(void *), void * parameter);
extern struct cron_entry *allocate_cron_entry (void);
extern struct cron_entry *get_cron_entry (size_t idx);
extern void free_cron_entry (struct cron_entry *e);
extern void cron (void);
#endif /* _cron_h_ */

View file

@ -0,0 +1,125 @@
/**
* \file
* Resource for crontab entry
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
* \brief get/put crontab entry
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "time_resource.h"
#include "jsonparse.h"
#include "er-coap.h"
#include "generic_resource.h"
#include "cron.h"
static size_t get_index_from_uri (const char *uri)
{
const char *s;
char *endptr;
size_t idx;
if (uri == NULL) {
return MAX_CRON_ENTRIES;
}
if (NULL == (s = strrchr (uri, '/'))) {
return MAX_CRON_ENTRIES;
}
idx = strtoul (s+1, &endptr, 10);
if (s == endptr || *endptr != '\0') {
return MAX_CRON_ENTRIES;
}
return idx;
}
int crontab_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
const char *err;
int res;
size_t idx = get_index_from_uri (uri);
if (idx >= MAX_CRON_ENTRIES) {
return -1;
}
res = parse_crontab_line (s, get_cron_entry (idx), &err);
if (res < 0) {
printf ("Error parsing: %s\n", err);
return -1;
}
return 0;
}
size_t
crontab_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
/* FIXME: For now we only return "valid" or "invalid" until someone
* comes up with a clever algorithm to reconstruct a crontab string
* from the cron_entry struct.
*/
size_t idx = get_index_from_uri (uri);
struct cron_entry *e;
if (idx >= MAX_CRON_ENTRIES) {
return MAX_GET_STRING_LENGTH;
}
e = get_cron_entry (idx);
if (e->flags & VALID) {
return snprintf (buf, bsize, "valid");
}
return snprintf (buf, bsize, "invalid");
}
GENERIC_RESOURCE
( crontab
, crontab-entry
, s
, 1
, crontab_from_string
, crontab_to_string
);
/* Allocate all cron entries and the necessary resources */
void activate_cron_resources (void)
{
size_t n;
for (n=0; n<MAX_CRON_ENTRIES; n++) {
resource_t *res;
char *buf;
size_t len;
struct cron_entry *e;
char name [15];
/* Need to copy the resource because resource->url holds the path
* under which we activate it using rest_activate_resource
*/
if (NULL == (res = malloc (sizeof (*res)))) {
printf ("Error malloc\n");
break;
}
memcpy (res, &res_crontab, sizeof (*res));
e = allocate_cron_entry ();
assert (!(e->flags & VALID));
len = snprintf (name, sizeof (name), "crontab/%u", n);
name [sizeof (name) -1] = '\0';
assert (len < 15);
if (NULL == (buf = malloc (len + 1))) {
printf ("Error malloc\n");
break;
}
strcpy (buf, name);
rest_activate_resource (res, buf);
}
}
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/

View file

@ -0,0 +1,63 @@
/**
* \file
* Resource for gmtime (utc) / localtime handling
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
* \brief get time as a string in utc or localtime
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "xtime.h"
#include "time_resource.h"
#include "jsonparse.h"
#include "er-coap.h"
#include "generic_resource.h"
size_t time_to_string
(const char *name, const char *uri, const char *query, char *buf, size_t bs)
{
struct xtimeval tv;
struct xtm tm;
struct xtm *(*method)(const xtime_t *, struct xtm *) = xgmtime_r;
if (0 == strcmp (name, "localtime")) {
method = xlocaltime_r;
}
xgettimeofday (&tv, NULL);
method (&tv.tv_sec, &tm);
return snprintf
( buf
, bs
, "%lu-%02u-%02u %02u:%02u:%02u %s"
, 1900 + tm.tm_year
, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec
, tm.tm_zone
);
}
GENERIC_RESOURCE \
( localtime
, Local time
, formatted time
, 1
, NULL
, time_to_string
);
GENERIC_RESOURCE \
( utc
, UTC
, formatted time
, 1
, NULL
, time_to_string
);
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/

View file

@ -0,0 +1,63 @@
/**
* \file
* Resource for timestamp handling
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
* \brief get/put time in seconds since 1970 (UNIX time)
* Note: the internal format of the time in seconds is a 64bit number
* unfortunately javascript (json) will only support double for which
* the mantissa isn't long enough for representing that number. So we're
* back to 32 bit and have a year 2038 problem.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "xtime.h"
#include "time_resource.h"
#include "jsonparse.h"
#include "er-coap.h"
#include "generic_resource.h"
int timestamp_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
struct xtimeval tv;
// FIXME: Platform has no strtoll (long long)?
tv.tv_sec = strtol (s, NULL, 10);
xsettimeofday (&tv, NULL);
return 0;
}
size_t
timestamp_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
struct xtimeval tv;
xgettimeofday (&tv, NULL);
// FIXME: Platform doesn't seem to support long long printing
// We get empty string
return snprintf (buf, bsize, "%ld", (long)tv.tv_sec);
}
GENERIC_RESOURCE
( timestamp
, Time
, s
, 1
, timestamp_from_string
, timestamp_to_string
);
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/

View file

@ -0,0 +1,55 @@
/**
* \file
* Resource for timezone handling
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
* \brief get/put timezone string
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "xtime.h"
#include "time_resource.h"
#include "jsonparse.h"
#include "er-coap.h"
#include "generic_resource.h"
int timezone_from_string
(const char *name, const char *uri, const char *query, const char *s)
{
set_tz (s);
return 0;
}
size_t
timezone_to_string
( const char *name
, const char *uri
, const char *query
, char *buf
, size_t bsize
)
{
if (get_tz (buf, bsize) == NULL) {
*buf = '\0';
}
return strlen (buf);
}
GENERIC_RESOURCE
( timezone
, TZ
, s
, 1
, timezone_from_string
, timezone_to_string
);
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/

847
apps/time/time.c Normal file
View file

@ -0,0 +1,847 @@
/**
* \addgroup Time related functions
*
* @{
*/
#include "contiki.h"
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "contiki-lib.h"
#include "xtime.h"
#include "tzparse.h"
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
static const int mon_lengths[2][MONSPERYEAR] =
{ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
/*
* Static timezone information
*/
static struct tzoffset_info localtime_tzoffset;
/* Used for gmtime and localtime, according to manpage on linux the
* internal value may be overwritten "by subsequent calls to any of the
* date and time functions".
*/
static struct xtm tm;
/*
* Internal variables to manage offset of utc from the contiki clock
* and timezone offset from utc in minutes.
* For now we don't manage the sub-second offset -- time of setting the
* clock and the precisiont of the clock in use don't warrant this
* effort.
* The last_seconds is used to check if we had a seconds overflow,
* although this happens only every 136 years :-)
*/
static xtime_t clock_offset;
static uint32_t last_seconds;
static xtime_t
transtime (xtime_t janfirst, int year, const struct tzrule *rp, long offset);
# define LEAP_YEAR(_year) \
((_year % 4) == 0 && (_year % 100 != 0 || _year % 400 == 0))
# define YDAYS(_year) (LEAP_YEAR(year) ? 366 : 365)
struct xtm *xgmtime_r (const xtime_t *timep, struct xtm *ptm)
{
unsigned int year;
int days, month, month_len;
xtime_t t = *timep;
ptm->tm_sec = t % 60;
t /= 60;
ptm->tm_min = t % 60;
t /= 60;
ptm->tm_hour = t % 24;
t /= 24;
ptm->tm_wday = (t+4) % 7;
year = 1970;
days = 0;
while ((days += YDAYS (year)) <= t)
{
year++;
}
ptm->tm_year = year - 1900;
days -= YDAYS (year);
t -= days;
ptm->tm_yday = t;
for (month=0; month<12; month++)
{
if (month == 1)
{
month_len = LEAP_YEAR (year) ? 29 : 28;
}
else
{
int m = month;
if (m >= 7)
{
m -= 1;
}
m &= 1;
month_len = m ? 30 : 31;
}
if (t >= month_len)
{
t -= month_len;
}
else
{
break;
}
}
ptm->tm_mon = month;
ptm->tm_mday = t + 1;
ptm->tm_isdst = 0;
ptm->tm_gmtoff = 0;
ptm->tm_zone = "UTC";
return ptm;
}
struct xtm *xgmtime (const xtime_t *timep)
{
return xgmtime_r (timep, &tm);
}
/*
* Compute is_dst flag of given timestamp
*/
static int is_dst (const xtime_t *timep, const struct tzoffset_info *tzo)
{
xtime_t janfirst = 0;
xtime_t starttime, endtime;
int year = 1970;
int lastdst = 0;
if (tzo->dstname == NULL) {
return 0;
}
for (year = 1970; janfirst < *timep; year++) {
starttime = transtime (janfirst, year, &tzo->start, tzo->stdoffset);
endtime = transtime (janfirst, year, &tzo->end, tzo->dstoffset);
if (starttime <= *timep && endtime <= *timep) {
lastdst = (starttime > endtime);
} else if (starttime > *timep && endtime <= *timep) {
return 0;
} else if (starttime <= *timep && endtime > *timep) {
return 1;
} else if (starttime > *timep && endtime > *timep) {
return lastdst;
}
janfirst += YDAYS (year) * SECSPERDAY;
}
return lastdst;
}
struct xtm *xlocaltime_r (const xtime_t *timep, struct xtm *ptm)
{
const struct tzoffset_info *tzo = &localtime_tzoffset;
int isdst = 0;
long offset = 0;
xtime_t t = *timep;
if (tzo->stdname == NULL) {
set_tz (DEFAULT_TIMEZONE);
}
isdst = is_dst (timep, tzo);
offset = isdst ? tzo->dstoffset : tzo->stdoffset;
t -= offset;
xgmtime_r (&t, ptm);
ptm->tm_isdst = isdst;
ptm->tm_gmtoff = -offset;
ptm->tm_zone = isdst ? tzo->dstname : tzo->stdname;
return ptm;
}
struct xtm *xlocaltime (const xtime_t *timep)
{
return xlocaltime_r (timep, &tm);
}
/**
* \brief Get time in seconds and microseconds
* xgettimeofday will return the clock time as the microseconds part
* while xsettimeofday will *ignore* the microseconds part (for now).
* Note that the contiki clock interface is broken anyway, we can't read
* seconds and sub-seconds atomically. We try to work around this by
* repeatedly reading seconds, sub-seconds, seconds until first and
* second read of seconds match.
*/
int xgettimeofday (struct xtimeval *tv, struct timezone *tz)
{
uint32_t cs;
if (tv) {
int i;
/* Limit tries to get the same second twice to two */
for (i=0; i<2; i++) {
cs = clock_seconds ();
if (cs < last_seconds) {
clock_offset += 0xFFFFFFFFL;
clock_offset ++;
}
last_seconds = cs;
tv->tv_sec = cs + clock_offset;
tv->tv_usec = ((xtime_t)(clock_time () % CLOCK_SECOND))
* 1000000L / CLOCK_SECOND;
if (cs == clock_seconds ()) {
break;
}
}
}
if (tz) {
const struct tzoffset_info *tzo = &localtime_tzoffset;
tz->tz_dsttime = is_dst (&tv->tv_sec, tzo);
if (tz->tz_dsttime) {
tz->tz_minuteswest = -tzo->dstoffset / 60;
} else {
tz->tz_minuteswest = -tzo->stdoffset / 60;
}
}
return 0;
}
/**
* \brief Set time in seconds, microseconds ignored for now
*/
int xsettimeofday (const struct xtimeval *tv, const struct timezone *tz)
{
/* Don't allow setting timezone */
if (tz) {
errno = ERANGE;
return -1;
}
if (tv) {
uint32_t cs;
cs = clock_seconds ();
clock_offset = tv->tv_sec - cs;
}
return 0;
}
/*
* Save timezone names into reserved string buffer and fill in the names
* into the given tzoffset_info.
* Return -1 on error, 0 for success.
*/
static int save_tznames
( const char *stdname, const char *dstname
, size_t stdlen, size_t dstlen
, struct tzoffset_info *tzo
)
{
size_t len = stdlen;
if (stdname == NULL) {
return -1;
}
if (dstname != NULL) {
len += dstlen;
}
if (len + 2 > sizeof (tzo->namebuf)) {
return -1;
}
tzo->stdname = tzo->namebuf;
strncpy (tzo->namebuf, stdname, stdlen);
tzo->namebuf [stdlen] = '\0';
if (dstlen) {
strncpy (tzo->namebuf + stdlen + 1, dstname, dstlen);
tzo->namebuf [stdlen + 1 + dstlen] = '\0';
tzo->dstname = tzo->namebuf + stdlen + 1;
} else {
tzo->dstname = NULL;
}
return 0;
}
/*
* Utility functions for timezone string parsing (POSIX section 8)
* Code adapted from OpenBSD localtime.c 1.57 2015/12/12 21:25:44
* which is in the public domain.
*/
/*
* The DST rules to use if TZ has no rules:
* We default to US rules as of 1999-08-17.
* POSIX 1003.1 section 8.1.1 says that the default DST rules are
* implementation dependent; for historical reasons, US rules are a
* common default.
*/
#ifndef TZDEFRULESTRING
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
#endif
/*
* Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
* year, a rule, and the offset from UTC at the time that rule takes effect,
* calculate the Epoch-relative time that rule takes effect.
*/
static xtime_t
transtime(xtime_t janfirst, int year, const struct tzrule *rulep, long offset)
{
int leapyear;
xtime_t value;
int i;
int d, m1, yy0, yy1, yy2, dow;
value = 0;
leapyear = LEAP_YEAR (year);
switch (rulep->r_type) {
case JULIAN_DAY:
/*
* Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
* years.
* In non-leap years, or if the day number is 59 or less, just
* add SECSPERDAY times the day number-1 to the time of
* January 1, midnight, to get the day.
*/
value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
if (leapyear && rulep->r_day >= 60) {
value += SECSPERDAY;
}
break;
case DAY_OF_YEAR:
/*
* n - day of year.
* Just add SECSPERDAY times the day number to the time of
* January 1, midnight, to get the day.
*/
value = janfirst + rulep->r_day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
/*
* Mm.n.d - nth "dth day" of month m.
*/
value = janfirst;
for (i = 0; i < rulep->r_mon - 1; ++i) {
value += mon_lengths [leapyear][i] * SECSPERDAY;
}
/*
** Use Zeller's Congruence to get day-of-week of first day of
** month.
*/
m1 = (rulep->r_mon + 9) % 12 + 1;
yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
yy1 = yy0 / 100;
yy2 = yy0 % 100;
dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
if (dow < 0) {
dow += DAYSPERWEEK;
}
/*
** "dow" is the day-of-week of the first day of the month. Get
** the day-of-month (zero-origin) of the first "dow" day of the
** month.
*/
d = rulep->r_day - dow;
if (d < 0) {
d += DAYSPERWEEK;
}
for (i = 1; i < rulep->r_week; ++i) {
if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1]) {
break;
}
d += DAYSPERWEEK;
}
/*
** "d" is the day-of-month (zero-origin) of the day we want.
*/
value += d * SECSPERDAY;
break;
}
/*
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
** question. To get the Epoch-relative time of the specified local
** time on that day, add the transition time and the current offset
** from UTC.
*/
return value + rulep->r_time + offset;
}
/*
* Given a pointer into a time zone string, scan until a character that is not
* a valid character in a zone name is found. Return a pointer to that
* character.
*/
static const char *getzname (const char *s)
{
char c;
while ((c = *s) != '\0' && !isdigit(c) && c != ',' && c != '-' && c != '+'){
++s;
}
return s;
}
/*
* Given a pointer into an extended time zone string, scan until the ending
* delimiter of the zone name is located. Return a pointer to the delimiter.
*
* As with getzname above, the legal character set is actually quite
* restricted, with other characters producing undefined results.
* We don't do any checking here; checking is done later in common-case code.
*/
static const char *getqzname (const char *strp, const int delim)
{
int c;
while ((c = *strp) != '\0' && c != delim) {
++strp;
}
return strp;
}
/*
* Given a pointer into a time zone string, extract a number from that string.
* Check that the number is within a specified range; if it is not, return
* NULL.
* Otherwise, return a pointer to the first character not part of the number.
*/
static const char *getnum (const char *strp, int *nump, int min, int max)
{
char c;
int num;
if (strp == NULL || !isdigit ((c = *strp))) {
return NULL;
}
num = 0;
do {
num = num * 10 + (c - '0');
if (num > max) {
return NULL; /* illegal value */
}
c = *++strp;
} while (isdigit (c));
if (num < min) {
return NULL; /* illegal value */
}
*nump = num;
return strp;
}
/*
* Given a pointer into a time zone string, extract a number of seconds,
* in hh[:mm[:ss]] form, from the string.
* If any error occurs, return NULL.
* Otherwise, return a pointer to the first character not part of the number
* of seconds.
*/
static const char *getsecs (const char *strp, long *secsp)
{
int num;
/*
* `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
* "M10.4.6/26", which does not conform to Posix,
* but which specifies the equivalent of
* ``02:00 on the first Sunday on or after 23 Oct''.
*/
strp = getnum (strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
if (strp == NULL) {
return NULL;
}
*secsp = num * (long) SECSPERHOUR;
if (*strp == ':') {
++strp;
strp = getnum (strp, &num, 0, MINSPERHOUR - 1);
if (strp == NULL) {
return NULL;
}
*secsp += num * SECSPERMIN;
if (*strp == ':') {
++strp;
/* `SECSPERMIN' allows for leap seconds. */
strp = getnum (strp, &num, 0, SECSPERMIN);
if (strp == NULL) {
return NULL;
}
*secsp += num;
}
}
return strp;
}
/*
* Given a pointer into a time zone string, extract an offset, in
* [+-]hh[:mm[:ss]] form, from the string.
* If any error occurs, return NULL.
* Otherwise, return a pointer to the first character not part of the time.
*/
static const char *getoffset (const char *strp, long *offsetp)
{
int neg = 0;
if (*strp == '-') {
neg = 1;
++strp;
} else if (*strp == '+') {
++strp;
}
strp = getsecs (strp, offsetp);
if (strp == NULL) {
return NULL; /* illegal time */
}
if (neg) {
*offsetp = -*offsetp;
}
return strp;
}
/*
* Parse (optionally extended) timezone name. Return pointer to
* (undelimited) timezone name in tzn and length of same in len.
* Return pointer to first character *after* name, NULL on error.
* Factored from original tzparse function.
*/
static const char *
egettzname (const char *strp, size_t *len, const char **tzn)
{
*tzn = strp;
if (*strp == '<') {
strp++;
*tzn = strp;
strp = getqzname (strp, '>');
if (*strp != '>') {
return NULL;
}
*len = strp - *tzn;
strp++;
} else {
strp = getzname (strp);
*len = strp - *tzn;
}
return strp;
}
/*
** Given a pointer into a time zone string, extract a rule in the form
** date[/time]. See POSIX section 8 for the format of "date" and "time".
** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule.
*/
static const char *getrule (const char *strp, struct tzrule *rulep)
{
if (*strp == 'J') {
/*
* Julian day.
*/
rulep->r_type = JULIAN_DAY;
++strp;
strp = getnum (strp, &rulep->r_day, 1, DAYSPERNYEAR);
} else if (*strp == 'M') {
/*
* Month, week, day.
*/
rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
++strp;
strp = getnum (strp, &rulep->r_mon, 1, MONSPERYEAR);
if (strp == NULL) {
return NULL;
}
if (*strp++ != '.') {
return NULL;
}
strp = getnum (strp, &rulep->r_week, 1, 5);
if (strp == NULL) {
return NULL;
}
if (*strp++ != '.') {
return NULL;
}
strp = getnum (strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
} else if (isdigit (*strp)) {
/*
* Day of year.
*/
rulep->r_type = DAY_OF_YEAR;
strp = getnum (strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
} else {
return NULL; /* invalid format */
}
if (strp == NULL) {
return NULL;
}
if (*strp == '/') {
/*
* Time specified.
*/
++strp;
strp = getsecs (strp, &rulep->r_time);
} else {
rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
}
return strp;
}
/*
* Parse POSIX section 8 TZ string.
* We keep the misnomer "name" for the timezone string.
*/
int tzparse (const char *name, struct tzoffset_info *tzo)
{
const char *stdname;
const char *dstname;
size_t stdlen;
size_t dstlen;
long stdoffset;
long dstoffset;
dstname = NULL;
stdname = name;
name = egettzname (name, &stdlen, &stdname);
if (name == NULL || *name == '\0') {
return -1;
}
name = getoffset (name, &stdoffset);
if (name == NULL) {
return -1;
}
if (*name != '\0') {
name = egettzname (name, &dstlen, &dstname);
if (name == NULL) {
return -1;
}
if (*name != '\0' && *name != ',' && *name != ';') {
name = getoffset (name, &dstoffset);
if (name == NULL) {
return -1;
}
} else {
dstoffset = stdoffset - SECSPERHOUR;
}
if (*name == '\0') {
name = TZDEFRULESTRING;
}
if (*name == ',' || *name == ';') {
struct tzrule start;
struct tzrule end;
++name;
if ((name = getrule (name, &start)) == NULL) {
return -1;
}
if (*name++ != ',') {
return -1;
}
if ((name = getrule (name, &end)) == NULL) {
return -1;
}
if (*name != '\0') {
return -1;
}
if (save_tznames (stdname, dstname, stdlen, dstlen, tzo) != 0) {
return -1;
}
tzo->start = start;
tzo->end = end;
tzo->stdoffset = stdoffset;
tzo->dstoffset = dstoffset;
} else {
return -1;
}
} else {
/* only standard time, no DST */
if (save_tznames (stdname, NULL, stdlen, 0, tzo) != 0) {
return -1;
}
tzo->stdoffset = stdoffset;
tzo->dstoffset = stdoffset;
}
return 0;
}
/*
* Provide a single static timezone which is used by localtime et.al.
*/
int set_tz (const char *tzstring)
{
return tzparse (tzstring, &localtime_tzoffset);
}
static size_t lensecs (long seconds)
{
size_t len = 1;
long secs = abs (seconds);
if (seconds < 0) {
len++;
}
if (secs / 3600 > 9) {
len++;
}
if (secs % 3600) {
len += 3;
if (secs % 60) {
len += 3;
}
}
return len;
}
/*
* Get length of string resulting from serializing rule.
*/
static size_t lenrule (const struct tzrule *rule)
{
size_t len = 0;
if (rule->r_type == JULIAN_DAY) {
len++;
}
if (rule->r_type == JULIAN_DAY || rule->r_type == DAY_OF_YEAR) {
len++;
if (rule->r_day > 9) {
len++;
if (rule->r_day > 99) {
len++;
}
}
} else if (rule->r_type == MONTH_NTH_DAY_OF_WEEK) {
len++;
len++;
if (rule->r_mon > 9) {
len++;
}
len += 4; /* dots and week/day */
if (rule->r_time != 7200) {
len++;
len += lensecs (rule->r_time);
}
}
return len;
}
static int is_extended_name (const char *name)
{
int i;
for (i=0; name [i]; i++) {
if (isdigit (name [i]) || name [i] == '+' || name [i] == '-') {
return 1;
}
}
return 0;
}
/*
* Get length of timezone string resulting from serializing tzo.
*/
static size_t len_tz_r (const struct tzoffset_info *tzo)
{
size_t len = 0;
if (tzo->stdname == NULL) {
return 0;
}
len = strlen (tzo->stdname);
if (is_extended_name (tzo->stdname)) {
len += 2;
}
len += lensecs (tzo->stdoffset);
if (tzo->dstname) {
len += strlen (tzo->dstname);
if (is_extended_name (tzo->dstname)) {
len += 2;
}
if (tzo->dstoffset - tzo->stdoffset != -3600) {
len += lensecs (tzo->dstoffset);
}
len += 2; /* commas */
len += lenrule (&tzo->start);
len += lenrule (&tzo->end);
}
return len;
}
size_t len_tz (void)
{
return len_tz_r (&localtime_tzoffset);
}
void appendsecs (char *buf, long minutes)
{
char *p = buf + strlen (buf);
long min = abs (minutes);
if (minutes < 0) {
*p++ = '-';
}
if (min % 3600 == 0) {
sprintf (p, "%ld", min / 3600);
} else if (min % 60 == 0) {
sprintf (p, "%ld:%ld", min / 3600, (min / 60) % 60);
} else {
sprintf (p, "%ld:%ld:%ld", min / 3600, (min / 60) % 60, min % 60);
}
}
void appendrule (char *buf, const struct tzrule *rule)
{
char *p = buf + strlen (buf);
if (rule->r_type == JULIAN_DAY) {
sprintf (p, "J%d", rule->r_day);
} else if (rule->r_type == DAY_OF_YEAR) {
sprintf (p, "%d", rule->r_day);
} else if (rule->r_type == MONTH_NTH_DAY_OF_WEEK) {
sprintf (p, "M%d.%d.%d", rule->r_mon, rule->r_week, rule->r_day);
p = buf + strlen (buf);
if (rule->r_time != 7200) {
*p++ = '/';
*p = '\0';
appendsecs (p, rule->r_time);
}
}
}
const char *get_tz (char *buf, size_t buflen)
{
const struct tzoffset_info *tzo = &localtime_tzoffset;
if (tzo->stdname == NULL || len_tz_r (tzo) > buflen) {
return NULL;
}
if (is_extended_name (tzo->stdname)) {
sprintf (buf, "<%s>", tzo->stdname);
} else {
strcpy (buf, tzo->stdname);
}
appendsecs (buf, tzo->stdoffset);
if (tzo->dstname != NULL) {
if (is_extended_name (tzo->dstname)) {
sprintf (buf + strlen (buf), "<%s>", tzo->dstname);
} else {
strcat (buf, tzo->dstname);
}
if (tzo->dstoffset - tzo->stdoffset != -3600) {
appendsecs (buf, tzo->dstoffset);
}
strcat (buf, ",");
appendrule (buf, &tzo->start);
strcat (buf, ",");
appendrule (buf, &tzo->end);
}
return buf;
}
/** @} */

32
apps/time/time_resource.h Normal file
View file

@ -0,0 +1,32 @@
/**
* \addgroup Time related functions
*
* Resource definitions for time module
*
* @{
*/
/**
* \file
* Resource definitions for the time module
*
* \author
* Ralf Schlatterbeck <rsc@tux.runtux.com>
*/
#ifndef time_resource_h
#define time_resource_h
#include <assert.h>
#include "contiki.h"
#include "rest-engine.h"
extern resource_t res_timestamp;
extern resource_t res_timezone;
extern resource_t res_crontab;
extern resource_t res_localtime;
extern resource_t res_utc;
extern void activate_cron_resources (void);
#endif // time_resource_h
/** @} */

56
apps/time/tzparse.h Normal file
View file

@ -0,0 +1,56 @@
/*
* Timezone parsing
*/
/**
* \file
* Definitions for timezone parsing
*
* \author
* Ralf Schlatterbeck <rsc@tux.runtux.com>
*/
#ifndef tzparse_h
#define tzparse_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* Rule for DST switching
*/
struct tzrule {
int r_type; /* type of rule--see below */
int r_day; /* day number of rule */
int r_week; /* week number of rule */
int r_mon; /* month number of rule */
long r_time; /* transition time of rule */
};
#define JULIAN_DAY 0 /* Jn - Julian day */
#define DAY_OF_YEAR 1 /* n - day of year */
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
/*
* Info about timezone offset handling.
* We get at least a dstname and stdoffset, if no daylight saving is in
* effect, dstname is NULL and no rule is filled in.
*/
struct tzoffset_info {
const char *stdname;
const char *dstname;
long stdoffset;
long dstoffset;
struct tzrule start;
struct tzrule end;
char namebuf [TZ_MAX_CHARS];
};
int tzparse (const char *name, struct tzoffset_info *tzo);
#ifdef __cplusplus
}
#endif
#endif // tzparse_h

94
apps/time/xtime.h Normal file
View file

@ -0,0 +1,94 @@
/**
* \defgroup Time related functions
*
* This rolls the necessary definition for getting/setting time and
* managing local time into one include file, on posix systems this
* lives in at least two include files, time.h and sys/time.h
*
* @{
*/
/**
* \file
* Definitions for the time module
*
* \author
* Ralf Schlatterbeck <rsc@tux.runtux.com>
*/
#ifndef xtime_h
#define xtime_h
/* This is a time.h implementation but to avoid name-clashes with libs
* trying to be helpfull we add the prefix x
*/
#ifdef LOCAL_COMPILE
#define clock_seconds() 1
#define clock_time() 1
#endif
#define DEFAULT_TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
typedef signed long long xtime_t;
typedef signed long suseconds_t;
#ifdef __cplusplus
extern "C" {
#endif
/* tm_gmtoff and tm_zone are BSD additions */
struct xtm {
uint32_t tm_year; /* year */
uint16_t tm_yday; /* day in the year */
uint8_t tm_sec; /* seconds */
uint8_t tm_min; /* minutes */
uint8_t tm_hour; /* hours */
uint8_t tm_mday; /* day of the month */
uint8_t tm_mon; /* month */
uint8_t tm_wday; /* day of the week */
uint8_t tm_isdst; /* daylight saving time */
int32_t tm_gmtoff; /* Seconds east of UTC */
const char *tm_zone; /* Timezone abbreviation */
};
struct xtimeval {
xtime_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int16_t tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction, unused */
};
struct xtm *xgmtime (const xtime_t *timep);
struct xtm *xgmtime_r (const xtime_t *timep, struct xtm *result);
struct xtm *xlocaltime (const xtime_t *timep);
struct xtm *xlocaltime_r (const xtime_t *timep, struct xtm *result);
int xgettimeofday (struct xtimeval *tv, struct timezone *tz);
int xsettimeofday (const struct xtimeval *tv, const struct timezone *tz);
/*
* Maximum length of all timezone names, this is much longer in UNIX
* implementations but we have limited space here. Note that the length
* includes a trailing \0 byte for each timezone name.
*/
#ifndef TZ_MAX_CHARS
#define TZ_MAX_CHARS 16
#endif
/* Maximum length of buffer to reserve for timezone string */
#define MAXTZLEN (TZ_MAX_CHARS+9+2*(2+6+1+8)+1)
int set_tz (const char *tzstring);
const char *get_tz (char *buffer, size_t buflen);
size_t len_tz (void);
#ifdef __cplusplus
}
#endif
#endif // xtime_h
/** @} */

1
apps/tinydtls Submodule

@ -0,0 +1 @@
Subproject commit e95b02584a0041817da67c8c01f2a197d0c26915

View file

@ -47,6 +47,8 @@
#define IGNORE_CHAR(c) (c == 0x0d) #define IGNORE_CHAR(c) (c == 0x0d)
#define END 0x0a #define END 0x0a
//#define IGNORE_CHAR(c) (c == 0x0a)
//#define END 0x0d
static struct ringbuf rxbuf; static struct ringbuf rxbuf;
static uint8_t rxbuf_data[BUFSIZE]; static uint8_t rxbuf_data[BUFSIZE];

View file

@ -130,7 +130,7 @@ typedef uint16_t settings_length_t;
#define SETTINGS_KEY_RDC_INDEX TCC('R','D') /*!< RDC index, uint8_t */ #define SETTINGS_KEY_RDC_INDEX TCC('R','D') /*!< RDC index, uint8_t */
#define SETTINGS_KEY_CHANNEL_MASK TCC('C','M') /*!< Channel mask, uint16_t */ #define SETTINGS_KEY_CHANNEL_MASK TCC('C','M') /*!< Channel mask, uint16_t */
#define SETTINGS_KEY_MAC_CONF TCC('M','C') /*!< MAC Layer Config, uint8_t */
/*****************************************************************************/ /*****************************************************************************/
// MARK: - Constants // MARK: - Constants

View file

@ -365,6 +365,8 @@ powercycle_turn_radio_on(void)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
volatile uint8_t mcusleepcycle=16;
static void static void
powercycle_wrapper(struct rtimer *t, void *ptr) powercycle_wrapper(struct rtimer *t, void *ptr)
{ {
@ -479,8 +481,8 @@ powercycle(struct rtimer *t, void *ptr)
break; break;
} }
schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); // schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
PT_YIELD(&pt); // PT_YIELD(&pt);
} }
if(radio_is_on) { if(radio_is_on) {
if(!(NETSTACK_RADIO.receiving_packet() || if(!(NETSTACK_RADIO.receiving_packet() ||
@ -500,14 +502,15 @@ powercycle(struct rtimer *t, void *ptr)
ensure an occasional wake cycle or foreground processing will ensure an occasional wake cycle or foreground processing will
be blocked until a packet is detected */ be blocked until a packet is detected */
#if RDC_CONF_MCU_SLEEP #if RDC_CONF_MCU_SLEEP
static uint8_t sleepcycle; static uint8_t sleepcycle;
if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { if((sleepcycle++ < mcusleepcycle) && !we_are_sending && !radio_is_on && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) {
rtimer_arch_sleep(RTIMER_NOW() - cycle_start); rtimer_arch_sleep(cycle_start - RTIMER_NOW());
} else { } else {
sleepcycle = 0; sleepcycle = 0;
#ifndef RDC_CONF_PT_YIELD_OFF
schedule_powercycle_fixed(t, cycle_start); schedule_powercycle_fixed(t, cycle_start);
PT_YIELD(&pt); PT_YIELD(&pt);
#endif
} }
#else #else
schedule_powercycle_fixed(t, cycle_start); schedule_powercycle_fixed(t, cycle_start);
@ -548,11 +551,11 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
rtimer_clock_t t0; rtimer_clock_t t0;
#if WITH_PHASE_OPTIMIZATION #if WITH_PHASE_OPTIMIZATION
rtimer_clock_t encounter_time = 0; rtimer_clock_t encounter_time = 0;
uint8_t is_known_receiver = 0;
#endif #endif
int strobes; int strobes;
uint8_t got_strobe_ack = 0; uint8_t got_strobe_ack = 0;
uint8_t is_broadcast = 0; uint8_t is_broadcast = 0;
uint8_t is_known_receiver = 0;
uint8_t collisions; uint8_t collisions;
int transmit_len; int transmit_len;
int ret; int ret;
@ -712,11 +715,13 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
watchdog_periodic(); watchdog_periodic();
#if WITH_PHASE_OPTIMIZATION
if(!is_broadcast && (is_receiver_awake || is_known_receiver) && if(!is_broadcast && (is_receiver_awake || is_known_receiver) &&
!RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]); PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]);
break; break;
} }
#endif /* WITH_PHASE_OPTIMIZATION */
#if !RDC_CONF_HARDWARE_ACK #if !RDC_CONF_HARDWARE_ACK
len = 0; len = 0;

151
core/sys/log-conf.h Normal file
View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2017, Inria.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Default log levels for a number of modules
* \author
* Simon Duquennoy <simon.duquennoy@inria.fr>
*/
/** \addtogroup sys
* @{ */
/** \addtogroup log
* @{ */
#ifndef __LOG_CONF_H__
#define __LOG_CONF_H__
/* Log only the last 16 bytes of link-layer and IPv6 addresses */
#ifdef LOG_CONF_WITH_COMPACT_ADDR
#define LOG_WITH_COMPACT_ADDR LOG_CONF_WITH_COMPACT_ADDR
#else /* LOG_CONF_WITH_COMPACT_ADDR */
#define LOG_WITH_COMPACT_ADDR 0
#endif /* LOG_CONF_WITH_COMPACT_ADDR */
/* Prefix all logs with file name and line-of-code */
#ifdef LOG_CONF_WITH_LOC
#define LOG_WITH_LOC LOG_CONF_WITH_LOC
#else /* LOG_CONF_WITH_LOC */
#define LOG_WITH_LOC 0
#endif /* LOG_CONF_WITH_LOC */
/* Prefix all logs with Module name and logging level */
#ifdef LOG_CONF_WITH_MODULE_PREFIX
#define LOG_WITH_MODULE_PREFIX LOG_CONF_WITH_MODULE_PREFIX
#else /* LOG_CONF_WITH_MODULE_PREFIX */
#define LOG_WITH_MODULE_PREFIX 1
#endif /* LOG_CONF_WITH_MODULE_PREFIX */
/* Cooja annotations */
#ifdef LOG_CONF_WITH_ANNOTATE
#define LOG_WITH_ANNOTATE LOG_CONF_WITH_ANNOTATE
#else /* LOG_CONF_WITH_ANNOTATE */
#define LOG_WITH_ANNOTATE 0
#endif /* LOG_CONF_WITH_ANNOTATE */
/* Custom output function -- default is printf */
#ifdef LOG_CONF_OUTPUT
#define LOG_OUTPUT(...) LOG_CONF_OUTPUT(__VA_ARGS__)
#else /* LOG_CONF_OUTPUT */
#define LOG_OUTPUT(...) printf(__VA_ARGS__)
#endif /* LOG_CONF_OUTPUT */
/*
* Custom output function to prefix logs with level and module.
*
* This will only be called when LOG_CONF_WITH_MODULE_PREFIX is enabled and
* all implementations should be based on LOG_OUTPUT.
*
* \param level The log level
* \param levelstr The log level as string
* \param module The module string descriptor
*/
#ifdef LOG_CONF_OUTPUT_PREFIX
#define LOG_OUTPUT_PREFIX(level, levelstr, module) LOG_CONF_OUTPUT_PREFIX(level, levelstr, module)
#else /* LOG_CONF_OUTPUT_PREFIX */
#define LOG_OUTPUT_PREFIX(level, levelstr, module) LOG_OUTPUT("[%-4s: %-10s] ", levelstr, module)
#endif /* LOG_CONF_OUTPUT_PREFIX */
/******************************************************************************/
/********************* A list of currently supported modules ******************/
/******************************************************************************/
#ifndef LOG_CONF_LEVEL_RPL
#define LOG_CONF_LEVEL_RPL LOG_LEVEL_NONE /* Only for rpl-lite */
#endif /* LOG_CONF_LEVEL_RPL */
#ifndef LOG_CONF_LEVEL_TCPIP
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_TCPIP */
#ifndef LOG_CONF_LEVEL_IPV6
#define LOG_CONF_LEVEL_IPV6 LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_IPV6 */
#ifndef LOG_CONF_LEVEL_6LOWPAN
#define LOG_CONF_LEVEL_6LOWPAN LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_6LOWPAN */
#ifndef LOG_CONF_LEVEL_NULLNET
#define LOG_CONF_LEVEL_NULLNET LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_NULLNET */
#ifndef LOG_CONF_LEVEL_MAC
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_MAC */
#ifndef LOG_CONF_LEVEL_FRAMER
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_FRAMER */
#ifndef LOG_CONF_LEVEL_6TOP
#define LOG_CONF_LEVEL_6TOP LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_6TOP */
#ifndef LOG_CONF_LEVEL_COAP
#define LOG_CONF_LEVEL_COAP LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_COAP */
#ifndef LOG_CONF_LEVEL_LWM2M
#define LOG_CONF_LEVEL_LWM2M LOG_LEVEL_NONE
#endif /* LOG_CONF_LEVEL_LWM2M */
#ifndef LOG_CONF_LEVEL_MAIN
#define LOG_CONF_LEVEL_MAIN LOG_LEVEL_INFO
#endif /* LOG_CONF_LEVEL_MAIN */
#endif /* __LOG_CONF_H__ */
/** @} */
/** @} */

View file

@ -12,8 +12,9 @@ CONTIKI_CPU=$(CONTIKI)/cpu/avr
### These directories will be searched for the specified source files ### These directories will be searched for the specified source files
### TARGETLIBS are platform-specific routines in the contiki library path ### TARGETLIBS are platform-specific routines in the contiki library path
CONTIKI_CPU_DIRS = . dev CONTIKI_CPU_DIRS = . dev dev/arduino
AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c watchdog.c rtimer-arch.c bootloader.c AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c \
watchdog.c rtimer-arch.c bootloader.c
ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c
TARGETLIBS = random.c leds.c TARGETLIBS = random.c leds.c
@ -88,6 +89,7 @@ CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)
### Compiler definitions ### Compiler definitions
CC = avr-gcc CC = avr-gcc
CXX = avr-g++
LD = avr-gcc LD = avr-gcc
AS = avr-as AS = avr-as
AR = avr-ar AR = avr-ar
@ -129,6 +131,12 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
$(OBJECTDIR)/%.o: %.cpp | $(OBJECTDIR)
$(CXX) $(CFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(CFLAGS) -c $< -o $@
%.ko: %.o %.ko: %.o
$(STRIP) -K _init -K _fini --strip-unneeded -g -x $< -o $@ $(STRIP) -K _init -K _fini --strip-unneeded -g -x $< -o $@
@ -194,22 +202,18 @@ endif
### Upload image ### Upload image
#Let avrdude use defaults if port or programmer not defined #Let avrdude use defaults if port or programmer not defined
AVRDUDE ?= avrdude AVRDUDE ?= avrdude
ifdef AVRDUDE_PORT
AVRDUDE_PORT:=-P $(AVRDUDE_PORT)
endif
ifdef AVRDUDE_PROGRAMMER
AVRDUDE_PROGRAMMER:=-c $(AVRDUDE_PROGRAMMER)
endif
ifdef AVRDUDE_MCU ifdef AVRDUDE_MCU
AVRDUDE_MCU:=-p $(AVRDUDE_MCU) DUDE_MCU:=-p $(AVRDUDE_MCU)
else else
AVRDUDE_MCU:=-p $(MCU) DUDE_MCU:=-p $(MCU)
endif endif
%.u: %.hex %.u: %.hex
$(AVRDUDE) $(AVRDUDE_MCU) $(AVRDUDE_OPTIONS) $(AVRDUDE_PORT) $(AVRDUDE_PROGRAMMER) -U flash:w:$< $(AVRDUDE) $(DUDE_MCU) $(AVRDUDE_OPTIONS) -P $(AVRDUDE_PORT) \
-c $(AVRDUDE_PROGRAMMER) -U flash:w:$<:i
%.eu: %.eep %.eu: %.eep
$(AVRDUDE) $(AVRDUDE_MCU) ${AVRDUDE_OPTIONS} ${AVRDUDE_PORT} ${AVRDUDE_PROGRAMMER} -U eeprom:w:$< $(AVRDUDE) $(DUDE_MCU) ${AVRDUDE_OPTIONS} -P ${AVRDUDE_PORT} \
-c ${AVRDUDE_PROGRAMMER} -U eeprom:w:$<:i
symbols.c: symbols.c:
cp ${CONTIKI}/tools/empty-symbols.c symbols.c cp ${CONTIKI}/tools/empty-symbols.c symbols.c

84
cpu/avr/dev/adc.c Normal file
View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2012, BinaryLabs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: adc.c,v 1.1 2010/08/25 19:34:06 nifi Exp $
*/
/**
* \file
* ADC file for Atmega128rfa1.
* \author
* Paulo Louro <paulolouro@binarylabs.dk>
*/
#include "adc.h"
static uint8_t analog_reference = ADC_DEFAULT;
/*
* For arduino interface for setting external reference voltage
* Note that applying an external voltage *and* then setting the analog
* reference to something internal will short the internal and the
* external reference voltage and most likely destroy the processor.
*/
void analogReference(uint8_t mode)
{
analog_reference = mode;
}
int readADC(uint8_t pin)
{
int result = 0;
adc_setup (analog_reference, pin);
result = adc_read ();
adc_fin ();
return result;
}
/**
* \return Internal temperature in 0.01C, e.g. 25C is 2500
*/
int readInternalTemp(void)
{
int reading = 0;
ADCSRB |= _BV(MUX5);
ADMUX = _BV(REFS1) | _BV(REFS0) | 0b1001 ;
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS2) ;
ADCSRA |= 1 << ADSC;
loop_until_bit_is_clear(ADCSRA,ADSC);
reading = ADC;
ADCSRB=0; //disable ADC, need to write B first for MUX5 bit
ADCSRA=0; //disable ADC
ADMUX=0; //turn off internal vref
return reading * 113 - 27280;
}

65
cpu/avr/dev/adc.h Normal file
View file

@ -0,0 +1,65 @@
#ifndef __ADC_ARCH_H__
#define __ADC_ARCH_H__
#include <avr/io.h>
/*
* Reference voltage
* The default is 1.6V reference voltage
* The selected reference voltage is the maximum voltage that can be
* measured.
* Directly provide shifted variants so we don't need to shift.
*/
#define ADC_1_5 (2<<6)
#define ADC_1_6 (3<<6)
#define ADC_1_8 (1<<6)
#define ADC_EXTERNAL (0<<6)
#define ADC_DEFAULT ADC_1_6
/* sometimes it's desirable to decouple setup / finish from sampling */
static inline void adc_setup (uint8_t ref_volt, uint8_t pin)
{
ADMUX = ref_volt | (pin & 0x7);
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS2);
}
static inline int adc_read (void)
{
ADCSRA |= (1 << ADSC);
loop_until_bit_is_clear (ADCSRA, ADSC);
return ADC;
}
static inline void adc_fin (void)
{
ADCSRA = 0;
ADMUX = 0;
}
static inline void adc_init (void)
{
uint8_t temp;
ADCSRC = 0;
ADCSRB = 0;
adc_fin ();
/*
* Disable JTAG interface
* Hardware manual about JTD bit:
* "In order to avoid unintentional disabling or enabling of the
* JTAG interface, a timed sequence must be followed when changing
* this bit: The application software must write this bit to the
* desired value twice within four cycles to change its value."
* 15.4.1 "MCUCR - MCU Control Register", p. 219
*/
temp = MCUCR | (1 << JTD);
MCUCR = temp;
MCUCR = temp;
}
int readADC(uint8_t pin);
long readVcc();
int readInternalTemp(void);
void analogReference(uint8_t mode);
#endif /* __ADC_ARCH_H__ */

View file

@ -0,0 +1,174 @@
#ifndef Arduino_h
#define Arduino_h
#include <hw-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
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
#define true 0x1
#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
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#define DEFAULT ADC_DEFAULT
#define EXTERNAL ADC_EXTERNAL
// undefine stdlib's abs if encountered
#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 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))
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define microsecondsToClockCycles(a) ( (a) * (F_CPU / 1000000L) )
typedef unsigned int word;
#define bit(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
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);
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
// 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.
#define analogInPinToBit(P) (P)
// On the ATmega1280, the addresses of some 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 uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_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 analogInPinToBit(P) (P)
#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 NOT_A_PIN 0
#define NOT_A_PORT 0
#ifdef ARDUINO_MAIN
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 10
#define PK 11
#define PL 12
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
// look at this again when considering implementing serial
#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__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
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
#include "pins_arduino.h"
#include "dev/arduino/arduino-compat.h"
#endif

View file

@ -0,0 +1,146 @@
/*
EEPROM.h - EEPROM library
Original Copyright (c) 2006 David A. Mellis. All right reserved.
New version by Christopher Andrews 2015.
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 EEPROM_h
#define EEPROM_h
#include <inttypes.h>
#include <avr/eeprom.h>
#include <avr/io.h>
/***
EERef class.
This object references an EEPROM cell.
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
***/
struct EERef{
EERef( const int index )
: index( index ) {}
//Access/read members.
uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); }
operator const uint8_t() const { return **this; }
//Assignment/write members.
EERef &operator=( const EERef &ref ) { return *this = *ref; }
EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; }
EERef &operator +=( uint8_t in ) { return *this = **this + in; }
EERef &operator -=( uint8_t in ) { return *this = **this - in; }
EERef &operator *=( uint8_t in ) { return *this = **this * in; }
EERef &operator /=( uint8_t in ) { return *this = **this / in; }
EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
EERef &operator %=( uint8_t in ) { return *this = **this % in; }
EERef &operator &=( uint8_t in ) { return *this = **this & in; }
EERef &operator |=( uint8_t in ) { return *this = **this | in; }
EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
/** Prefix increment/decrement **/
EERef& operator++() { return *this += 1; }
EERef& operator--() { return *this -= 1; }
/** Postfix increment/decrement **/
uint8_t operator++ (int){
uint8_t ret = **this;
return ++(*this), ret;
}
uint8_t operator-- (int){
uint8_t ret = **this;
return --(*this), ret;
}
int index; //Index of current EEPROM cell.
};
/***
EEPtr class.
This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
Just like a normal pointer type, this can be dereferenced and repositioned using
increment/decrement operators.
***/
struct EEPtr{
EEPtr( const int index )
: index( index ) {}
operator const int() const { return index; }
EEPtr &operator=( int in ) { return index = in, *this; }
//Iterator functionality.
bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
EERef operator*() { return index; }
/** Prefix & Postfix increment/decrement **/
EEPtr& operator++() { return ++index, *this; }
EEPtr& operator--() { return --index, *this; }
EEPtr operator++ (int) { return index++; }
EEPtr operator-- (int) { return index--; }
int index; //Index of current EEPROM cell.
};
/***
EEPROMClass class.
This object represents the entire EEPROM space.
It wraps the functionality of EEPtr and EERef into a basic interface.
This class is also 100% backwards compatible with earlier Arduino core releases.
***/
struct EEPROMClass{
//Basic user access methods.
EERef operator[]( const int idx ) { return idx; }
uint8_t read( int idx ) { return EERef( idx ); }
void write( int idx, uint8_t val ) { (EERef( idx )) = val; }
void update( int idx, uint8_t val ) { EERef( idx ).update( val ); }
//STL and C++11 iteration capability.
EEPtr begin() { return 0x00; }
EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
uint16_t length() { return E2END + 1; }
//Functionality to 'get' and 'put' objects to and from EEPROM.
template< typename T > T &get( int idx, T &t ){
EEPtr e = idx;
uint8_t *ptr = (uint8_t*) &t;
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e;
return t;
}
template< typename T > const T &put( int idx, const T &t ){
EEPtr e = idx;
const uint8_t *ptr = (const uint8_t*) &t;
for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ );
return t;
}
};
static EEPROMClass EEPROM;
#endif

View file

@ -0,0 +1,250 @@
/*
HardwareSerial.cpp - 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 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
#include "HardwareSerial.h"
#include "HardwareSerial_private.h"
// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
// but we can refer to it weakly so we don't pull in the entire
// HardwareSerial instance if the user doesn't also refer to it.
#if defined(HAVE_HWSERIAL0)
void serialEvent() __attribute__((weak));
bool Serial0_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL1)
void serialEvent1() __attribute__((weak));
bool Serial1_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL2)
void serialEvent2() __attribute__((weak));
bool Serial2_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL3)
void serialEvent3() __attribute__((weak));
bool Serial3_available() __attribute__((weak));
#endif
void serialEventRun(void)
{
#if defined(HAVE_HWSERIAL0)
if (Serial0_available && serialEvent && Serial0_available()) serialEvent();
#endif
#if defined(HAVE_HWSERIAL1)
if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
#endif
#if defined(HAVE_HWSERIAL2)
if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
#endif
#if defined(HAVE_HWSERIAL3)
if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3();
#endif
}
// Actual interrupt handlers //////////////////////////////////////////////////////////////
void HardwareSerial::_tx_udr_empty_irq(void)
{
// If interrupts are enabled, there must be more data in the output
// buffer. Send the next byte
unsigned char c = _tx_buffer[_tx_buffer_tail];
_tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
*_udr = c;
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
sbi(*_ucsra, TXC0);
if (_tx_buffer_head == _tx_buffer_tail) {
// Buffer empty, so disable interrupts
cbi(*_ucsrb, UDRIE0);
}
}
// Public Methods //////////////////////////////////////////////////////////////
void HardwareSerial::begin(unsigned long baud, byte config)
{
// Try u2x mode first
uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
*_ucsra = 1 << U2X0;
// hardcoded exception for 57600 for compatibility with the bootloader
// shipped with the Duemilanove and previous boards and the firmware
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
// be > 4095, so switch back to non-u2x mode if the baud rate is too
// low.
if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
{
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
_written = false;
//set the data bits, parity, and stop bits
#if defined(__AVR_ATmega8__)
config |= 0x80; // select UCSRC register (shared with UBRRH)
#endif
*_ucsrc = config;
sbi(*_ucsrb, RXEN0);
sbi(*_ucsrb, TXEN0);
sbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
}
void HardwareSerial::end()
{
// wait for transmission of outgoing data
flush();
cbi(*_ucsrb, RXEN0);
cbi(*_ucsrb, TXEN0);
cbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
// clear any received data
_rx_buffer_head = _rx_buffer_tail;
}
int HardwareSerial::available(void)
{
return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
}
int HardwareSerial::peek(void)
{
if (_rx_buffer_head == _rx_buffer_tail) {
return -1;
} else {
return _rx_buffer[_rx_buffer_tail];
}
}
int HardwareSerial::read(void)
{
// if the head isn't ahead of the tail, we don't have any characters
if (_rx_buffer_head == _rx_buffer_tail) {
return -1;
} else {
unsigned char c = _rx_buffer[_rx_buffer_tail];
_rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
return c;
}
}
int HardwareSerial::availableForWrite(void)
{
#if (SERIAL_TX_BUFFER_SIZE>256)
uint8_t oldSREG = SREG;
cli();
#endif
tx_buffer_index_t head = _tx_buffer_head;
tx_buffer_index_t tail = _tx_buffer_tail;
#if (SERIAL_TX_BUFFER_SIZE>256)
SREG = oldSREG;
#endif
if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
return tail - head - 1;
}
void HardwareSerial::flush()
{
// If we have never written a byte, no need to flush. This special
// case is needed since there is no way to force the TXC (transmit
// complete) bit to 1 during initialization
if (!_written)
return;
while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
// Interrupts are globally disabled, but the DR empty
// interrupt should be enabled, so poll the DR empty flag to
// prevent deadlock
if (bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
}
// If we get here, nothing is queued anymore (DRIE is disabled) and
// the hardware finished tranmission (TXC is set).
}
size_t HardwareSerial::write(uint8_t c)
{
_written = true;
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
*_udr = c;
sbi(*_ucsra, TXC0);
return 1;
}
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
while (i == _tx_buffer_tail) {
if (bit_is_clear(SREG, SREG_I)) {
// Interrupts are disabled, so we'll have to poll the data
// register empty flag ourselves. If it is set, pretend an
// interrupt has happened and call the handler to free up
// space for us.
if(bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
} else {
// nop, the interrupt handler will free up space for us
}
}
_tx_buffer[_tx_buffer_head] = c;
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
return 1;
}
#endif // whole file

View file

@ -0,0 +1,161 @@
/*
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
Modified 3 December 2013 by Matthijs Kooijman
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "Stream.h"
// 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.
// NOTE: a "power of 2" buffer size is reccomended to dramatically
// optimize all the modulo operations for ring buffers.
// WARNING: When buffer sizes are increased to > 256, the buffer index
// variables are automatically increased in size, but the extra
// atomicity guards needed for that are not implemented. This will
// often work, but occasionally a race condition can occur that makes
// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405
#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#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
// Define config for Serial.begin(baud, config);
#define SERIAL_5N1 0x00
#define SERIAL_6N1 0x02
#define SERIAL_7N1 0x04
#define SERIAL_8N1 0x06
#define SERIAL_5N2 0x08
#define SERIAL_6N2 0x0A
#define SERIAL_7N2 0x0C
#define SERIAL_8N2 0x0E
#define SERIAL_5E1 0x20
#define SERIAL_6E1 0x22
#define SERIAL_7E1 0x24
#define SERIAL_8E1 0x26
#define SERIAL_5E2 0x28
#define SERIAL_6E2 0x2A
#define SERIAL_7E2 0x2C
#define SERIAL_8E2 0x2E
#define SERIAL_5O1 0x30
#define SERIAL_6O1 0x32
#define SERIAL_7O1 0x34
#define SERIAL_8O1 0x36
#define SERIAL_5O2 0x38
#define SERIAL_6O2 0x3A
#define SERIAL_7O2 0x3C
#define SERIAL_8O2 0x3E
class HardwareSerial : public Stream
{
protected:
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];
public:
inline HardwareSerial(
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *ucsrc, volatile uint8_t *udr);
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint8_t);
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; // pull in write(str) and write(buf, size) from Print
operator bool() { return true; }
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);
void _tx_udr_empty_irq(void);
};
#if defined(UBRRH) || defined(UBRR0H)
extern HardwareSerial Serial;
#define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
extern HardwareSerial Serial1;
#define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
extern HardwareSerial Serial2;
#define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
extern HardwareSerial Serial3;
#define HAVE_HWSERIAL3
#endif
extern void serialEventRun(void) __attribute__((weak));
#endif

View file

@ -0,0 +1,79 @@
/*
HardwareSerial0.cpp - 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 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman
*/
#include "Arduino.h"
#include "HardwareSerial.h"
#include "HardwareSerial_private.h"
// Each HardwareSerial is defined in its own file, sine the linker pulls
// in the entire file when any element inside is used. --gc-sections can
// additionally cause unused symbols to be dropped, but ISRs have the
// "used" attribute so are never dropped and they keep the
// HardwareSerial instance in as well. Putting each instance in its own
// file prevents the linker from pulling in any unused instances in the
// first place.
#if defined(HAVE_HWSERIAL0)
#if defined(USART_RX_vect)
ISR(USART_RX_vect)
#elif defined(USART0_RX_vect)
ISR(USART0_RX_vect)
#elif defined(USART_RXC_vect)
ISR(USART_RXC_vect) // ATmega8
#else
#error "Don't know what the Data Received vector is called for Serial"
#endif
{
Serial._rx_complete_irq();
}
#if defined(UART0_UDRE_vect)
ISR(UART0_UDRE_vect)
#elif defined(UART_UDRE_vect)
ISR(UART_UDRE_vect)
#elif defined(USART0_UDRE_vect)
ISR(USART0_UDRE_vect)
#elif defined(USART_UDRE_vect)
ISR(USART_UDRE_vect)
#else
#error "Don't know what the Data Register Empty vector is called for Serial"
#endif
{
Serial._tx_udr_empty_irq();
}
#if defined(UBRRH) && defined(UBRRL)
HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
#else
HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
#endif
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
bool Serial0_available() {
return Serial.available();
}
#endif // HAVE_HWSERIAL0

View file

@ -0,0 +1,69 @@
/*
HardwareSerial1.cpp - 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 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman
*/
#include "Arduino.h"
#include "HardwareSerial.h"
#include "HardwareSerial_private.h"
// Each HardwareSerial is defined in its own file, sine the linker pulls
// in the entire file when any element inside is used. --gc-sections can
// additionally cause unused symbols to be dropped, but ISRs have the
// "used" attribute so are never dropped and they keep the
// HardwareSerial instance in as well. Putting each instance in its own
// file prevents the linker from pulling in any unused instances in the
// first place.
#if defined(HAVE_HWSERIAL1)
#if defined(UART1_RX_vect)
ISR(UART1_RX_vect)
#elif defined(USART1_RX_vect)
ISR(USART1_RX_vect)
#else
#error "Don't know what the Data Register Empty vector is called for Serial1"
#endif
{
Serial1._rx_complete_irq();
}
#if defined(UART1_UDRE_vect)
ISR(UART1_UDRE_vect)
#elif defined(USART1_UDRE_vect)
ISR(USART1_UDRE_vect)
#else
#error "Don't know what the Data Register Empty vector is called for Serial1"
#endif
{
Serial1._tx_udr_empty_irq();
}
HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1);
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
bool Serial1_available() {
return Serial1.available();
}
#endif // HAVE_HWSERIAL1

View file

@ -0,0 +1,123 @@
/*
HardwareSerial_private.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 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/
#include "wiring_private.h"
// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
// Ensure that the various bit positions we use are available with a 0
// postfix, so we can always use the values for UART0 for all UARTs. The
// alternative, passing the various values for each UART to the
// HardwareSerial constructor also works, but makes the code bigger and
// slower.
#if !defined(TXC0)
#if defined(TXC)
// Some chips like ATmega8 don't have UPE, only PE. The other bits are
// named as expected.
#if !defined(UPE) && defined(PE)
#define UPE PE
#endif
// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc.
#define TXC0 TXC
#define RXEN0 RXEN
#define TXEN0 TXEN
#define RXCIE0 RXCIE
#define UDRIE0 UDRIE
#define U2X0 U2X
#define UPE0 UPE
#define UDRE0 UDRE
#elif defined(TXC1)
// Some devices have uart1 but no uart0
#define TXC0 TXC1
#define RXEN0 RXEN1
#define TXEN0 TXEN1
#define RXCIE0 RXCIE1
#define UDRIE0 UDRIE1
#define U2X0 U2X1
#define UPE0 UPE1
#define UDRE0 UDRE1
#else
#error No UART found in HardwareSerial.cpp
#endif
#endif // !defined TXC0
// Check at compiletime that it is really ok to use the bit positions of
// UART0 for the other UARTs as well, in case these values ever get
// changed for future hardware.
#if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \
UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \
UDRE1 != UDRE0)
#error "Not all bit positions for UART1 are the same as for UART0"
#endif
#if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \
UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \
UDRE2 != UDRE0)
#error "Not all bit positions for UART2 are the same as for UART0"
#endif
#if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \
UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \
UDRE3 != UDRE0)
#error "Not all bit positions for UART3 are the same as for UART0"
#endif
// Constructors ////////////////////////////////////////////////////////////////
HardwareSerial::HardwareSerial(
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *ucsrc, volatile uint8_t *udr) :
_ubrrh(ubrrh), _ubrrl(ubrrl),
_ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc),
_udr(udr),
_rx_buffer_head(0), _rx_buffer_tail(0),
_tx_buffer_head(0), _tx_buffer_tail(0)
{
}
// Actual interrupt handlers //////////////////////////////////////////////////////////////
void HardwareSerial::_rx_complete_irq(void)
{
if (bit_is_clear(*_ucsra, UPE0)) {
// No Parity error, read byte and store it in the buffer if there is
// room
unsigned char c = *_udr;
rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != _rx_buffer_tail) {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
} else {
// Parity error, read byte but discard it
*_udr;
};
}
#endif // whole file

View file

@ -0,0 +1,265 @@
/*
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
Modified 03 August 2015 by Chuck Todd
*/
#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--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
if (write(c)) n++;
else break;
}
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)
{
return write("\r\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;
}

View file

@ -0,0 +1,84 @@
/*
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) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
size_t write(const char *str) {
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
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 <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

201
cpu/avr/dev/arduino/SPI.cpp Normal file
View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "SPI.h"
SPIClass SPI;
uint8_t SPIClass::initialized = 0;
uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif
void SPIClass::begin()
{
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
if (!initialized) {
// Set SS to high so a connected chip will be "deselected" by default
uint8_t port = digitalPinToPort(SS);
uint8_t bit = digitalPinToBitMask(SS);
volatile uint8_t *reg = portModeRegister(port);
// if the SS pin is not already configured as an output
// then set it high (to enable the internal pull-up resistor)
if(!(*reg & bit)){
digitalWrite(SS, HIGH);
}
// When the SS pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
pinMode(SS, OUTPUT);
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
// automatically switches to Slave, so the data direction of
// the SS pin MUST be kept as OUTPUT.
SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);
// Set direction register for SCK and MOSI pin.
// MISO pin automatically overrides to INPUT.
// By doing this AFTER enabling SPI, we avoid accidentally
// clocking in a single bit since the lines go directly
// from "input" to SPI control.
// http://code.google.com/p/arduino/issues/detail?id=888
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
}
initialized++; // reference count
SREG = sreg;
}
void SPIClass::end() {
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
// Decrease the reference counter
if (initialized)
initialized--;
// If there are no more references disable SPI
if (!initialized) {
SPCR &= ~_BV(SPE);
interruptMode = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
inTransactionFlag = 0;
#endif
}
SREG = sreg;
}
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
#if defined(__AVR_ATmega32U4__)
#define SPI_INT0_MASK (1<<INT0)
#define SPI_INT1_MASK (1<<INT1)
#define SPI_INT2_MASK (1<<INT2)
#define SPI_INT3_MASK (1<<INT3)
#define SPI_INT4_MASK (1<<INT6)
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define SPI_INT0_MASK (1<<INT0)
#define SPI_INT1_MASK (1<<INT1)
#define SPI_INT2_MASK (1<<INT2)
#define SPI_INT3_MASK (1<<INT3)
#define SPI_INT4_MASK (1<<INT4)
#define SPI_INT5_MASK (1<<INT5)
#define SPI_INT6_MASK (1<<INT6)
#define SPI_INT7_MASK (1<<INT7)
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
#define SPI_INT0_MASK (1<<INT4)
#define SPI_INT1_MASK (1<<INT5)
#define SPI_INT2_MASK (1<<INT0)
#define SPI_INT3_MASK (1<<INT1)
#define SPI_INT4_MASK (1<<INT2)
#define SPI_INT5_MASK (1<<INT3)
#define SPI_INT6_MASK (1<<INT6)
#define SPI_INT7_MASK (1<<INT7)
#else
#ifdef INT0
#define SPI_INT0_MASK (1<<INT0)
#endif
#ifdef INT1
#define SPI_INT1_MASK (1<<INT1)
#endif
#ifdef INT2
#define SPI_INT2_MASK (1<<INT2)
#endif
#endif
void SPIClass::usingInterrupt(uint8_t interruptNumber)
{
uint8_t mask = 0;
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
switch (interruptNumber) {
#ifdef SPI_INT0_MASK
case 0: mask = SPI_INT0_MASK; break;
#endif
#ifdef SPI_INT1_MASK
case 1: mask = SPI_INT1_MASK; break;
#endif
#ifdef SPI_INT2_MASK
case 2: mask = SPI_INT2_MASK; break;
#endif
#ifdef SPI_INT3_MASK
case 3: mask = SPI_INT3_MASK; break;
#endif
#ifdef SPI_INT4_MASK
case 4: mask = SPI_INT4_MASK; break;
#endif
#ifdef SPI_INT5_MASK
case 5: mask = SPI_INT5_MASK; break;
#endif
#ifdef SPI_INT6_MASK
case 6: mask = SPI_INT6_MASK; break;
#endif
#ifdef SPI_INT7_MASK
case 7: mask = SPI_INT7_MASK; break;
#endif
default:
interruptMode = 2;
break;
}
interruptMask |= mask;
if (!interruptMode)
interruptMode = 1;
SREG = sreg;
}
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
{
// Once in mode 2 we can't go back to 0 without a proper reference count
if (interruptMode == 2)
return;
uint8_t mask = 0;
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
switch (interruptNumber) {
#ifdef SPI_INT0_MASK
case 0: mask = SPI_INT0_MASK; break;
#endif
#ifdef SPI_INT1_MASK
case 1: mask = SPI_INT1_MASK; break;
#endif
#ifdef SPI_INT2_MASK
case 2: mask = SPI_INT2_MASK; break;
#endif
#ifdef SPI_INT3_MASK
case 3: mask = SPI_INT3_MASK; break;
#endif
#ifdef SPI_INT4_MASK
case 4: mask = SPI_INT4_MASK; break;
#endif
#ifdef SPI_INT5_MASK
case 5: mask = SPI_INT5_MASK; break;
#endif
#ifdef SPI_INT6_MASK
case 6: mask = SPI_INT6_MASK; break;
#endif
#ifdef SPI_INT7_MASK
case 7: mask = SPI_INT7_MASK; break;
#endif
default:
break;
// this case can't be reached
}
interruptMask &= ~mask;
if (!interruptMask)
interruptMode = 0;
SREG = sreg;
}

324
cpu/avr/dev/arduino/SPI.h Normal file
View file

@ -0,0 +1,324 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include <Arduino.h>
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1
// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
#define SPI_HAS_NOTUSINGINTERRUPT 1
// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
// This way when there is a bug fix you can check this define to alert users
// of your code if it uses better version of this library.
// This also implies everything that SPI_HAS_TRANSACTION as documented above is
// available too.
#define SPI_ATOMIC_VERSION 1
// Uncomment this line to add detection of mismatched begin/end transactions.
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn
// on if any mismatch is ever detected.
//#define SPI_TRANSACTION_MISMATCH_LED 5
#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
#if defined(EIMSK)
#define SPI_AVR_EIMSK EIMSK
#elif defined(GICR)
#define SPI_AVR_EIMSK GICR
#elif defined(GIMSK)
#define SPI_AVR_EIMSK GIMSK
#endif
class SPISettings {
public:
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings() {
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
}
private:
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
__attribute__((__always_inline__)) {
// Clock settings are defined as follows. Note that this shows SPI2X
// inverted, so the bits form increasing numbers. Also note that
// fosc/64 appears twice
// SPR1 SPR0 ~SPI2X Freq
// 0 0 0 fosc/2
// 0 0 1 fosc/4
// 0 1 0 fosc/8
// 0 1 1 fosc/16
// 1 0 0 fosc/32
// 1 0 1 fosc/64
// 1 1 0 fosc/64
// 1 1 1 fosc/128
// We find the fastest clock that is less than or equal to the
// given clock rate. The clock divider that results in clock_setting
// is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
// slowest (128 == 2 ^^ 7, so clock_div = 6).
uint8_t clockDiv;
// When the clock is known at compiletime, use this if-then-else
// cascade, which the compiler knows how to completely optimize
// away. When clock is not known, use a loop instead, which generates
// shorter code.
if (__builtin_constant_p(clock)) {
if (clock >= F_CPU / 2) {
clockDiv = 0;
} else if (clock >= F_CPU / 4) {
clockDiv = 1;
} else if (clock >= F_CPU / 8) {
clockDiv = 2;
} else if (clock >= F_CPU / 16) {
clockDiv = 3;
} else if (clock >= F_CPU / 32) {
clockDiv = 4;
} else if (clock >= F_CPU / 64) {
clockDiv = 5;
} else {
clockDiv = 6;
}
} else {
uint32_t clockSetting = F_CPU / 2;
clockDiv = 0;
while (clockDiv < 6 && clock < clockSetting) {
clockSetting /= 2;
clockDiv++;
}
}
// Compensate for the duplicate fosc/64
if (clockDiv == 6)
clockDiv = 7;
// Invert the SPI2X bit
clockDiv ^= 0x1;
// Pack into the SPISettings class
spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
(dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
spsr = clockDiv & SPI_2XCLOCK_MASK;
}
uint8_t spcr;
uint8_t spsr;
friend class SPIClass;
};
class SPIClass {
public:
// Initialize the SPI library
static void begin();
// If SPI is used from within an interrupt, this function registers
// that interrupt with the SPI library, so beginTransaction() can
// prevent conflicts. The input interruptNumber is the number used
// with attachInterrupt. If SPI is used from a different interrupt
// (eg, a timer), interruptNumber should be 255.
static void usingInterrupt(uint8_t interruptNumber);
// And this does the opposite.
static void notUsingInterrupt(uint8_t interruptNumber);
// Note: the usingInterrupt and notUsingInterrupt functions should
// not to be called from ISR context or inside a transaction.
// For details see:
// https://github.com/arduino/Arduino/pull/2381
// https://github.com/arduino/Arduino/pull/2449
// Before using SPI.transfer() or asserting chip select pins,
// this function is used to gain exclusive access to the SPI bus
// and configure the correct settings.
inline static void beginTransaction(SPISettings settings) {
if (interruptMode > 0) {
uint8_t sreg = SREG;
noInterrupts();
#ifdef SPI_AVR_EIMSK
if (interruptMode == 1) {
interruptSave = SPI_AVR_EIMSK;
SPI_AVR_EIMSK &= ~interruptMask;
SREG = sreg;
} else
#endif
{
interruptSave = sreg;
}
}
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 1;
#endif
SPCR = settings.spcr;
SPSR = settings.spsr;
}
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
inline static uint8_t transfer(uint8_t data) {
SPDR = data;
/*
* The following NOP introduces a small delay that can prevent the wait
* loop form iterating when running at the maximum speed. This gives
* about 10% more speed, even if it seems counter-intuitive. At lower
* speeds it is unnoticed.
*/
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ; // wait
return SPDR;
}
inline static uint16_t transfer16(uint16_t data) {
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
if (!(SPCR & _BV(DORD))) {
SPDR = in.msb;
asm volatile("nop"); // See transfer(uint8_t) function
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
SPDR = in.lsb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
} else {
SPDR = in.lsb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
SPDR = in.msb;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
}
return out.val;
}
inline static void transfer(void *buf, size_t count) {
if (count == 0) return;
uint8_t *p = (uint8_t *)buf;
SPDR = *p;
while (--count > 0) {
uint8_t out = *(p + 1);
while (!(SPSR & _BV(SPIF))) ;
uint8_t in = SPDR;
SPDR = out;
*p++ = in;
}
while (!(SPSR & _BV(SPIF))) ;
*p = SPDR;
}
// After performing a group of transfers and releasing the chip select
// signal, this function allows others to access the SPI bus
inline static void endTransaction(void) {
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (!inTransactionFlag) {
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
}
inTransactionFlag = 0;
#endif
if (interruptMode > 0) {
#ifdef SPI_AVR_EIMSK
uint8_t sreg = SREG;
#endif
noInterrupts();
#ifdef SPI_AVR_EIMSK
if (interruptMode == 1) {
SPI_AVR_EIMSK = interruptSave;
SREG = sreg;
} else
#endif
{
SREG = interruptSave;
}
}
}
// Disable the SPI bus
static void end();
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setBitOrder(uint8_t bitOrder) {
if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
else SPCR &= ~(_BV(DORD));
}
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setDataMode(uint8_t dataMode) {
SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
}
// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setClockDivider(uint8_t clockDiv) {
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
}
// These undocumented functions should not be used. SPI.transfer()
// polls the hardware flag which is automatically cleared as the
// AVR responds to SPI's interrupt
inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
private:
static uint8_t initialized;
static uint8_t interruptMode; // 0=none, 1=mask, 2=global
static uint8_t interruptMask; // which interrupts to mask
static uint8_t interruptSave; // temp storage, to restore state
#ifdef SPI_TRANSACTION_MISMATCH_LED
static uint8_t inTransactionFlag;
#endif
};
extern SPIClass SPI;
#endif

View file

@ -0,0 +1,319 @@
/*
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
findMulti/findUntil routines written by Jim Leonard/Xuth
*/
#include "Arduino.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
// 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(LookaheadMode lookahead, bool detectDecimal)
{
int c;
while (1) {
c = timedPeek();
if( c < 0 ||
c == '-' ||
(c >= '0' && c <= '9') ||
(detectDecimal && c == '.')) return c;
switch( lookahead ){
case SKIP_NONE: return -1; // Fail code.
case SKIP_WHITESPACE:
switch( c ){
case ' ':
case '\t':
case '\r':
case '\n': break;
default: return -1; // Fail code.
}
case SKIP_ALL:
break;
}
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, strlen(target), NULL, 0);
}
// 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)
{
if (terminator == NULL) {
MultiTarget t[1] = {{target, targetLen, 0}};
return findMulti(t, 1) == 0 ? true : false;
} else {
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
return findMulti(t, 2) == 0 ? true : false;
}
}
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == ignore)
; // ignore this character
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 == ignore );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
bool isFraction = false;
long value = 0;
int c;
float fraction = 1.0;
c = peekNextDigit(lookahead, true);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == ignore)
; // 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 == '.' && !isFraction) || c == ignore );
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,129 @@
/*
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(ignore) parseInt(ignore)
#define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
// This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input.
enum LookaheadMode{
SKIP_ALL, // All invalid characters are ignored.
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
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(LookaheadMode lookahead, bool detectDecimal); // 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
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(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// 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 ignore) { return parseInt(SKIP_ALL, ignore); }
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
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);
};
#undef NO_IGNORE_CHAR
#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,58 @@
/* -*- 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
*/
extern "C" {
#include "stdlib.h"
}
void randomSeed(unsigned long 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,745 @@
/*
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;
}
#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 (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,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);
#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; }
// 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,330 @@
/*
TwoWire.cpp - TWI/I2C library for Wiring & Arduino
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 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "twi.h"
}
#include "Wire.h"
// Initialize Class Variables //////////////////////////////////////////////////
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;
uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
uint8_t TwoWire::txBufferIndex = 0;
uint8_t TwoWire::txBufferLength = 0;
uint8_t TwoWire::transmitting = 0;
void (*TwoWire::user_onRequest)(void);
void (*TwoWire::user_onReceive)(int);
// Constructors ////////////////////////////////////////////////////////////////
TwoWire::TwoWire()
{
}
// Public Methods //////////////////////////////////////////////////////////////
void TwoWire::begin(void)
{
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
twi_init();
}
void TwoWire::begin(uint8_t address)
{
twi_setAddress(address);
twi_attachSlaveTxEvent(onRequestService);
twi_attachSlaveRxEvent(onReceiveService);
begin();
}
void TwoWire::begin(int address)
{
begin((uint8_t)address);
}
void TwoWire::end(void)
{
twi_disable();
}
void TwoWire::setClock(uint32_t frequency)
{
TWBR = ((F_CPU / frequency) - 16) / 2;
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop)
{
if (isize > 0) {
// send internal address; this mode allows sending a repeated start to access
// some devices' internal registers. This function is executed by the hardware
// TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers)
beginTransmission(address);
// the maximum size of internal address is 3 bytes
if (isize > 3){
isize = 3;
}
// write internal register address - most significant byte first
while (isize-- > 0)
write((uint8_t)(iaddress >> (isize*8)));
endTransmission(false);
}
// clamp to buffer length
if(quantity > BUFFER_LENGTH){
quantity = BUFFER_LENGTH;
}
// perform blocking read into buffer
uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;
return read;
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop);
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
}
void TwoWire::beginTransmission(uint8_t address)
{
// indicate that we are transmitting
transmitting = 1;
// set address of targeted slave
txAddress = address;
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
}
void TwoWire::beginTransmission(int address)
{
beginTransmission((uint8_t)address);
}
//
// Originally, 'endTransmission' was an f(void) function.
// It has been modified to take one parameter indicating
// whether or not a STOP should be performed on the bus.
// Calling endTransmission(false) allows a sketch to
// perform a repeated start.
//
// WARNING: Nothing in the library keeps track of whether
// the bus tenure has been properly ended with a STOP. It
// is very possible to leave the bus in a hung state if
// no call to endTransmission(true) is made. Some I2C
// devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
// transmit buffer (blocking)
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
// indicate that we are done transmitting
transmitting = 0;
return ret;
}
// This provides backwards compatibility with the original
// definition, and expected behaviour, of endTransmission
//
uint8_t TwoWire::endTransmission(void)
{
return endTransmission(true);
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
size_t TwoWire::write(uint8_t data)
{
if(transmitting){
// in master transmitter mode
// don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH){
setWriteError();
return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;
}else{
// in slave send mode
// reply to master
twi_transmit(&data, 1);
}
return 1;
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
if(transmitting){
// in master transmitter mode
for(size_t i = 0; i < quantity; ++i){
write(data[i]);
}
}else{
// in slave send mode
// reply to master
twi_transmit(data, quantity);
}
return quantity;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::available(void)
{
return rxBufferLength - rxBufferIndex;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::read(void)
{
int value = -1;
// get each successive byte on each call
if(rxBufferIndex < rxBufferLength){
value = rxBuffer[rxBufferIndex];
++rxBufferIndex;
}
return value;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::peek(void)
{
int value = -1;
if(rxBufferIndex < rxBufferLength){
value = rxBuffer[rxBufferIndex];
}
return value;
}
void TwoWire::flush(void)
{
// XXX: to be implemented.
}
// behind the scenes function that is called when data is received
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
{
// don't bother if user hasn't registered a callback
if(!user_onReceive){
return;
}
// don't bother if rx buffer is in use by a master requestFrom() op
// i know this drops data, but it allows for slight stupidity
// meaning, they may not have read all the master requestFrom() data yet
if(rxBufferIndex < rxBufferLength){
return;
}
// copy twi rx buffer into local read buffer
// this enables new reads to happen in parallel
for(uint8_t i = 0; i < numBytes; ++i){
rxBuffer[i] = inBytes[i];
}
// set rx iterator vars
rxBufferIndex = 0;
rxBufferLength = numBytes;
// alert user program
user_onReceive(numBytes);
}
// behind the scenes function that is called when data is requested
void TwoWire::onRequestService(void)
{
// don't bother if user hasn't registered a callback
if(!user_onRequest){
return;
}
// reset tx buffer iterator vars
// !!! this will kill any pending pre-master sendTo() activity
txBufferIndex = 0;
txBufferLength = 0;
// alert user program
user_onRequest();
}
// sets function called on slave write
void TwoWire::onReceive( void (*function)(int) )
{
user_onReceive = function;
}
// sets function called on slave read
void TwoWire::onRequest( void (*function)(void) )
{
user_onRequest = function;
}
// Preinstantiate Objects //////////////////////////////////////////////////////
TwoWire Wire = TwoWire();

View file

@ -0,0 +1,85 @@
/*
TwoWire.h - TWI/I2C library for Arduino & 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 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#ifndef TwoWire_h
#define TwoWire_h
#include <inttypes.h>
#include "Stream.h"
#define BUFFER_LENGTH 32
// WIRE_HAS_END means Wire has end()
#define WIRE_HAS_END 1
class TwoWire : public Stream
{
private:
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;
static uint8_t txAddress;
static uint8_t txBuffer[];
static uint8_t txBufferIndex;
static uint8_t txBufferLength;
static uint8_t transmitting;
static void (*user_onRequest)(void);
static void (*user_onReceive)(int);
static void onRequestService(void);
static void onReceiveService(uint8_t*, int);
public:
TwoWire();
void begin();
void begin(uint8_t);
void begin(int);
void end();
void setClock(uint32_t);
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
uint8_t endTransmission(uint8_t);
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
uint8_t requestFrom(int, int);
uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
virtual int read(void);
virtual int peek(void);
virtual void flush(void);
void onReceive( void (*)(int) );
void onRequest( void (*)(void) );
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;
};
extern TwoWire Wire;
#endif

View file

@ -0,0 +1,515 @@
#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,83 @@
/*
* Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \defgroup compatibility Arduino - Contiki
*
* This defines contiki-compatible hardware definitions for running
* arduino sketches (or just to call arduino-compatible function).
* For now only for osd hardware, a similar file should exist for each
* arduino-compatible hardware.
*
* @{
*/
/**
* \file
* Header file for arduino compatibility
* \author
* Ralf Schlatterbeck <rsc@runtux.com>
*
*/
#ifdef __cplusplus
extern "C"{
#endif
#include "contiki.h"
/*
* The OSD hardware only supports timer 3 for PWM, timer 2 is used by
* contiki for sleep/wakeup timing and is not usable for PWM.
*/
#define digitalPinToTimer(pin) \
( (pin) == 2 \
? TIMER3A \
: ( (pin) == 3 \
? TIMER3B \
: ((pin == 4) ? TIMER3C : NOT_ON_TIMER) \
) \
)
/* Only init timer 3 with phase correct pwm 8-bit and prescaler 64 */
#define arduino_pwm_timer_init() \
(hwtimer_ini (3, HWT_WGM_PWM_PHASE_8_BIT, HWT_CLOCK_PRESCALER_64, 0))
/*
* VI settings, see coding style
* ex:ts=8:et:sw=2
*/
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */

View file

@ -0,0 +1,36 @@
/*
Copyright (c) 2014 Arduino. 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 <stdlib.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);
}

30
cpu/avr/dev/arduino/new.h Normal file
View file

@ -0,0 +1,30 @@
/*
Copyright (c) 2014 Arduino. 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 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);
#endif

545
cpu/avr/dev/arduino/twi.c Normal file
View file

@ -0,0 +1,545 @@
/*
twi.c - TWI/I2C library for Wiring & Arduino
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 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#include <math.h>
#include <stdlib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
#include "Arduino.h" // for digitalWrite
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#include "pins_arduino.h"
#include "twi.h"
static volatile uint8_t twi_state;
static volatile uint8_t twi_slarw;
static volatile uint8_t twi_sendStop; // should the transaction end with a stop
static volatile uint8_t twi_inRepStart; // in the middle of a repeated start
static void (*twi_onSlaveTransmit)(void);
static void (*twi_onSlaveReceive)(uint8_t*, int);
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_masterBufferIndex;
static volatile uint8_t twi_masterBufferLength;
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_txBufferIndex;
static volatile uint8_t twi_txBufferLength;
static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_rxBufferIndex;
static volatile uint8_t twi_error;
/*
* Function twi_init
* Desc readys twi pins and sets twi bitrate
* Input none
* Output none
*/
void twi_init(void)
{
// initialize state
twi_state = TWI_READY;
twi_sendStop = true; // default value
twi_inRepStart = false;
// activate internal pullups for twi.
digitalWrite(SDA, 1);
digitalWrite(SCL, 1);
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
/* twi bit rate formula from atmega128 manual pg 204
SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
note: TWBR should be 10 or higher for master mode
It is 72 for a 16mhz Wiring board with 100kHz TWI */
// enable twi module, acks, and twi interrupt
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}
/*
* Function twi_disable
* Desc disables twi pins
* Input none
* Output none
*/
void twi_disable(void)
{
// disable twi module, acks, and twi interrupt
TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));
// deactivate internal pullups for twi.
digitalWrite(SDA, 0);
digitalWrite(SCL, 0);
}
/*
* Function twi_slaveInit
* Desc sets slave address and enables interrupt
* Input none
* Output none
*/
void twi_setAddress(uint8_t address)
{
// set twi slave address (skip over TWGCE bit)
TWAR = address << 1;
}
/*
* Function twi_readFrom
* Desc attempts to become twi bus master and read a
* series of bytes from a device on the bus
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes to read into array
* sendStop: Boolean indicating whether to send a stop at the end
* Output number of bytes read
*/
uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
uint8_t i;
// ensure data will fit into buffer
if(TWI_BUFFER_LENGTH < length){
return 0;
}
// wait until twi is ready, become master receiver
while(TWI_READY != twi_state){
continue;
}
twi_state = TWI_MRX;
twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
// initialize buffer iteration vars
twi_masterBufferIndex = 0;
twi_masterBufferLength = length-1; // This is not intuitive, read on...
// On receive, the previously configured ACK/NACK setting is transmitted in
// response to the received byte before the interrupt is signalled.
// Therefor we must actually set NACK when the _next_ to last byte is
// received, causing that NACK to be sent in response to receiving the last
// expected byte of data.
// build sla+w, slave device address + w bit
twi_slarw = TW_READ;
twi_slarw |= address << 1;
if (true == twi_inRepStart) {
// if we're in the repeated start state, then we've already sent the start,
// (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
// We need to remove ourselves from the repeated start state before we enable interrupts,
// since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
// up. Also, don't enable the START interrupt. There may be one pending from the
// repeated start that we sent outselves, and that would really confuse things.
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
do {
TWDR = twi_slarw;
} while(TWCR & _BV(TWWC));
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
}
else
// send start condition
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
// wait for read operation to complete
while(TWI_MRX == twi_state){
continue;
}
if (twi_masterBufferIndex < length)
length = twi_masterBufferIndex;
// copy twi buffer to data
for(i = 0; i < length; ++i){
data[i] = twi_masterBuffer[i];
}
return length;
}
/*
* Function twi_writeTo
* Desc attempts to become twi bus master and write a
* series of bytes to a device on the bus
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes in array
* wait: boolean indicating to wait for write or not
* sendStop: boolean indicating whether or not to send a stop at the end
* Output 0 .. success
* 1 .. length to long for buffer
* 2 .. address send, NACK received
* 3 .. data send, NACK received
* 4 .. other twi error (lost bus arbitration, bus error, ..)
*/
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
{
uint8_t i;
// ensure data will fit into buffer
if(TWI_BUFFER_LENGTH < length){
return 1;
}
// wait until twi is ready, become master transmitter
while(TWI_READY != twi_state){
continue;
}
twi_state = TWI_MTX;
twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
// initialize buffer iteration vars
twi_masterBufferIndex = 0;
twi_masterBufferLength = length;
// copy data to twi buffer
for(i = 0; i < length; ++i){
twi_masterBuffer[i] = data[i];
}
// build sla+w, slave device address + w bit
twi_slarw = TW_WRITE;
twi_slarw |= address << 1;
// if we're in a repeated start, then we've already sent the START
// in the ISR. Don't do it again.
//
if (true == twi_inRepStart) {
// if we're in the repeated start state, then we've already sent the start,
// (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
// We need to remove ourselves from the repeated start state before we enable interrupts,
// since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
// up. Also, don't enable the START interrupt. There may be one pending from the
// repeated start that we sent outselves, and that would really confuse things.
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
do {
TWDR = twi_slarw;
} while(TWCR & _BV(TWWC));
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
}
else
// send start condition
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
// wait for write operation to complete
while(wait && (TWI_MTX == twi_state)){
continue;
}
if (twi_error == 0xFF)
return 0; // success
else if (twi_error == TW_MT_SLA_NACK)
return 2; // error: address send, nack received
else if (twi_error == TW_MT_DATA_NACK)
return 3; // error: data send, nack received
else
return 4; // other twi error
}
/*
* Function twi_transmit
* Desc fills slave tx buffer with data
* must be called in slave tx event callback
* Input data: pointer to byte array
* length: number of bytes in array
* Output 1 length too long for buffer
* 2 not slave transmitter
* 0 ok
*/
uint8_t twi_transmit(const uint8_t* data, uint8_t length)
{
uint8_t i;
// ensure data will fit into buffer
if(TWI_BUFFER_LENGTH < length){
return 1;
}
// ensure we are currently a slave transmitter
if(TWI_STX != twi_state){
return 2;
}
// set length and copy data into tx buffer
twi_txBufferLength = length;
for(i = 0; i < length; ++i){
twi_txBuffer[i] = data[i];
}
return 0;
}
/*
* Function twi_attachSlaveRxEvent
* Desc sets function called before a slave read operation
* Input function: callback function to use
* Output none
*/
void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
{
twi_onSlaveReceive = function;
}
/*
* Function twi_attachSlaveTxEvent
* Desc sets function called before a slave write operation
* Input function: callback function to use
* Output none
*/
void twi_attachSlaveTxEvent( void (*function)(void) )
{
twi_onSlaveTransmit = function;
}
/*
* Function twi_reply
* Desc sends byte or readys receive line
* Input ack: byte indicating to ack or to nack
* Output none
*/
void twi_reply(uint8_t ack)
{
// transmit master read ready signal, with or without ack
if(ack){
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
}else{
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
}
}
/*
* Function twi_stop
* Desc relinquishes bus master status
* Input none
* Output none
*/
void twi_stop(void)
{
// send stop condition
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
// wait for stop condition to be exectued on bus
// TWINT is not set after a stop condition!
while(TWCR & _BV(TWSTO)){
continue;
}
// update twi state
twi_state = TWI_READY;
}
/*
* Function twi_releaseBus
* Desc releases bus control
* Input none
* Output none
*/
void twi_releaseBus(void)
{
// release bus
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
// update twi state
twi_state = TWI_READY;
}
ISR(TWI_vect)
{
switch(TW_STATUS){
// All Master
case TW_START: // sent start condition
case TW_REP_START: // sent repeated start condition
// copy device address and r/w bit to output register and ack
TWDR = twi_slarw;
twi_reply(1);
break;
// Master Transmitter
case TW_MT_SLA_ACK: // slave receiver acked address
case TW_MT_DATA_ACK: // slave receiver acked data
// if there is data to send, send it, otherwise stop
if(twi_masterBufferIndex < twi_masterBufferLength){
// copy data to output register and ack
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
twi_reply(1);
}else{
if (twi_sendStop)
twi_stop();
else {
twi_inRepStart = true; // we're gonna send the START
// don't enable the interrupt. We'll generate the start, but we
// avoid handling the interrupt until we're in the next transaction,
// at the point where we would normally issue the start.
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
twi_state = TWI_READY;
}
}
break;
case TW_MT_SLA_NACK: // address sent, nack received
twi_error = TW_MT_SLA_NACK;
twi_stop();
break;
case TW_MT_DATA_NACK: // data sent, nack received
twi_error = TW_MT_DATA_NACK;
twi_stop();
break;
case TW_MT_ARB_LOST: // lost bus arbitration
twi_error = TW_MT_ARB_LOST;
twi_releaseBus();
break;
// Master Receiver
case TW_MR_DATA_ACK: // data received, ack sent
// put byte into buffer
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
case TW_MR_SLA_ACK: // address sent, ack received
// ack if more bytes are expected, otherwise nack
if(twi_masterBufferIndex < twi_masterBufferLength){
twi_reply(1);
}else{
twi_reply(0);
}
break;
case TW_MR_DATA_NACK: // data received, nack sent
// put final byte into buffer
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
if (twi_sendStop)
twi_stop();
else {
twi_inRepStart = true; // we're gonna send the START
// don't enable the interrupt. We'll generate the start, but we
// avoid handling the interrupt until we're in the next transaction,
// at the point where we would normally issue the start.
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
twi_state = TWI_READY;
}
break;
case TW_MR_SLA_NACK: // address sent, nack received
twi_stop();
break;
// TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
// Slave Receiver
case TW_SR_SLA_ACK: // addressed, returned ack
case TW_SR_GCALL_ACK: // addressed generally, returned ack
case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
// enter slave receiver mode
twi_state = TWI_SRX;
// indicate that rx buffer can be overwritten and ack
twi_rxBufferIndex = 0;
twi_reply(1);
break;
case TW_SR_DATA_ACK: // data received, returned ack
case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
// if there is still room in the rx buffer
if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
// put byte in buffer and ack
twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
twi_reply(1);
}else{
// otherwise nack
twi_reply(0);
}
break;
case TW_SR_STOP: // stop or repeated start condition received
// ack future responses and leave slave receiver state
twi_releaseBus();
// put a null char after data if there's room
if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
twi_rxBuffer[twi_rxBufferIndex] = '\0';
}
// callback to user defined callback
twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
// since we submit rx buffer to "wire" library, we can reset it
twi_rxBufferIndex = 0;
break;
case TW_SR_DATA_NACK: // data received, returned nack
case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
// nack back at master
twi_reply(0);
break;
// Slave Transmitter
case TW_ST_SLA_ACK: // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
// enter slave transmitter mode
twi_state = TWI_STX;
// ready the tx buffer index for iteration
twi_txBufferIndex = 0;
// set tx buffer length to be zero, to verify if user changes it
twi_txBufferLength = 0;
// request for txBuffer to be filled and length to be set
// note: user must call twi_transmit(bytes, length) to do this
twi_onSlaveTransmit();
// if they didn't change buffer & length, initialize it
if(0 == twi_txBufferLength){
twi_txBufferLength = 1;
twi_txBuffer[0] = 0x00;
}
// transmit first byte from buffer, fall
case TW_ST_DATA_ACK: // byte sent, ack returned
// copy data to output register
TWDR = twi_txBuffer[twi_txBufferIndex++];
// if there is more to send, ack, otherwise nack
if(twi_txBufferIndex < twi_txBufferLength){
twi_reply(1);
}else{
twi_reply(0);
}
break;
case TW_ST_DATA_NACK: // received nack, we are done
case TW_ST_LAST_DATA: // received ack, but we are done already!
// ack future responses
twi_reply(1);
// leave slave receiver state
twi_state = TWI_READY;
break;
// All
case TW_NO_INFO: // no state information
break;
case TW_BUS_ERROR: // bus error, illegal stop/start
twi_error = TW_BUS_ERROR;
twi_stop();
break;
}
}

54
cpu/avr/dev/arduino/twi.h Normal file
View file

@ -0,0 +1,54 @@
/*
twi.h - TWI/I2C library for Wiring & Arduino
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
*/
#ifndef twi_h
#define twi_h
#include <inttypes.h>
//#define ATMEGA8
#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif
#ifndef TWI_BUFFER_LENGTH
#define TWI_BUFFER_LENGTH 32
#endif
#define TWI_READY 0
#define TWI_MRX 1
#define TWI_MTX 2
#define TWI_SRX 3
#define TWI_STX 4
void twi_init(void);
void twi_disable(void);
void twi_setAddress(uint8_t);
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
uint8_t twi_transmit(const uint8_t*, uint8_t);
void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
void twi_attachSlaveTxEvent( void (*)(void) );
void twi_reply(uint8_t);
void twi_stop(void);
void twi_releaseBus(void);
#endif

View file

@ -0,0 +1,104 @@
/*
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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#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);
volatile uint8_t *reg, *out;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
out = portOutputRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
*out &= ~bit;
SREG = oldSREG;
} else if (mode == INPUT_PULLUP) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
*out |= bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
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;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
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);
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.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
if (*portInputRegister(port) & bit) return HIGH;
return LOW;
}

View file

@ -0,0 +1,69 @@
/*
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"
#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
#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
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define EXTERNAL_NUM_INTERRUPTS 8
#elif defined(__AVR_ATmega128RFA1__)
#define EXTERNAL_NUM_INTERRUPTS 8
#else
#define EXTERNAL_NUM_INTERRUPTS 2
#endif
typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

55
cpu/avr/dev/batmon.c Normal file
View file

@ -0,0 +1,55 @@
#include "contiki.h"
#include "batmon.h"
#include <util/delay.h>
int8_t batmon_init()
{
return 0;
}
int8_t batmon_get_voltage(uint16_t* voltage)
{
uint16_t volt = 0;
uint16_t resolution = 75;
uint16_t offset = 2550;
int8_t ctr = 0;
BATMON = 0 | _BV(BATMON_HR);
_delay_us(2);
if(BATMON & _BV(BATMON_OK))
{
// voltage above 2.550 V
resolution = 75;
offset = 2550;
for(ctr=15; ctr>=0; ctr--)
{
BATMON = (BATMON & 0xF0) | (ctr);
_delay_us(2);
if(BATMON & _BV(BATMON_OK)) break;
}
}
else
{
// voltage below 2.550 V
resolution = 50;
offset = 1700;
BATMON &= ~_BV(BATMON_HR);
for(ctr=15; ctr>=0; ctr--)
{
BATMON = (BATMON & 0xF0) | (ctr);
_delay_us(2);
if(BATMON & _BV(BATMON_OK)) break;
}
}
volt = resolution*ctr+offset;
*voltage=volt;
return 0;
}

8
cpu/avr/dev/batmon.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef BATMON_H_
#define BATMON_H_
int8_t batmon_init();
int8_t batmon_get_voltage(uint16_t* voltage);
#endif /* BATMON_H_ */

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2012, BinaryLabs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: battery-sensor.h,v 1.1 2012/08/25 19:34:06 nifi Exp $
*/
/**
* \file
* Battery sensor file for Atmega128rfa1.
* \author
* Paulo Louro <paulolouro@binarylabs.dk>
* Harald Pichler <harald@the-develop.net>
*/
/**
*The atmel rf23x radios have a low voltage detector that can be configured in units of 75 millivolts. Here is example *code for the ATmega128rfa1, where the BATMON register is in extended io space [dak664]
*/
#include "dev/battery-sensor.h"
#include "dev/batmon.h"
const struct sensors_sensor battery_sensor;
/*---------------------------------------------------------------------------*/
/**
* \return Voltage on battery measurement with BATMON register.
*/
static int
value(int type)
{
uint16_t h;
/*
uint8_t p1;
BATMON = 16; //give BATMON time to stabilize at highest range and lowest voltage
// Bandgap can't be measured against supply voltage in this chip.
// Use BATMON register instead
for ( p1=16; p1<31; p1++) {
BATMON = p1;
clock_delay_usec(100); // delay needed !!
if ((BATMON&(1<<BATMON_OK))==0) break;
}
h=2550-75*16-75+75*p1; //-75 to take the floor of the 75 mv transition window
*/
batmon_get_voltage(&h);
return h;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
// No configuration needed. readADC() handles all the config needed.
batmon_init();
return type == SENSORS_ACTIVE;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
// analog sensors are always ready
return 1;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status);

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012, BinaryLabs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: battery-sensor.h,v 1.1 2012/08/25 19:34:06 nifi Exp $
*/
/**
* \file
* Battery sensor header file for Atmega128rfa1.
* \author
* Paulo Louro <paulolouro@binarylabs.dk>
*/
#ifndef __BATTERY_SENSOR_H__
#define __BATTERY_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor battery_sensor;
#define BATTERY_SENSOR "Battery"
#endif /* __BATTERY_SENSOR_H__ */

View file

@ -0,0 +1,88 @@
/* Sensor routine */
#include "lib/sensors.h"
#include "dev/button-sensor.h"
#include <avr/interrupt.h>
#include "led.h" // debug
const struct sensors_sensor button_sensor;
static struct timer debouncetimer;
static int status(int type);
static int enabled = 0;
volatile static int bstate;
volatile static int bstatei;
struct sensors_sensor *sensors[1];
unsigned char sensors_flags[1];
#define BUTTON_BIT INTF4
#define BUTTON_CHECK_IRQ() (EIFR & BUTTON_BIT) ? 0 : 1
#define PRINTF(...) printf(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
ISR(INT4_vect)
{
if(BUTTON_CHECK_IRQ()) {
bstatei = (PINE & _BV(PE4) ? 0 : 1);
if(timer_expired(&debouncetimer)) {
// led1_on();
timer_set(&debouncetimer, CLOCK_SECOND / 16);
bstate = (PINE & _BV(PE4) ? 0 : 1);
if(bstate == bstatei){
sensors_changed(&button_sensor);
}
// led1_off();
}
}
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
//return (PINE & _BV(PE4) ? 0 : 1) || !timer_expired(&debouncetimer);
return bstate;
}
static int
configure(int type, int c)
{
switch (type) {
case SENSORS_ACTIVE:
if (c) {
if(!status(SENSORS_ACTIVE)) {
// led1_on();
timer_set(&debouncetimer, 0);
DDRE |= (0<<DDE4); // Set pin as input
PORTE |= (1<<PORTE4); // Set port PORTE bint 5 with pullup resistor
EICRB |= (1<<ISC40); // For falling edge
EIMSK |= (1<<INT4); // Set int
enabled = 1;
sei();
// led1_off();
}
} else {
enabled = 0;
EIMSK &= ~(1<<INT4); // clear int
}
return 1;
}
return 0;
}
static int
status(int type)
{
switch (type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;//(EIMSK & (1<<INT5) ? 0 : 1);//BUTTON_IRQ_ENABLED();
}
return 0;
}
SENSORS_SENSOR(button_sensor, BUTTON_SENSOR,
value, configure, status);

View file

@ -371,13 +371,13 @@ volatile static uint8_t osccalhigh,osccallow;
if (seconds < 60) { //give a minute to stabilize if (seconds < 60) { //give a minute to stabilize
if(++lockcount >= 8192UL*128/RTIMER_ARCH_SECOND) { if(++lockcount >= 8192UL*128/RTIMER_ARCH_SECOND) {
lockcount=0; lockcount=0;
rtimer_phase = TCNT3 & 0x0fff; rtimer_phase = PLAT_TCNT & 0x0fff;
if (seconds < 2) OSCCAL=100; if (seconds < 2) OSCCAL=100;
if (last_phase > rtimer_phase) osccalhigh=++OSCCAL; else osccallow=--OSCCAL; if (last_phase > rtimer_phase) osccalhigh=++OSCCAL; else osccallow=--OSCCAL;
last_phase = rtimer_phase; last_phase = rtimer_phase;
} }
} else { } else {
uint8_t error = (TCNT3 - last_phase) & 0x3f; uint8_t error = (PLAT_TCNT - last_phase) & 0x3f;
if (error == 0) { if (error == 0) {
} else if (error<32) { } else if (error<32) {
OSCCAL=osccallow-1; OSCCAL=osccallow-1;

125
cpu/avr/dev/dht11.c Normal file
View file

@ -0,0 +1,125 @@
/*
DHT-11 Library
(c) Created by Charalampos Andrianakis on 18/12/11.
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 <avr/io.h>
#include "contiki.h"
#include "dht11.h"
#include "led.h" // debug
#define udelay(u) clock_delay_usec(u)
#define mdelay(u) clock_delay_msec(u)
// todo: set DHT22 or DHT11 in project file
// define for DHT11 else for DHT22, RHT03
// #define DHT11 1
uint8_t DHT_Read_Data(uint16_t *temperature, uint16_t *humidity){
//data[5] is 8byte table where data come from DHT are stored
//laststate holds laststate value
//counter is used to count microSeconds
uint8_t data[5], laststate = 0, counter = 0, j = 0, i = 0;
//Clear array
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
uint8_t volatile sreg;
sreg = SREG; /* Save status register before disabling interrupts. */
cli(); /* Disable interrupts. */
//Set pin Output
//Pin High
DHT_DRIVE();
mdelay(100); //Wait for 100mS
//Send Request Signal
//Pin Low
OUTP_0(); //20ms Low
mdelay(20);
//Pin High
OUTP_1();
udelay(40); //40us High
//Set pin Input to read Bus
//Set pin Input
DHT_RELEASE();
laststate=DHT_INP(); //Read Pin value
//Repeat for each Transistions
for (i=0; i<MAXTIMINGS; i++) {
//While state is the same count microseconds
//led1_on();
//led1_off();
while (laststate==DHT_INP()) {
udelay(1);
counter++;
if (counter>254) break;
}
if (counter>254) break;
//laststate==_BV(DHT_PIN) checks if laststate was High
//ignore the first 2 transitions which are the DHT Response
//if (laststate==_BV(DHT_PIN) && (i > 2)) {
if ((i&0x01) && (i > 2)) {
//Save bits in segments of bytes
//Shift data[] value 1 position left
//Example. 01010100 if we shift it left one time it will be
//10101000
data[j/8]<<=1;
if (counter >= 15) { //If it was high for more than 40uS
//led1_on();
data[j/8]|=1; //it means it is bit '1' so make a logic
//led1_off();
} //OR with the value (save it)
j++; //making an OR by 1 to this value 10101000
} //we will have the resault 10101001
//1 in 8-bit binary is 00000001
//j/8 changes table record every 8 bits which means a byte has been saved
//so change to next record. 0/8=0 1/8=0 ... 7/8=0 8/8=1 ... 15/8=1 16/8=2
laststate=DHT_INP(); //save current state
counter=0; //reset counter
}
SREG = sreg; /* Enable interrupts. */
//printf("HUM %d %d %d %d %d %d",data[0],data[1],data[2],data[3],data[4],(uint8_t)(data[0] + data[1] + data[2] + data[3]) );
//Check if data received are correct by checking the CheckSum
if ((uint8_t)(data[0] + data[1] + data[2] + data[3]) == data[4]) {
#ifdef DHT11
*humidity = data[0]*100;
*temperature = data[2]*100;
#else
*humidity = ((uint16_t)data[0]<<8 | data[1])*10;
*temperature = ((uint16_t)data[2]<<8 | data[3])*10;
#endif
return 0;
}else{
*humidity = 2;
*temperature = 2;
// uart_puts("\r\nCheck Sum Error");
}
return 0xff; // Check Sum Error
}

67
cpu/avr/dev/dht11.h Normal file
View file

@ -0,0 +1,67 @@
/*
DHT-11 Library
(c) Created by Charalampos Andrianakis on 18/12/11.
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 <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
/* DHT 1-wire is at PortE.6 */
#define DHT_PIN_READ PINE
#define DHT_PIN_MASK _BV(PE6)
#define DHT_PxOUT PORTE
#define DHT_PxDIR DDRE
#define SET_PIN_INPUT() (DHT_PxDIR &= ~DHT_PIN_MASK)
#define SET_PIN_OUTPUT() (DHT_PxDIR |= DHT_PIN_MASK)
#define OUTP_0() (DHT_PxOUT &= ~DHT_PIN_MASK)
#define OUTP_1() (DHT_PxOUT |= DHT_PIN_MASK)
#define PIN_INIT() do{ \
SET_PIN_INPUT(); \
OUTP_0(); \
} while(0)
/* Drive the one wire interface hight */
#define DHT_DRIVE() do { \
SET_PIN_OUTPUT(); \
OUTP_1(); \
} while (0)
/* Release the one wire by turning on the internal pull-up. */
#define DHT_RELEASE() do { \
SET_PIN_INPUT(); \
OUTP_1(); \
} while (0)
/* Read one bit. */
#define DHT_INP() (DHT_PIN_READ & DHT_PIN_MASK)
//The packet size is 40bit but each bit consists of low and high state
//so 40 x 2 = 80 transitions. Also we have 2 transistions DHT response
//and 2 transitions which indicates End Of Frame. In total 84
#define MAXTIMINGS 84
//This is the main function which requests and reads the packet
uint8_t DHT_Read_Data(uint16_t *temperature, uint16_t *humidity);

291
cpu/avr/dev/ds1820.c Normal file
View file

@ -0,0 +1,291 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: ds1820.c,v 1.5 2010/08/25 18:35:52 nifi Exp $
*/
/*
* Device driver for the Dallas Semiconductor DS1820 chip. Heavily
* based on the application note 126 "1-Wire Communications Through
* Software".
*
* http://www.maxim-ic.com/appnotes.cfm/appnote_number/126
*/
/*
* For now we stuff in Moteiv Corporation's unique OUI.
* From http://www.ethereal.com/distribution/manuf.txt:
* 00:12:75 Moteiv # Moteiv Corporation
*
* The EUI-64 is a concatenation of the 24-bit OUI value assigned by
* the IEEE Registration Authority and a 40-bit extension identifier
* assigned by the organization with that OUI assignment.
*/
#include <avr/io.h>
#include <string.h>
#include "contiki.h"
#include "ds1820.h"
unsigned char ds1820_id[8];
unsigned char ds1820_ok[8];
/* 1-wire is at PortE.3 */
#define SERIAL_ID_PIN_READ PINE
//#define SERIAL_ID_PIN_MASK _BV(PE3)
#define SERIAL_ID_PIN_MASK _BV(PE4)
#define SERIAL_ID_PxOUT PORTE
#define SERIAL_ID_PxDIR DDRE
#define SET_PIN_INPUT() (SERIAL_ID_PxDIR &= ~SERIAL_ID_PIN_MASK)
#define SET_PIN_OUTPUT() (SERIAL_ID_PxDIR |= SERIAL_ID_PIN_MASK)
#define OUTP_0() (SERIAL_ID_PxOUT &= ~SERIAL_ID_PIN_MASK)
#define OUTP_1() (SERIAL_ID_PxOUT |= SERIAL_ID_PIN_MASK)
#define PIN_INIT() do{ \
SET_PIN_INPUT(); \
OUTP_0(); \
} while(0)
/* Drive the one wire interface low */
#define OW_DRIVE() do { \
SET_PIN_OUTPUT(); \
OUTP_0(); \
} while (0)
/* Release the one wire by turning on the internal pull-up. */
#define OW_RELEASE() do { \
SET_PIN_INPUT(); \
OUTP_1(); \
} while (0)
/* Read one bit. */
#define INP() (SERIAL_ID_PIN_READ & SERIAL_ID_PIN_MASK)
/*
* Delay times in us.
*/
#define tA 6 /* min-5, recommended-6, max-15 */
#define tB 64 /* min-59, recommended-64, max-N/A */
#define tC 60 /* min-60, recommended-60, max-120 */
#define tD 10 /* min-5.3, recommended-10, max-N/A */
#define tE 9 /* min-0.3, recommended-9, max-9.3 */
#define tF 55 /* min-50, recommended-55, max-N/A */
#define tG 0 /* min-0, recommended-0, max-0 */
#define tH 480 /* min-480, recommended-480, max-640 */
#define tI 70 /* min-60.3, recommended-70, max-75.3 */
#define tJ 410 /* min-410, recommended-410, max-N/A */
/*---------------------------------------------------------------------------*/
#define udelay(u) clock_delay_usec(u)
/*---------------------------------------------------------------------------*/
static int
owreset(void)
{
int result;
OW_DRIVE();
udelay(tH); /* 480 < tH < 640 */
OW_RELEASE(); /* Releases the bus */
udelay(tI);
result = INP();
udelay(tJ);
return result;
}
/*---------------------------------------------------------------------------*/
static void
owwriteb(unsigned byte)
{
int i = 7;
do {
if(byte & 0x01) {
OW_DRIVE();
udelay(tA);
OW_RELEASE(); /* Releases the bus */
udelay(tB);
} else {
OW_DRIVE();
udelay(tC);
OW_RELEASE(); /* Releases the bus */
udelay(tD);
}
if(i == 0) {
return;
}
i--;
byte >>= 1;
} while(1);
}
/*---------------------------------------------------------------------------*/
static unsigned
owreadb(void)
{
unsigned result = 0;
int i = 7;
do {
OW_DRIVE();
udelay(tA);
OW_RELEASE(); /* Releases the bus */
udelay(tE);
if (INP()){
result |= 0x80; /* LSbit first */
}
udelay(tF);
if(i == 0) {
return result;
}
i--;
result >>= 1;
} while(1);
}
/*---------------------------------------------------------------------------*/
/* Polynomial ^8 + ^5 + ^4 + 1 */
static unsigned
crc8_add(unsigned acc, unsigned byte)
{
int i;
acc ^= byte;
for(i = 0; i < 8; i++) {
if(acc & 1) {
acc = (acc >> 1) ^ 0x8c;
} else {
acc >>= 1;
}
}
return acc;
}
/*---------------------------------------------------------------------------*/
int
ds1820_init()
{
int i;
unsigned family, crc, acc;
PIN_INIT();
if(owreset() == 0) { /* Something pulled down 1-wire. */
owwriteb(0x33); /* Read ROM command. */
family = owreadb();
/* We receive 6 bytes in the reverse order, LSbyte first. */
for(i = 7; i >= 2; i--) {
ds1820_id[i] = owreadb();
}
crc = owreadb();
/* Verify family DS1820 and that CRC match. */
if(family != 0x10) {
goto fail;
}
acc = crc8_add(0x0, family);
for(i = 7; i >= 2; i--) {
acc = crc8_add(acc, ds1820_id[i]);
}
if(acc == crc) {
ds1820_id[0] = 0x00;
ds1820_id[1] = 0x00;
ds1820_id[2] = 0x00;
return 1; /* Success! */
}
} else {
}
fail:
memset(ds1820_id, 0x0, sizeof(ds1820_id));
return 0; /* Fail! */
}
/*---------------------------------------------------------------------------*/
int
ds1820_temp()
{
ds1820_convert();
// wait max 750ms pin lo
clock_wait(CLOCK_SECOND);
ds1820_read();
return 1;
}
int
ds1820_convert()
{
unsigned i;
PIN_INIT();
for(i=0;i<3;i++){
if(owreset() == 0) { /* Something pulled down 1-wire. */
owwriteb(0xCC); /* Skip ROM command. */
owwriteb(0x44); /* Convert T command. */
OW_RELEASE(); /* Releases the bus */
return 1;
} else {
}
}
return 0; /* Fail! */
}
/*---------------------------------------------------------------------------*/
int
ds1820_read()
{
int i;
unsigned crc, acc;
if(owreset() == 0) { /* Something pulled down 1-wire. */
owwriteb(0xCC); /* Skip ROM command. */
owwriteb(0xBE); /* Read Scratchpad command. */
/* We receive 8 bytes in the reverse order, LSbyte first. */
for(i = 0; i < 8; i++) {
ds1820_id[i] = owreadb();
}
crc = owreadb();
acc=0;
for(i = 0; i < 8; i++) {
acc = crc8_add(acc, ds1820_id[i]);
}
if(acc == crc) {
// store temp
for(i = 0; i < 8; i++) {
ds1820_ok[i]=ds1820_id[i];
}
return 1; /* Success! */
} else {
return 0; /* Fail! */
}
} else {
return 0; /* Fail! */
}
return 1; /* Fail! */
}

45
cpu/avr/dev/ds1820.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: ds1820.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $
*/
/* -*- C -*- */
/* @(#)$Id: ds1820.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ */
#ifndef DS1820_H
#define DS1820_H
extern unsigned char ds1820_id[8];
extern unsigned char ds1820_ok[8];
extern int ds1820_init();
extern int ds1820_convert();
extern int ds1820_read();
extern int ds1820_temp();
#endif /* DS1820_H */

391
cpu/avr/dev/i2c.c Normal file
View file

@ -0,0 +1,391 @@
/*
* Copyright (c) 2014, Ingo Gulyas Intembsys
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* I2C driver for ATMEGA128rfa1
*
* \author
* Ingo Gulyas Intembsys
* office@intembsys.at
* www.intembsys.at
*/
#include "i2c.h"
#include "contiki-conf.h"
#include <stdint.h>
#include <avr/power.h>
#include <stdbool.h>
#include <stddef.h>
#if I2C_TD != 0
#include <stdio.h>
#include <avr/pgmspace.h>
#include "system_mgmt.h"
#define PRINTD(FORMAT,args...) {sleep_acquire_lock(); printf_P(PSTR(FORMAT),##args); sleep_release_lock();}
#else
#define PRINTD(...)
#endif
#if WITH_RTDEBUG == 1
#include "rtdebug.h"
#define RTDEBUG_PUSH(x) rtdebug_push(x)
#else
#warning "I2C Driver compiling without RTDEBUG!"
#define RTDEBUG_PUSH(x)
#endif
#ifndef TIMEOUT_TIMER
#warning "I2C Driver compiling without TIMEOUT!"
#endif
static int8_t wait_job();
static int8_t wait_stop();
static int8_t i2c_ioctl(const i2c_driver* const me, uint8_t cmd, uint8_t arg);
static int8_t i2c_read(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len);
static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len);
// static linkage of member functions
i2c_driver i2c_drv = {i2c_ioctl, i2c_read, i2c_write};
// lock spi if driver opened to prevent further opening access
static volatile bool i2c_lock = false;
///////////////////////////////////////////////////////////////
// global functions
///////////////////////////////////////////////////////////////
i2c_driver* i2c_open(void)
{
if(i2c_lock == true)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_OPEN__DEVICE_BUSY);
return NULL;
}
i2c_lock = true;
power_twi_enable();
I2C_INIT();
TWBR = I2C_FREQ_STANDARD;
TWSR &= ~((1<<TWPS1) | (1<<TWPS0));
TWSR |= (1<<TWPS0);
TWCR = (1<<TWEN);
return &i2c_drv;
}
void i2c_close(i2c_driver* const me)
{
if(me == NULL || i2c_lock == false)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_CLOSE__NO_DEVICE);
return;
}
i2c_reset();
return;
}
void i2c_reset(void)
{
TWCR &= ~(1<<TWEN);
I2C_DEINIT();
power_twi_disable();
i2c_lock = false;
return;
}
///////////////////////////////////////////////////////////////
// local helper functions
///////////////////////////////////////////////////////////////
#ifdef TIMEOUT_TIMER
static int8_t wait_job()
{
int8_t status = I2C_OK;
uint16_t timeout = TIMEOUT_TIMER_NOW_ADD(I2C_TIMEOUT);
while (!(TWCR & (1<<TWINT)))
{
if(!(TIMEOUT_TIMER_LT(TIMEOUT_TIMER_NOW(), timeout)))
{
status = I2C_ERROR_TIMEOUT;
break;
}
}
return status;
}
static int8_t wait_stop()
{
int8_t status = I2C_OK;
uint16_t timeout = TIMEOUT_TIMER_NOW_ADD(I2C_TIMEOUT);
while (TWCR & (1<<TWSTO))
{
if(!(TIMEOUT_TIMER_LT(TIMEOUT_TIMER_NOW(), timeout)))
{
status = I2C_ERROR_TIMEOUT;
break;
}
}
return status;
}
#else
static int8_t wait_job()
{
while (!(TWCR & (1<<TWINT)));
return I2C_OK;
}
static int8_t wait_stop()
{
while (TWCR & (1<<TWSTO));
return I2C_OK;
}
#endif
///////////////////////////////////////////////////////////////
// member functions
///////////////////////////////////////////////////////////////
static int8_t i2c_ioctl(const i2c_driver* const me, uint8_t cmd, uint8_t arg)
{
if(me == NULL || i2c_lock == false)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_IOCTL__DEVICE_CLOSED);
return I2C_ERROR_DRIVER;
}
if(cmd == I2C_IOCTL_CMD_SET_FREQ)
{
switch(arg)
{
case I2C_FREQ_400KHZ: TWBR = I2C_FREQ_400KHZ; break;
case I2C_FREQ_250KHZ: TWBR = I2C_FREQ_250KHZ; break;
case I2C_FREQ_100KHZ: TWBR = I2C_FREQ_100KHZ; break;
case I2C_FREQ_50KHZ: TWBR = I2C_FREQ_50KHZ; break;
case I2C_FREQ_10KHZ: TWBR = I2C_FREQ_10KHZ; break;
default:
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_IOCTL__ARG_INVALID);
return I2C_ERROR_DRIVER;
}
}
}
else
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_IOCTL__CMD_INVALID);
return I2C_ERROR_DRIVER;
}
return I2C_OK;
}
static int8_t i2c_read(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len)
{
uint8_t i = 0;
int8_t status = I2C_OK;
if(me == NULL || i2c_lock == false)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__DEVICE_CLOSED);
return I2C_ERROR_DRIVER;
}
if((len > 0) && (buffer == NULL))
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__ERROR_NULLPOINTER);
return I2C_ERROR_DRIVER;
}
do
{
if(cmd_flags & I2C_CMD_FLAG_START)
{
I2C_START();
if(wait_job() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
break;
}
if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP))
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_ERROR);
status = I2C_ERROR_START;
break;
}
PRINTD("I2C-RD-START\n");
}
if(len == 0) break;
for(i=0; i<(len-1); i++)
{
I2C_READ_BYTE_ACK();
if(wait_job() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
break;
}
if(I2C_STATUS() != I2C_STATUS_DATAR_ACK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_ERROR);
status = I2C_ERROR_READ;
break;
}
buffer[i] = I2C_RX_REG;
PRINTD("I2C-RD-RACK: 0x%02X\n", buffer[i]);
}
I2C_READ_BYTE_NACK();
if(wait_job() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
break;
}
if(I2C_STATUS() != I2C_STATUS_DATAR_NACK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_ERROR);
status = I2C_ERROR_READ;
break;
}
buffer[i] = I2C_RX_REG;
PRINTD("I2C-RD-RNACK: 0x%02X\n", buffer[i]);
} while (0);
if(cmd_flags & I2C_CMD_FLAG_STOP)
{
I2C_STOP();
if(wait_stop() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__STOP_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
}
PRINTD("I2C-RD_STOP\n");
}
return status;
}
static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len)
{
uint8_t i = 0;
int8_t status = I2C_OK;
if(me == NULL || i2c_lock == false)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__DEVICE_CLOSED);
return I2C_ERROR_DRIVER;
}
if((len > 0) && (data == NULL))
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__ERROR_NULLPOINTER);
return I2C_ERROR_DRIVER;
}
do
{
if(cmd_flags & I2C_CMD_FLAG_START)
{
I2C_START();
if(wait_job() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
break;
}
if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP))
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_ERROR);
status = I2C_ERROR_START;
break;
}
PRINTD("I2C-WR-START\n");
}
for(i=0; i<len; i++)
{
I2C_TX_REG = data[i];
I2C_WRITE_BYTE();
if(wait_job() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__WRITE_BYTE_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
break;
}
if((I2C_STATUS() != I2C_STATUS_DATAW_ACK) && (I2C_STATUS() != I2C_STATUS_SLAW_ACK) && (I2C_STATUS() != I2C_STATUS_SLAR_ACK))
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__WRITE_BYTE_ERROR);
status = I2C_ERROR_WRITE;
break;
}
PRINTD("I2C-WR-BYTE: 0x%02X\n", data[i]);
}
} while (0);
if(cmd_flags & I2C_CMD_FLAG_STOP)
{
I2C_STOP();
if(wait_stop() != I2C_OK)
{
RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__STOP_TIMEOUT);
status = I2C_ERROR_TIMEOUT;
}
PRINTD("I2C-WR-STOP\n");
}
return status;
}

131
cpu/avr/dev/i2c.h Normal file
View file

@ -0,0 +1,131 @@
/*
* Copyright (c) 2014, Ingo Gulyas Intembsys
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* I2C driver for ATMEGA128rfa1
*
* \author
* Ingo Gulyas Intembsys
* office@intembsys.at
* www.intembsys.at
*/
#ifndef I2C_H_
#define I2C_H_
#include <stdint.h>
////////////////////////////////////////////////////////////////////////////////////////////
// CONFIGURATION SECTION:
#define I2C_TD 0 // compiler switch: i2c testdriver code
#define I2C_PORT PORTD
#define I2C_DDR DDRD
#define I2C_SCL_PIN 0
#define I2C_SDA_PIN 1
// END OF CONFIGURATION SECTION
////////////////////////////////////////////////////////////////////////////////////////////
#define I2C_INIT() ({I2C_DDR &= ~((1<<I2C_SCL_PIN) | (1<<I2C_SDA_PIN)); I2C_PORT |= ((1<<I2C_SCL_PIN) | (1<<I2C_SDA_PIN));})
#define I2C_DEINIT() ({I2C_DDR &= ~((1<<I2C_SCL_PIN) | (1<<I2C_SDA_PIN)); I2C_PORT |= ((1<<I2C_SCL_PIN) | (1<<I2C_SDA_PIN));})
#define I2C_FREQ_STANDARD I2C_FREQ_50KHZ
#if F_CPU == 16000000UL
#define I2C_FREQ_400KHZ 0x03
#define I2C_FREQ_250KHZ 0x06
#define I2C_FREQ_100KHZ 0x12
#define I2C_FREQ_50KHZ 0x26
#define I2C_FREQ_10KHZ 0xC6
#else
#error "NO I2C FREQUENCY DEFINED -> CHECK F_CPU SETTINGS!"
#endif
#define I2C_STATUS_REG TWSR
#define I2C_TX_REG TWDR
#define I2C_RX_REG TWDR
#define I2C_START() (TWCR = (1<<TWINT) |(1<<TWSTA) | (1<<TWEN))
#define I2C_STOP() (TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO))
#define I2C_WRITE_BYTE() (TWCR = (1<<TWINT) | (1<<TWEN))
#define I2C_READ_BYTE_ACK() (TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA))
#define I2C_READ_BYTE_NACK() (TWCR = (1<<TWINT) | (1<<TWEN))
#define I2C_STATUS() (I2C_STATUS_REG & I2C_STATUS_MASK)
#define I2C_STATUS_MASK 0xF8
#define I2C_STATUS_START 0x08
#define I2C_STATUS_START_REP 0x10
#define I2C_STATUS_SLAW_ACK 0x18
#define I2C_STATUS_DATAW_ACK 0x28
#define I2C_STATUS_SLAR_ACK 0x40
#define I2C_STATUS_DATAR_ACK 0x50
#define I2C_STATUS_DATAR_NACK 0x58
#define I2C_ADR_WR(adr) ((adr<<1) & ~(1<<0))
#define I2C_ADR_RD(adr) ((adr<<1) | (1<<0))
#define I2C_CMD_FLAG_NONE 0x00
#define I2C_CMD_FLAG_START (1<<0)
#define I2C_CMD_FLAG_STOP (1<<1)
#define I2C_OK 0
#define I2C_ERROR_DRIVER -1
#define I2C_ERROR_TIMEOUT -2
#define I2C_ERROR_START -3
#define I2C_ERROR_WRITE -4
#define I2C_ERROR_READ -5
#define I2C_IOCTL_CMD_SET_FREQ 0x01
typedef struct i2c_driver i2c_driver;
struct i2c_driver
{
int8_t (*ioctl)(const i2c_driver* const me, uint8_t cmd, uint8_t arg);
int8_t (*read)(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len);
int8_t (*write)(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len);
};
i2c_driver* i2c_open(void);
void i2c_close(i2c_driver* const me);
void i2c_reset(void);
#endif /* I2C_H_ */

73
cpu/avr/dev/key.c Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2010 harald pichler
* 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.
*/
/**
* \file
*
* \brief
* This file provides Raven KEY support.
*
* \author
* Harald Pichler harald@the-develop.net
*
*/
#include "key.h"
/*---------------------------------------------------------------------------*/
/**
* \brief This will intialize the KEY for button readings.
*/
void
key_init(void)
{
/* Enter is input w/pullup */
DDRF &= ~(1<<PINF1);
}
/*---------------------------------------------------------------------------*/
/**
* \brief This will poll run key_task() to determine if a button has been pressed.
*
* \retval True if button is pressed
* \retval False if button is not pressed
*/
uint8_t
is_button(void)
{
/* Return true if button has been pressed. */
if ( PINF & (1<<PINF1) ) {
return 0;
}
else{
return 1;
}
}

50
cpu/avr/dev/key.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010 Harald Pichler
* 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.
*/
/**
* \file
*
* \brief
* This file provides Raven Key support.
*
* \author
* Harald Pixhlwe harald@the-develop.net
*
*/
#ifndef __KEY_H__
#define __KEY_H__
#include <stdint.h>
#include <avr/io.h>
void key_init(void);
uint8_t is_button(void);
#endif /* __KEY_H__ */

89
cpu/avr/dev/led.c Normal file
View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2012 harald pichler
* 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.
*/
/**
* \file
*
* \brief
* This file provides Raven LED support.
*
* \author
* Harald Pichler harald@the-develop.net
*
*/
#include "led.h"
/**
* \addtogroup relay
* \{
*/
/*---------------------------------------------------------------------------*/
/**
* \brief Turns the Raven LED1 on.
*/
void
led1_on(void)
{
PORTE &= ~(1<<PINE5);
DDRE |= (1<<PINE5);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Turns the Raven LED1 off.
*/
void
led1_off(void)
{
PORTE |= (1<<PINE5);
DDRE |= (1<<PINE5);
}
/*---------------------------------------------------------------------------*/
void
led2_on(void)
{
PORTE &= ~(1<<PINE4);
DDRE |= (1<<PINE4);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Turns the Raven LED1 off.
*/
void
led2_off(void)
{
PORTE |= (1<<PINE4);
DDRE |= (1<<PINE4);
}
/*---------------------------------------------------------------------------*/

67
cpu/avr/dev/led.h Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2012 Harald Pichler
* 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.
*/
/**
* \file
*
* \brief
* This file provides Raven LED support.
*
* \author
* Harald Pichler harald@the-develop.net
*
*/
#ifndef __LED_H__
#define __LED_H__
#include <avr/io.h>
/* Some io.h definitions of shift vary among processors */
#ifndef DDE0
#define DDE0 DDRE0
#define DDE1 DDRE1
#define DDE2 DDRE2
#define DDE3 DDRE3
#define DDE4 DDRE4
#define DDE5 DDRE5
#define DDE6 DDRE6
#define DDE7 DDRE7
#endif
/** @name LED Functions */
/** @{ */
void led1_on(void);
void led1_off(void);
void led2_on(void);
void led2_off(void);
/** @} */
#endif /* __LED_H__ */

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) , Harald Pichler.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: servo-sensor.c,v 1.0 2013/02/20 19:34:06 nifi Exp $
*/
/**
* \file
* optriac sensor header file for Atmega128rfa1.
* \author
* Harald Pichler <harald@the-develop.net>
*/
#include "contiki.h"
#include "Arduino.h"
#include "dev/optriac-sensor.h"
#define PRINTF(...) printf(__VA_ARGS__)
const struct sensors_sensor optriac_sensor;
static int status(int type);
static int enabled = 0;
static int optriac[2]={0,0};
static int optriacpin[8]={OPTRIAC_PIN_1,OPTRIAC_PIN_2};
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return optriac[type];
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
switch(type) {
case SENSORS_ACTIVE:
if(c) {
if(!status(SENSORS_ACTIVE)) {
pinMode(optriacpin[OPTRIAC_SENSOR_1], OUTPUT);
digitalWrite(optriacpin[OPTRIAC_SENSOR_1], LOW);
pinMode(optriacpin[OPTRIAC_SENSOR_2], OUTPUT);
digitalWrite(optriacpin[OPTRIAC_SENSOR_2], LOW);
enabled = 1;
}
} else {
enabled = 1;
}
break;
case OPTRIAC_SENSOR_1:
case OPTRIAC_SENSOR_2:
if(c==0){
digitalWrite(optriacpin[type], LOW);
optriac[type]=0;
}else{
digitalWrite(optriacpin[type], HIGH);
optriac[type]=1;
};
break;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;
}
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(optriac_sensor, OPTRIAC_SENSOR, value, configure, status);

View file

@ -0,0 +1,54 @@
/*
* Copyright (c), Harald Pichler.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: servo-sensor.h,v 1.0 2013/02/20 19:34:06 nifi Exp $
*/
/**
* \file
* Servo sensor header file for Atmega128rfa1.
* \author
* Harald Pichler <harald@the-develop.net>
*/
#ifndef __OPTRIAC_SENSOR_H__
#define __OPTRIAC_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor optriac_sensor;
#define OPTRIAC_SENSOR "TRIAC"
#define OPTRIAC_SENSOR_1 0
#define OPTRIAC_SENSOR_2 1
/* default pins Arduino-Merkurboard */
#define OPTRIAC_PIN_1 2
#define OPTRIAC_PIN_2 3
#endif /* __OPTRIAC_SENSOR_H__ */

85
cpu/avr/dev/pir-sensor.c Normal file
View file

@ -0,0 +1,85 @@
/* Sensor routine */
#include "contiki.h"
#include "lib/sensors.h"
#include "dev/pir-sensor.h"
#include <avr/interrupt.h>
#include "led.h" // debug
const struct sensors_sensor pir_sensor;
static struct timer debouncetimer;
static int status(int type);
static int enabled = 0;
struct sensors_sensor *sensors[1];
unsigned char sensors_flags[1];
#define PIR_BIT INTF6
#define PIR_CHECK_IRQ() (EIFR & PIR_BIT) ? 0 : 1
#define PRINTF(...) printf(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
ISR(INT6_vect)
{
// leds_toggle(LEDS_YELLOW);
if(PIR_CHECK_IRQ()) {
if(timer_expired(&debouncetimer)) {
// led1_on();
timer_set(&debouncetimer, CLOCK_SECOND / 4);
sensors_changed(&pir_sensor);
// led1_off();
}
}
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return (PORTE & _BV(PE6) ? 0 : 1) || !timer_expired(&debouncetimer);
//return 0;
}
static int
configure(int type, int c)
{
switch (type) {
case SENSORS_ACTIVE:
if (c) {
if(!status(SENSORS_ACTIVE)) {
// led1_on();
timer_set(&debouncetimer, 0);
DDRE |= (0<<DDE6); // Set pin as input
PORTE |= (1<<PORTE6); // Set port PORTE bint 6 with pullup resistor
EICRB |= (3<<ISC60); // For rising edge
EIMSK |= (1<<INT6); // Set int
enabled = 1;
sei();
// led1_off();
}
} else {
enabled = 0;
EIMSK &= ~(1<<INT6); // clear int
}
return 1;
}
return 0;
}
static int
status(int type)
{
switch (type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;//(EIMSK & (1<<INT6) ? 0 : 1);//PIR_IRQ_ENABLED();
}
return 0;
}
SENSORS_SENSOR(pir_sensor, PIR_SENSOR,
value, configure, status);

48
cpu/avr/dev/pir-sensor.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012, BinaryLabs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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: battery-sensor.h,v 1.1 2012/08/25 19:34:06 nifi Exp $
*/
/**
* \file
* PIR sensor header file for Atmega128rfa1.
* \author
* Harald Pichler <harald@the-develop.net>
*/
#ifndef __PIR_SENSOR_H__
#define __PIR_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor pir_sensor;
#define PIR_SENSOR "PIR"
#endif /* __PIR_SENSOR_H__ */

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