Compare commits

...

491 Commits

Author SHA1 Message Date
fddc4e647a 0.0.59 2018-01-10 12:52:48 -08:00
798a351f15 updated package lock 2018-01-10 12:52:36 -08:00
e61dffff03 fixing threshold 2018-01-10 11:45:08 -08:00
b9f5096480 pause until motor measured move is done 2018-01-10 11:29:27 -08:00
9912d68c8b fixing chassis 2018-01-10 11:14:25 -08:00
951b9be6e4 fixing motors 2018-01-10 11:14:18 -08:00
f64bf57000 Merge master 2018-01-10 09:56:32 -08:00
f1242724b5 Fix legofont icons 2018-01-10 09:55:58 -08:00
cd0c9df86e bump to 3.0.8 2018-01-10 08:58:54 -08:00
337d42287a 0.0.58 2018-01-09 22:14:43 -08:00
ce3383f1b7 Turn ratio field editor (#225)
* Turn ratio field editor (initial draft)

* Add field turn ratio editor

* Fix arrow rotation

* Fix left and right direction, remove unnecessary SVG circles.

* Update UI a little. add marker.

* updated math for turnratio angle

* slightly cuter

* cleanup

* consistent naming

* more cleanup

* fixing motor node issue

* updated package version
2018-01-09 22:05:26 -08:00
e51721303a Merge pull request #224 from Microsoft/fixportlabels
Fix port labels in the simulator.
2018-01-09 14:43:26 -08:00
50f6c77fdb Fix port labels in the simulator. Fixes #219 2018-01-09 14:43:01 -08:00
5ed0135124 cleaning up images (#223)
* cleaning up images

* extra comma
2018-01-09 12:51:44 -08:00
892a2d585f Thresholds (#222)
* add threshold blocks

* updated strings

* added gap

* reorg color/gyro blocks

* fixing sound names

* adding stop block

* fixing exanmples
2018-01-09 12:46:48 -08:00
9890f2340a Add no-drag class and set on synced motor labels. Fixes #213 (#221) 2018-01-09 12:04:37 -08:00
109b809909 Sort field port values. Fixes #212 (#220) 2018-01-09 12:01:42 -08:00
9cbf5efd7e 0.0.57 2018-01-08 22:01:11 -08:00
a27a7fcd55 removing measured overloads until blocks support (#215) 2018-01-08 15:27:37 -08:00
85263fb84d Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2018-01-08 15:13:20 -08:00
b5ad898c9e Screentweak (#214)
* adding pid

* hiding functions

* precision of value
2018-01-08 15:00:00 -08:00
456df3c442 Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2018-01-08 14:43:19 -08:00
1552eb05b4 matter most info 2018-01-08 14:43:15 -08:00
d60e2c4a7d adding pid 2018-01-08 14:36:34 -08:00
f4b78c3ee7 PID example 2018-01-08 14:06:39 -08:00
dd5e1957d5 fix coding page 2018-01-08 14:06:29 -08:00
d61a63f70a avoid overlaps in port view 2018-01-08 09:08:59 -08:00
4207bd06c0 removing microbit font 2018-01-08 08:53:03 -08:00
58763e398b 0.0.56 2018-01-07 23:39:04 -08:00
f77bf165eb updates strings 2018-01-07 20:51:48 -08:00
4880d9ea5b Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2018-01-07 20:45:56 -08:00
ab4fb019f9 more changes to "print" 2018-01-07 20:45:48 -08:00
2c2df31ba3 Merge pull request #205 from Microsoft/motorshuffle
shuffling motor blocks
2018-01-07 20:34:20 -08:00
0f2bda2496 shuffling motor blocks 2018-01-07 20:33:02 -08:00
44386be3c7 Merge pull request #185 from Microsoft/printlineinverted
invert arguments in print line
2018-01-07 12:14:16 -08:00
89ca66b8a9 Merge pull request #201 from Microsoft/speedfield
Add a speed field editor
2018-01-07 12:11:40 -08:00
64389a7689 more annotations 2018-01-07 10:06:02 -08:00
f77778ef85 Merge branch 'master' into speedfield 2018-01-07 09:59:11 -08:00
7d01823caf remove stopAllMotors on escape key 2018-01-07 09:58:08 -08:00
b3f9a4c92f Make sure we stop motors on exit (#199) 2018-01-07 07:54:40 -08:00
7fe8580de8 Add brick buttons field editor (#202)
* Add brick buttons field editor

* add hover title text
2018-01-07 07:52:07 -08:00
c70d6fe01a Remove unnecessary extra 'light' text in block pauseUntilLight (#203) 2018-01-07 00:12:29 -08:00
ed7099cc97 more square shaped corners 2018-01-06 21:00:39 -08:00
a79704fecc Decompilation and minor PR feedback 2018-01-06 17:16:08 -08:00
6a1b560101 Fix default 2018-01-06 14:40:09 -08:00
5e21f9ab6d Add a speed field editor 2018-01-06 14:25:50 -08:00
74648bd1df Merge pull request #198 from Microsoft/moresquarecorners
More square shaped corners on blocks
2018-01-06 12:55:51 -08:00
e24d4d56b1 More square shaped corners on blocks (toggle rect and arrow corner) 2018-01-06 00:12:32 -08:00
0345277bef 0.0.55 2018-01-06 00:00:40 -08:00
9ae6482f28 fixing isReady query on motors (#197) 2018-01-06 00:00:04 -08:00
77fb64043d stop all motors when pressing escape 2018-01-05 22:56:11 -08:00
f875681661 added roaming 2018-01-05 22:04:18 -08:00
fbb1fa688d fixing gallery 2018-01-05 21:50:50 -08:00
485f02ed27 cruise control activities 2018-01-05 21:49:04 -08:00
81f406c6cc ignition activities 2018-01-05 21:40:11 -08:00
ac0a7b326f 0.0.54 2018-01-05 21:30:05 -08:00
c814728354 pdated ultrasonic default 2018-01-05 21:29:52 -08:00
abeb378b17 reverse beeper 2018-01-05 21:20:00 -08:00
6928f9e50e traffic lights activity 2018-01-05 19:28:24 -08:00
931987468a light the way activities 2018-01-05 19:14:55 -08:00
94c4e508fe reversing the robot 2018-01-05 18:36:20 -08:00
ea46f1cbc7 3 activies from curriculum (#194)
* 3 activies from curriculum

* fixing style
2018-01-05 18:24:23 -08:00
9f9ce29476 Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2018-01-05 17:35:47 -08:00
50f6b04ed4 Re-implement Math.sign so it works on IE 11 (not supported). Square shaped corners for Flyout 2018-01-05 17:35:25 -08:00
64d6c2b090 Motors cleanup (#192)
* refactoring

* moving chassis into separate project

* added set motors
2018-01-05 16:02:52 -08:00
76ff39605a Remove synced motor label when motors are no longer in sync (#189) 2018-01-05 10:54:42 -08:00
2d3ea5631a Merge pull request #190 from Microsoft/consoleicon
Add console icon and set color.
2018-01-05 10:38:52 -08:00
e938f354fd Add console icon and set color. Fixes #152 2018-01-05 10:38:26 -08:00
886464b470 Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2018-01-05 08:47:26 -08:00
b9ff9d21f1 bump common packages 2018-01-05 08:47:22 -08:00
aa06fd344a store synched motor info always (#187) 2018-01-05 08:40:49 -08:00
dc6ce0efc7 0.0.53 2018-01-05 08:39:30 -08:00
4039a85bc9 Make sure the ESC button always stops the program 2018-01-05 16:17:33 +00:00
7bd6280292 Disable HID deploy from command line (seems broken; was crashing until my previous checkin) 2018-01-05 16:17:20 +00:00
2ebe96e563 Fix command line deploy 2018-01-05 15:33:09 +00:00
a9be582f90 gyro calibration done right (#186) 2018-01-04 23:21:19 -08:00
ac428a3936 invert arguments in print line 2018-01-04 22:13:17 -08:00
de91dc6ab7 Handle the case where multiple motors or multiple sensors are connected to the same port. (#181) 2018-01-04 21:57:01 -08:00
1e460eef9e basic reading of battery level (#182) 2018-01-04 21:50:13 -08:00
0db6987ee5 Add loader and animation (#180) 2018-01-04 16:17:14 -08:00
148657908c Merge pull request #179 from Microsoft/syncedmotorui
Synced motors label (in simulator)
2018-01-04 14:38:29 -08:00
f3f87331c8 nit 2018-01-04 14:09:10 -08:00
5aef77ccc6 Generalizing motorView for both medium and large motor views. Initial work towards synced motor views. Adding sync label for controller motor. 2018-01-04 14:03:50 -08:00
59ca9cf463 0.0.52 2018-01-04 13:04:23 -08:00
7da811246c Behaviors Driven Robotics (#178)
* adding avoid crash behavior

* more implementation

* add another simple behavior

* fixed synched motors

* bump common packages
2018-01-04 12:55:30 -08:00
69f8453947 Merge pull request #177 from Microsoft/sounds_bug_fix
Fix stopAllSounds simulator bug
2018-01-04 12:52:17 -08:00
39ba9b81af Initial work 2018-01-04 12:20:31 -08:00
51a14596cd 0.0.51 2018-01-04 11:41:49 -08:00
8518c446cd Merge pull request #176 from Microsoft/iefonticons
Fix font icons on IE, and add package icon on Windows
2018-01-04 11:40:42 -08:00
2f69df0d9d Fix font icons on IE, and add package icon on Windows 2018-01-04 11:39:20 -08:00
1789d0ce21 Lowercase menubar titles. 2018-01-04 10:42:37 -08:00
d0809510c4 Merge pull request #174 from Microsoft/addbetatag
Add beta tag.
2018-01-04 10:14:43 -08:00
6b9c0eaf65 Add beta tag. #150 2018-01-04 10:14:11 -08:00
52bdf94233 Merge pull request #173 from Microsoft/blockiconfont
Add block icon font
2018-01-04 09:57:11 -08:00
fd50ed8f7c Add block icon font 2018-01-04 09:52:12 -08:00
ba0eb93b0f use common packages tests implementation (#171) 2018-01-04 09:23:28 -08:00
9a4ed45797 0.0.50 2018-01-04 09:19:33 -08:00
820fdf3a3c Merge pull request #172 from Microsoft/fixwinicons
Fix check and cancel icons on windows
2018-01-04 09:18:30 -08:00
348d5ffc26 Fix check and cancel icons on windows 2018-01-04 09:17:30 -08:00
95e47a0b25 Merge pull request #169 from Microsoft/screenimgeditor
Initial screen field editor.
2018-01-04 08:37:56 -08:00
c3312ed5d1 Merge pull request #170 from Microsoft/clearcounts
moving motor blocks around
2018-01-04 08:37:39 -08:00
b7cdc7d0fe moving blocks around 2018-01-04 08:25:02 -08:00
dde5a35cd9 Initial screen field editor. Adding Lego designer assets to legoresources 2018-01-03 17:20:35 -08:00
be398d84ee Merge pull request #135 from Microsoft/field_ports
Add an output port field editor
2018-01-03 17:07:34 -08:00
4445acce7a Split editor extensions into multiple module loaded files. Re-using editor/deploy.ts for cmds. Fixing field ports 2018-01-03 16:18:39 -08:00
d6d8b0655b Merge branch 'master' into field_ports 2018-01-03 15:12:35 -08:00
216aa1ddaf Fix save icon 2018-01-03 15:07:45 -08:00
783a561941 0.0.49 2018-01-03 15:02:35 -08:00
c916664ae7 Fix download and save icons. 2018-01-03 15:02:24 -08:00
4b836ede1b Merge pull request #167 from Microsoft/blockfixes
Block layout fixes.
2018-01-03 14:22:18 -08:00
52fdaeec99 remove colon from print line block 2018-01-03 14:22:00 -08:00
2aaa45e10d Merge pull request #168 from Microsoft/remainingiconfixes
Remaining icon fixes.
2018-01-03 14:21:04 -08:00
7993363e89 Remaining icon fixes. Using blockIcons to show custom icons for built in categories 2018-01-03 14:20:33 -08:00
4d671f6cb0 Block layout fixes. Fixes to screen blocks. Adding print line API. 2018-01-03 14:00:08 -08:00
cc020d5a81 Merge pull request #124 from Microsoft/icon_font
Icon font
2018-01-03 12:35:52 -08:00
5c39862a44 Fix the rest of the icons (sensors, math, variables and extensions) 2018-01-03 12:35:33 -08:00
e0e5c95989 Merge branch 'master' into icon_font 2018-01-03 11:56:28 -08:00
800b4ad224 Merge pull request #165 from Microsoft/fixnullrefthis
Fix null ref for this when _update is called.
2018-01-03 11:42:38 -08:00
40c3b4b0cf Tweaking sensor icon 2018-01-03 11:36:43 -08:00
64bdc35e6f Merge paths for sensor icon 2018-01-03 11:29:49 -08:00
2b5f702bb6 Fix null ref for this when _update is called. 2018-01-03 11:20:37 -08:00
1c81ecd23f send ports data to console 2018-01-03 08:24:54 -08:00
4d223374b5 Differential drive (#164)
* clear sync speed cmd

* differential drive model

* use cm/s

* fixed aggressive clearing of motor sync command

* better computation of turn artio

* improved robot dimensions

* moving block up

* hanbdle infinite case

* correct handling of inifinte time/step

* better stop handling
2018-01-03 00:27:05 -08:00
dd9cf9014f Merge pull request #163 from Microsoft/fixnullderefbuttons
Fix null dereferencing issue for buttons
2018-01-02 23:19:55 -08:00
eb11d7926c Fix null dereferencing issue for buttons 2018-01-02 23:18:54 -08:00
609740dc48 Merge pull request #162 from Microsoft/moresensorfixes
Better fix for null dereferencing issue.
2018-01-02 22:51:45 -08:00
955a2c9757 Better fix for null dereferencing issue. Fix initial Color sensor mode (default). 2018-01-02 22:51:12 -08:00
02838e6c30 Merge pull request #161 from Microsoft/colorgridfixes
Update Color sensor control (colorGrid) to match spec
2018-01-02 22:30:04 -08:00
b0c54e84e6 Update Color sensor control (colorGrid) to match spec 2018-01-02 22:29:12 -08:00
b6644b7a23 Merge pull request #160 from Microsoft/sensorfixes
Sensor fixes. Fix race condition
2018-01-02 22:23:14 -08:00
3c4c38eb59 Fix null dereferencing issue. Fix sensor mode changed not clearing cached control. 2018-01-02 22:22:14 -08:00
29aba7b10b Fix advanced icons 2018-01-02 17:30:19 -08:00
7427142243 Merge branch 'icon_font' of https://github.com/Microsoft/pxt-ev3 into icon_font 2018-01-02 17:17:13 -08:00
436500babb Merge 2018-01-02 17:11:24 -08:00
82be4e344b More work 2018-01-02 17:07:36 -08:00
81bfca4ed6 0.0.48 2018-01-02 16:20:30 -08:00
c35dbdd38f Motor sync support in simulator (#159)
* parse sync motor command

* better sim support

* sync support

* fixing tank
2018-01-02 16:20:00 -08:00
1bc93013e6 0.0.47 2018-01-02 14:51:00 -08:00
58148eb1c3 Square shaped corners for Blockly blocks and dropdowns. (#158) 2018-01-02 13:32:07 -08:00
a7c62b45b2 Use legoIcons font for flyout headings 2018-01-02 13:01:28 -08:00
bd765d49ee Add lego resources.AI 2018-01-02 12:59:48 -08:00
383ca5467d Remove advexpanded/advcollapsed 2018-01-02 12:49:25 -08:00
e240e3b394 Check, cancel 2018-01-02 10:47:04 -08:00
7affbf8cb6 Save, download 2018-01-02 10:47:04 -08:00
4dff282633 Initial work 2018-01-02 10:47:04 -08:00
5d470fdcef Merge pull request #143 from Microsoft/persistselected
Persist selected state of controls across simulator restarts
2017-12-29 14:02:50 -08:00
f30eac41e9 Persist selected state of controls across simulator restarts 2017-12-28 11:17:18 -08:00
d7f46c0fb5 Hide screen picker properly from typescript 2017-12-28 11:15:53 -08:00
58384017f2 0.0.46 2017-12-28 09:08:27 -08:00
01f7fe633c Motorworks2 (#141)
* fixing polarity

* allocate motor on motorUsed only

* perform sub-step integration step for better precision
2017-12-28 09:07:57 -08:00
a9a9a89811 Better fonts and better alignment of motor reporter control 2017-12-27 20:43:39 -08:00
7e2251d8ac Fix negative motor reporting 2017-12-27 20:35:36 -08:00
1903a6e347 Merge pull request #140 from Microsoft/motorreporters
Add motor reporter control
2017-12-27 20:32:53 -08:00
2fb75a2d83 Added todo 2017-12-27 17:07:50 -08:00
0da175a8cd Add motor reporter control 2017-12-27 17:06:23 -08:00
f01370e4fd Simulator support for motor commands (#137)
* support for "step" functions

* locale files

* enum issue

* fixing decoding of array

* implement clear count

* log unknown commands
2017-12-27 17:05:15 -08:00
751df2fe8c Merge pull request #139 from Microsoft/colorandsliderresizefixes
Fix resizing in controls to work for all sizes including full screen
2017-12-27 16:31:20 -08:00
8be4bb11d8 Fix resizing in controls to work for all sizes including full screen 2017-12-27 16:30:42 -08:00
342e714ae2 Merge pull request #138 from Microsoft/updatemotorassets
Update motor SVG assets and connections
2017-12-27 14:48:50 -08:00
fb31b81f7e Update motor SVG assets and connections 2017-12-27 14:48:15 -08:00
8204995749 Fix wire view to match spec size of wires. 2017-12-26 23:28:29 -08:00
85c14bb05a Fix rotation and distance slider update state 2017-12-26 23:23:26 -08:00
c398a5a133 Update padding and fix wiring order 2017-12-26 23:19:04 -08:00
a1b059171b Add a output port field editor 2017-12-24 17:46:58 -08:00
afaedaa0b2 Merge pull request #134 from Microsoft/fixflickering
Fix resizing flickering issue in the simulator
2017-12-24 16:19:36 -08:00
0aa41e9a64 Fix resizing flickering issue, remove flip animation on start, remove the need for a default height and width in the layout engine 2017-12-24 11:59:01 -08:00
88df2e14cb Merge pull request #125 from Microsoft/sim_refactor_resize
Refactor sim for better resizing and support for multiple controls to be open
2017-12-22 14:01:35 -08:00
180f32f25c Simulator refactoring to support better resizing of modules and controls 2017-12-22 14:00:23 -08:00
995527675a Check, cancel 2017-12-21 11:30:32 -08:00
84eb849bc7 Save, download 2017-12-21 11:10:47 -08:00
5e0e35b4bd Initial work 2017-12-21 11:00:54 -08:00
300a2c1476 Merge pull request #123 from Microsoft/gradient_circle
Gradient circle
2017-12-20 16:34:59 -08:00
703bd01931 Increase stroke width 2017-12-20 16:25:26 -08:00
75a65eeab2 Add lego icons 2017-12-20 16:16:13 -08:00
38a9f153f7 pxtarget 2017-12-20 15:15:12 -08:00
3c5dae8c7b Small changes 2017-12-20 15:11:44 -08:00
85345969d3 Initial work 2017-12-20 14:58:41 -08:00
ac1e5d2846 Remove constant resize 2017-12-19 21:20:06 -08:00
11b4bbc07e Fix controls 2017-12-19 17:20:01 -08:00
7f5b8aed99 more tweaking of angle encoding 2017-12-19 17:15:53 -08:00
c989e2fdab Merge pull request #121 from Microsoft/motorphysics
Motor work
2017-12-19 17:07:15 -08:00
d3dcb5de85 Use setChangedState for touch and color sensors 2017-12-19 17:01:45 -08:00
9cca35d49f encoding 32bit angle into data buffer 2017-12-19 16:54:44 -08:00
7123bfecd3 removing cancel animation stuff 2017-12-19 16:21:14 -08:00
c8ac770983 read motor state into lms_motor 2017-12-19 16:18:17 -08:00
aa031036ee updating motor state in game loop 2017-12-19 16:03:26 -08:00
a7d002d949 0.0.45 2017-12-19 15:10:32 -08:00
93fd8c8c78 removing more icons 2017-12-19 15:10:13 -08:00
1765ca2d35 Merge pull request #116 from Microsoft/revert_screenopt
Use game loop instead of animation queue
2017-12-19 14:58:37 -08:00
1ab7ae6cfa minor PR feedback 2017-12-19 14:57:28 -08:00
3acf4e9ac5 More hardware tests (#119) 2017-12-19 14:55:48 -08:00
ef5fa9ae82 Minor fix to killing the animation when the sim is killed 2017-12-19 14:55:43 -08:00
e1f7a5b8cf Merge pull request #118 from Microsoft/ambient_light_threshold
Set high/low to 20/5 for ambient light mode
2017-12-19 14:42:54 -08:00
2c73bfc813 Set high/low to 20/5 2017-12-19 14:40:30 -08:00
d78d9c8686 basic ports view (#115)
* basic ports view

* slight adjustement of rendering
2017-12-19 14:26:57 -08:00
2157af3e63 Using game loop instead of queueAnimationUpdate 2017-12-19 14:20:35 -08:00
eac3e183c3 better test support 2017-12-19 13:10:40 -08:00
785ddff706 Reverting screen optimization to use SetInterval and didChange 2017-12-19 12:53:12 -08:00
e07d6e3a31 0.0.44 2017-12-19 11:53:50 -08:00
763ad3f763 0.0.43 2017-12-19 11:38:02 -08:00
919a03951c Removing icons (#114)
* removing icons

* added "pause for light"
2017-12-19 11:37:33 -08:00
9e427898ae added test framework (#113)
* added test framework

* added toString on motors

* enabling logs
2017-12-19 07:07:50 -08:00
60bf3a17d3 a mini-console support with scroll up / down (#112)
* a mini-console support with scroll up / down

* fix compile error
2017-12-18 22:36:32 -08:00
0529759a80 Fix ultrasonic value to use cm instead of 0.1 cm units (#110)
* Fix simulator

* use 250 instead of 255
2017-12-18 20:30:56 -08:00
b07f157181 0.0.42 2017-12-18 18:24:46 -08:00
2f5f7d4133 Merge pull request #111 from Microsoft/scale_screen
Add tiny padding around the screen for the canvas.
2017-12-18 17:08:02 -08:00
e6e1dce59f Add tiny padding around the screen for the canvas. 2017-12-18 17:07:23 -08:00
43a9d03231 fixing pauseUntilReady signature 2017-12-18 14:45:44 -08:00
c0f6cd3651 test passing on hw 2017-12-18 14:31:17 -08:00
f1445c6e89 Motor pause until ready (#108)
* adding command to pause until ready

* adding console API

* adding ready support for motors

* fix time output scale

* fixing angle
2017-12-18 14:13:38 -08:00
04275ee35c 0.0.41 2017-12-18 13:22:13 -08:00
f8d0594eca Merge pull request #107 from Microsoft/initial_sim
Initial sim implementation
2017-12-18 13:21:48 -08:00
5be3b31e00 Merge branch 'master' into initial_sim 2017-12-18 13:21:35 -08:00
84c1079e50 Fix Safari bug. 2017-12-18 13:19:49 -08:00
6320379d02 Initial sim implementation 2017-12-18 13:04:17 -08:00
b166f6034e storing test 2017-12-18 09:43:44 -08:00
d07f672b28 fixing single motor set speed 2017-12-18 09:17:19 -08:00
363e076f36 fixing motor compilation 2017-12-18 08:54:53 -08:00
8bf6f265f7 Merge pull request #105 from Microsoft/motorfixes
Motor fixes
2017-12-18 00:54:53 -08:00
217958aec3 fix polarity 2017-12-17 23:19:38 -08:00
367b1b0d1a properly setting multiple-motor options 2017-12-17 23:00:07 -08:00
6836852122 refactoring motors wiht base class (#104) 2017-12-17 22:47:13 -08:00
944098b9f9 Minor refactor fix (#102)
* Minor fix to a refactor of motor output this.brake to this._brake

* No (_this) in global context

* Minor fix
2017-12-17 21:12:18 -08:00
539cf3d73e 0.0.40 2017-12-15 14:30:51 -08:00
4b3e7cfb7d bump pxt-core to 3.0.2, bump pxt-common-packages to 0.14.13, 2017-12-15 14:30:43 -08:00
b144744509 Add tsconfig.json for easier library editing (#96) 2017-12-15 14:29:31 -08:00
e591bed6ad Add 'clear screen' block to brick category (#100) 2017-12-15 14:29:10 -08:00
6a4e64eac0 Merge pull request #79 from Microsoft/motorsync
Motor sync block
2017-12-15 14:28:03 -08:00
f7dd14ff7b Merge pull request #88 from Microsoft/even_more_sounds
Add 'stopAllSounds' block
2017-12-15 11:36:31 -08:00
bfd34cedd6 Update built files 2017-12-15 11:04:16 -08:00
8e1c075911 Merge pull request #98 from Microsoft/portFixes
Fix order of color and ultrasonic sensor ports.
2017-12-15 10:45:34 -08:00
a02f364a4c Update function names for consistency 2017-12-15 10:42:44 -08:00
48fee2c215 Merge pull request #99 from Microsoft/ui_changes
Some UI theming. square buttons
2017-12-15 08:55:45 -08:00
5780d1982c Some UI theming. square buttons 2017-12-15 08:55:21 -08:00
6fb08f0f7b Fix order of color and ultrasonic sensor ports. 2017-12-15 07:48:42 -08:00
13f8659b98 Merge pull request #97 from Microsoft/startup_delay
Startup delay for sensors to get values
2017-12-15 07:05:21 -08:00
edc9d17a8c Merge pull request #95 from Microsoft/serialnumber
Implement getSerialNumber (based on BT MAC)
2017-12-15 07:04:21 -08:00
c7a3f5bbd0 Delay user code by 100ms to get sensor reading (fixes #90) 2017-12-15 11:55:20 +00:00
41d5052583 Run sensor "change handler" also with the initial value 2017-12-15 11:54:53 +00:00
07ddec343a Formatting 2017-12-15 11:30:15 +00:00
5a9a5e997a Error reporting fixes 2017-12-15 11:29:18 +00:00
55b6549999 Implement getSerialNumber (based on BT MAC) 2017-12-15 11:25:23 +00:00
fcdc350e40 more motor work 2017-12-14 17:01:23 -08:00
9dedbeae1b updated parameters 2017-12-14 13:26:04 -08:00
124d8a0fd8 tank support 2017-12-14 13:25:27 -08:00
81fcbb6916 tweaks of blocks 2017-12-14 13:07:10 -08:00
d436bd1227 Fix simulator stop() method 2017-12-14 09:41:01 -08:00
cb648019bb Progress 2017-12-14 09:17:47 -08:00
11a88a9d94 updated signatures 2017-12-13 23:00:37 -08:00
92178f3371 bring back speed 2017-12-13 22:54:08 -08:00
3c86ae286f more work on motors 2017-12-13 22:40:40 -08:00
1b6d84a9b8 Merge branch 'master' into motorsync 2017-12-13 21:16:33 -08:00
2d81be3b24 Add 'stopAllSounds' block 2017-12-13 16:31:42 -08:00
14f57f54bf Merge pull request #87 from Microsoft/motor_fix_2
Motor data fix
2017-12-13 15:56:17 -08:00
e7c697c24d Merge pull request #85 from Microsoft/on_color_fix
Fix "on color detected" block
2017-12-13 15:55:47 -08:00
7ac63f038c Merge pull request #84 from Microsoft/fix_image_attrs
Adding block identity
2017-12-13 15:55:36 -08:00
557926d631 Merge pull request #78 from Microsoft/waitUntiltopauseUntil
renaming all "wait until" to "pause until"
2017-12-13 15:52:46 -08:00
da62d51615 Merge branch 'master' into motor_fix_2 2017-12-13 15:48:43 -08:00
3918857fcc Merge branch 'master' into on_color_fix 2017-12-13 15:48:24 -08:00
f1dcebdd88 Merge branch 'master' into fix_image_attrs 2017-12-13 15:48:09 -08:00
1d35c78737 Merge branch 'master' into motorsync 2017-12-13 15:47:52 -08:00
d17326ad7a Merge branch 'master' into waitUntiltopauseUntil 2017-12-13 15:47:27 -08:00
4948a88833 Merge pull request #83 from Microsoft/new_ts_cleanup
New ts cleanup
2017-12-13 15:46:58 -08:00
b73b924ec4 ignoreing docs errors 2017-12-13 15:35:53 -08:00
641d292c33 Clean commit for motor fix 2017-12-13 14:55:14 -08:00
223275fd65 Moving a line of code 2017-12-13 13:35:28 -08:00
6e42e816d3 Adding block identity 2017-12-13 10:42:49 -08:00
5678cf5df9 Fixing test file 2017-12-13 10:29:12 -08:00
67ec4accb9 Monitor memory usage and panic on over 8MB used 2017-12-13 15:28:52 +00:00
fa867c3a34 Cleanup 2017-12-12 15:24:36 -08:00
7865876e64 Merge branch 'master' into waitUntiltopauseUntil 2017-12-12 14:19:35 -08:00
113b42656c sync command working 2017-12-12 14:08:45 -08:00
7557380722 adding sync command 2017-12-12 13:20:25 -08:00
3e2a1ec9e1 missing strings files 2017-12-12 11:23:29 -08:00
09db613620 updated docs 2017-12-12 10:49:45 -08:00
bacb4673c9 renaming all "wait until" to "pause until" 2017-12-12 10:46:56 -08:00
e649a167cd Merge pull request #74 from Microsoft/powertospeed
some speed renamings
2017-12-11 23:20:17 -08:00
997e8efb20 Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2017-12-11 17:08:12 -08:00
1f380ce959 0.0.39 2017-12-11 17:00:06 -08:00
8cbf601131 0.0.38 2017-12-11 17:00:03 -08:00
bdbb2a8c2f Fix on start color 2017-12-11 16:58:29 -08:00
5e90cb4434 Merge pull request #75 from Microsoft/new_ts
Update to latest TS and update blocks colors to match Lego's edu colors
2017-12-11 16:55:25 -08:00
1bf1eb16f0 Update to latest TS and update blocks colors to match Lego's edu colors 2017-12-11 16:55:00 -08:00
fbc6fc30a7 some speed renamings 2017-12-11 16:07:46 -08:00
fee2329ca7 Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2017-12-08 11:23:07 -08:00
5656031e2d Merge pull request #73 from Microsoft/more_sounds
Limit sound concurrency to 1
2017-12-08 11:21:21 -08:00
e87e1767b5 Null check 2017-12-08 11:16:47 -08:00
2d7a108e79 Fix merge conflict 2017-12-07 16:28:30 -08:00
193f66fd2d Limit sound concurrency to 1 2017-12-07 16:27:28 -08:00
5768fcaf35 Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2017-12-07 13:58:38 -08:00
2c22ea925f Merge pull request #69 from Microsoft/sounds
Get rid of "play sound" blocks; add non-blocking "play sound effect"
2017-12-07 11:53:04 -08:00
4e4aa266d5 Limit sound concurrency 2017-12-07 11:27:29 -08:00
05bdbd7b40 icon resources 2017-12-07 08:33:13 -08:00
085ab0844b rename "power" to "set speed" for consistency 2017-12-06 22:41:51 -08:00
4ad229cb37 0.0.37 2017-12-06 22:35:03 -08:00
170ee33848 bump pxt-core to 2.3.37, 2017-12-06 22:34:52 -08:00
162e437527 using icons on drop downs 2017-12-06 22:34:11 -08:00
ab13cb9047 adding a few more icons 2017-12-06 21:40:00 -08:00
80454f55c7 0.0.36 2017-12-06 16:31:06 -08:00
30e576345b more icon updates 2017-12-06 16:29:21 -08:00
dfc4c83718 resizing svg to sqaures
updates some icons
2017-12-06 16:22:31 -08:00
e25d273765 LEGO resources 2017-12-06 15:57:40 -08:00
903e98ca22 Merge pull request #70 from Microsoft/nodefaultinfrared
removing infrared from default ev3 configuration
2017-12-05 11:15:17 -08:00
8a64085288 enable language/high contrast 2017-12-05 10:53:26 -08:00
22ab1cba8d removing infrared from default ev3 configuration 2017-12-05 10:49:48 -08:00
064d6f9411 Check if sound not defined 2017-12-04 12:24:41 -08:00
330aff8082 Restore 'play sound effect' name 2017-12-01 09:59:59 -08:00
0886a5d4e1 Merge branch 'master' of https://github.com/Microsoft/pxt-ev3 2017-11-30 15:54:11 -08:00
aa636aef96 Separate blocks for 'play sound' and 'play sound until done' 2017-11-30 15:49:50 -08:00
1865ced312 Merge pull request #67 from Microsoft/note_default
Default piano note should be 1046
2017-11-30 15:41:55 -08:00
b940befe85 Default piano note should be 1046 2017-11-30 12:44:22 -08:00
c6bae5e17b missed files 2017-11-30 11:28:20 -08:00
83e4898eab Merge pull request #66 from Microsoft/gyroproject
moving gyro into separate project
2017-11-30 10:47:13 -08:00
7bdb9683c9 fixing naming 2017-11-30 10:37:59 -08:00
3c675892aa moving gyro into separate project 2017-11-30 10:34:34 -08:00
3d29c5e323 0.0.35 2017-11-30 10:16:04 -08:00
15d59269d4 bump pxt-core to 2.3.31, 2017-11-30 10:15:54 -08:00
73b5e7dc3f Merge pull request #65 from Microsoft/ultrasonicsensor
Ultrasonic/IR sensor refactoring work
2017-11-30 10:14:30 -08:00
a92edcffee adding waitUntil to buttons 2017-11-30 10:05:00 -08:00
305a650125 using threshold detector 2017-11-30 09:59:28 -08:00
34a5aeb7d2 moving IR as well 2017-11-30 09:53:43 -08:00
32f524ddd8 fixing build 2017-11-30 09:48:43 -08:00
b690c1634b updated distance detection 2017-11-30 09:41:34 -08:00
8089841892 wait until 2017-11-30 09:39:24 -08:00
3d8c697586 moving into separate project 2017-11-30 09:38:04 -08:00
e365e3d1be Merge pull request #64 from Microsoft/color-sensor
Color sensor refactoring
2017-11-30 08:55:50 -08:00
4ed41adb6a avoid conflicts of event values 2017-11-30 08:31:31 -08:00
39b7f99741 update mode selection 2017-11-30 08:20:00 -08:00
ad17191ae2 collapse reflected/ambient blocks 2017-11-29 22:47:17 -08:00
4a8633f506 updated descriptions 2017-11-29 22:11:59 -08:00
3690f409b0 docs skeleton 2017-11-29 22:09:12 -08:00
97663d2b83 updated naming 2017-11-29 21:57:05 -08:00
4d2b7ced71 moving color sensor to separate project 2017-11-29 21:41:00 -08:00
5676103052 Merge pull request #63 from Microsoft/speedispower
use speed when setting power
2017-11-29 21:22:32 -08:00
cb8c14fbb1 Allow waitForEvent on main thread; fixes #60
also use target_panic() instead of assert
2017-11-29 19:54:17 -03:00
815d438d86 use speed when setting power 2017-11-29 00:04:54 -08:00
da8de1e31e Merge pull request #56 from Microsoft/note 2017-11-28 17:00:57 -08:00
b028916025 Increment pxt-core and pxt-common-packages dependencies 2017-11-28 16:48:16 -08:00
b9be74bad8 Merge pull request #59 from Microsoft/touch
adding touch button examples
2017-11-28 16:35:48 -08:00
7e502b1749 adding bare docs 2017-11-28 16:24:22 -08:00
f22edac84d moving touch stuff into separate projects 2017-11-28 16:11:15 -08:00
ef2807a84e Fill in real min and max 2017-11-28 16:04:25 -08:00
580b40876c fixing bumped 2017-11-28 16:02:04 -08:00
b57ae5d588 implement wasPressed 2017-11-28 15:33:43 -08:00
71479d0caa adding touch button examples 2017-11-28 15:23:54 -08:00
7e39cdde9d Add a todo 2017-11-27 17:21:32 -08:00
85ca6b3698 Support for new data structure 2017-11-27 14:12:04 -08:00
2c89848fda More 2017-11-21 17:11:11 -08:00
ed1c187514 Initial work 2017-11-21 11:35:53 -08:00
52816e6de7 Merge pull request #51 from Microsoft/debugging
Add debug function
2017-11-20 10:54:44 -08:00
60ac3a9d00 0.0.34 2017-11-18 07:37:59 -08:00
d2c7a5ace0 support for wait/when 2017-11-18 07:37:46 -08:00
79fcd1c01e 0.0.33 2017-11-18 07:34:50 -08:00
2d48725c63 bump pxt-core to 2.3.28, bump pxt-common-packages to 0.14.3, 2017-11-18 07:34:40 -08:00
802c3db0ba 0.0.32 2017-11-17 14:12:32 -08:00
4a7e8c5fa8 adding block for sounds 2017-11-16 23:28:44 -08:00
0ebffd8549 0.0.31 2017-11-16 22:55:51 -08:00
988a2b638b add icon 2017-11-16 22:52:29 -08:00
fb743dea74 Merge pull request #50 from Microsoft/icons
Icons in blocks
2017-11-16 22:48:35 -08:00
e400637ba1 Merge branch 'master' into icons 2017-11-16 22:47:40 -08:00
b2768b1099 added showimage 2017-11-16 22:46:51 -08:00
3a5885b28e 0.0.30 2017-11-16 22:25:36 -08:00
b602b52f7d bump pxt-core to 2.3.27, 2017-11-16 22:25:26 -08:00
90afb60cc4 bump pxt-core to 2.3.26, bump pxt-common-packages to 0.14.2, 2017-11-16 22:04:29 -08:00
c936c16c33 more icons 2017-11-16 22:03:43 -08:00
ead69e3c6e Add debug function 2017-11-16 16:28:10 -08:00
d100026d5c more icons 2017-11-16 13:05:50 -08:00
41c2899feb more icons 2017-11-16 13:03:15 -08:00
9437873427 more images 2017-11-16 12:58:37 -08:00
dab281a9cb including a few icons in block names 2017-11-16 12:41:47 -08:00
f27fb4d93c 0.0.29 2017-11-09 10:29:24 -08:00
11fb82eba9 Merge pull request #49 from Microsoft/updatepxt
Update pxt
2017-11-09 19:28:55 +01:00
170e6b700b updating to latest pxt 2017-11-09 10:24:12 -08:00
387ad763f8 bump pxt-core to 2.3.19, bump pxt-common-packages to 0.12.17, 2017-11-09 10:14:47 -08:00
0e61f162bb Fix style to match latest changes in master. 2017-10-31 11:27:18 -07:00
400f01a6be fixing duplicate block id 2017-10-31 09:42:53 -07:00
afcbe69c44 0.0.28 2017-10-31 09:04:27 -07:00
9165fe09fc bump pxt-core to 2.3.6, 2017-10-31 09:04:20 -07:00
08f36fbb94 Merge pull request #30 from Microsoft/jres
Import images and sounds from ev3 EDU
2017-10-31 16:48:24 +01:00
afca2aa4d1 Merge pull request #45 from Microsoft/motorsrename
API tinkering
2017-10-31 16:43:27 +01:00
3c6c766412 removing lego resources 2017-10-30 21:54:23 -07:00
329a1e15ea simplified IR API 2017-10-30 21:39:50 -07:00
16a025f3a0 simplified motor API 2017-10-30 21:29:18 -07:00
26b975b5f2 images 2017-10-30 14:51:14 -07:00
79b9bce904 Merge branch 'master' into jres 2017-10-30 13:29:45 -07:00
d3d9fa6ca0 Merge branch 'master' into jres 2017-10-30 13:29:16 -07:00
8f5c930f76 Update UI to latest. 2017-10-30 13:21:03 -07:00
a082807455 Fix locking in waitForEvent() and sample playing 2017-10-30 19:18:01 +00:00
3469f51b7b Don't need to use freshcoat branch of pxt (#31) 2017-10-30 19:06:49 +00:00
e8e31e6aa7 Fix brick.print() 2017-10-30 19:03:45 +00:00
2df90152fe Remove debug output 2017-10-30 18:56:03 +00:00
e25590539e Add sample-playing code 2017-10-30 18:55:23 +00:00
a7795302fc Make it compile with master 2017-10-30 18:54:53 +00:00
480d89ba8e Added swift stuff 2017-10-30 11:46:06 -07:00
9487d324fd added link to gitlab 2017-10-30 11:45:02 -07:00
bfc95e075e Merge branch 'master' into jres 2017-10-30 18:48:18 +01:00
7d4ba9b2b2 0.0.27 2017-10-30 10:47:03 -07:00
71b83040e6 bump pxt-core to 2.3.5, bump pxt-common-packages to 0.12.4, 2017-10-30 10:46:56 -07:00
1976534da0 Merge pull request #28 from Microsoft/sensorscat
Aligning categories with LabView/RobotC
2017-10-30 18:46:27 +01:00
ebbbe6e86c Add sounds (only simulator for now) 2017-10-30 17:25:58 +00:00
c4a9b4a381 updated brick color 2017-10-30 09:58:00 -07:00
c7d36a5e82 moving motors up 2017-10-30 09:55:36 -07:00
c8c45be057 fixing brick groups 2017-10-30 09:51:18 -07:00
a8a7267851 Add LEGO EDU images 2017-10-30 15:34:47 +00:00
9cdb4081fd Add PNG decompressor in SIM 2017-10-30 14:42:08 +00:00
dcb398d3d5 Rename Icon to Image 2017-10-30 13:28:01 +00:00
f6e350cf9f Add separate type for Icons (same repr as buffer) 2017-10-30 13:04:12 +00:00
c085094394 Add screen::unpackPNG() 2017-10-30 12:45:37 +00:00
7c2ea7c406 fixing more groups 2017-10-28 09:20:34 -07:00
84b98a2788 brick namespace 2017-10-28 09:13:02 -07:00
4e99cd3ef1 0.0.26 2017-10-27 19:23:01 +01:00
57647318c4 Sensor fixes 2017-10-27 19:18:56 +01:00
2720698864 Fix infinite loop 2017-10-27 19:18:47 +01:00
dfe2fe3cff brick refactoring 2017-10-27 11:05:04 -07:00
18fefa2a44 output -> motors 2017-10-27 11:01:11 -07:00
c0bab4877a Merge branch 'master' of github.com:Microsoft/pxt-ev3 2017-10-27 15:17:24 +01:00
d2a1d10ada Add converter from RGF to PNG 2017-10-27 15:17:21 +01:00
bcb68d937d Merge branch 'master' of https://github.com/microsoft/pxt-ev3 2017-10-27 02:52:47 -07:00
05a8395028 stop all motors 2017-10-27 02:52:42 -07:00
3a1601a419 Add rsf2wav.js 2017-10-27 10:42:33 +01:00
712c2178d2 simplify motor API 2017-10-27 01:47:25 -07:00
12cdad72c8 added puppet 2017-10-27 00:13:51 -07:00
95076f8f24 differentiate large/medium motors 2017-10-27 00:09:00 -07:00
6391620373 added 2 more activities 2017-10-26 23:58:34 -07:00
86212e2153 added sound of color 2017-10-26 23:46:55 -07:00
98e430f3c1 added example of converted lesson 2017-10-26 22:19:16 -07:00
5c7e856e7b removed incorrect buy link 2017-10-26 21:57:48 -07:00
a47988913e 0.0.25 2017-10-26 21:27:51 -07:00
ea72dba6c7 Merge pull request #17 from Microsoft/irevents
Ultrasonic + IR events + Remote events
2017-10-27 06:25:02 +02:00
215e846a54 refactored remote button 2017-10-26 21:10:37 -07:00
21b34cb459 simplified events 2017-10-26 20:57:18 -07:00
282134f5dc refactoring IR 2017-10-26 20:51:13 -07:00
6b44352839 event for ultrasonic module 2017-10-26 20:38:17 -07:00
9a883d5672 Merge branch 'master' into irevents 2017-10-26 20:21:06 -07:00
59ce4338d3 renaming IR events 2017-10-26 20:20:24 -07:00
90560050b8 Merge pull request #16 from Microsoft/fonts
Mounting events on various sensors
2017-10-27 05:19:36 +02:00
2c72173bfe Use the _query() infrastructure for polling 2017-10-25 13:34:05 +02:00
1a5992408b added event for color changes 2017-10-24 23:10:27 -07:00
0e1a3b7e6b adding setpixel 2017-10-24 22:05:24 -07:00
ea6bfa03bd touched -> pressed 2017-10-24 21:55:37 -07:00
20d584db2b 0.0.24 2017-10-24 21:18:16 -07:00
0e4e0d8899 0.0.23 2017-10-24 21:09:56 -07:00
a18a690417 Merge pull request #12 from Microsoft/motors
Converting motors to fixed instances
2017-10-25 06:09:27 +02:00
c9d57c5e8d enabling banner 2017-10-24 21:08:02 -07:00
7e9d42a571 reset motors on start 2017-10-24 20:28:31 -07:00
1b51320edb pausing while running motor 2017-10-24 20:20:07 -07:00
4f44238237 use fixed instances for motors 2017-10-24 20:16:33 -07:00
c8ffa0ded7 fixed test 2017-10-24 18:49:15 -07:00
6b07d5f716 0.0.22 2017-10-24 18:48:30 -07:00
8784e23b60 fixed build link 2017-10-24 17:01:36 -07:00
4b8409fbc0 0.0.21 2017-10-24 16:56:52 -07:00
3237978cba Merge pull request #4 from Microsoft/blockupdate
Blocks update
2017-10-24 16:56:32 -07:00
33c8902050 aligning groups with hardware name components 2017-10-24 16:52:13 -07:00
fa6c81cf80 buttons -> brick buttons 2017-10-24 16:25:03 -07:00
46175fc7db separating touch sensor stuff 2017-10-24 15:58:47 -07:00
e6ef86101f more renaming 2017-10-24 15:37:48 -07:00
c4d3d7634e fixed naming of sonar 2017-10-24 15:35:42 -07:00
b0380fbef8 more annotations 2017-10-24 15:33:28 -07:00
c85c68ab68 fixing color / gyro 2017-10-24 15:22:07 -07:00
334d5aca9a on/off field editors on motors 2017-10-24 15:03:21 -07:00
1330a0fb82 fixed gyro def 2017-10-24 14:54:36 -07:00
005447ce44 4 times more sensors\! 2017-10-24 19:58:52 +01:00
60d5271de2 Merge branch 'master' into blockupdate 2017-10-24 10:02:27 -07:00
e3ab6ace55 0.0.20 2017-10-24 10:01:49 -07:00
5f4488dea7 Merge pull request #3 from Microsoft/pxtupdate
Updated to latest of pxt / common
2017-10-24 10:00:41 -07:00
07dc3bdae1 fixing docs compilation 2017-10-24 09:55:38 -07:00
5d5d78ced0 compiled strings 2017-10-24 09:47:30 -07:00
fe46461c4c adding a few more blocks 2017-10-24 05:30:05 -07:00
ccda971fd1 Bump PXT and common packages 2017-10-24 12:50:00 +01:00
8fa6cf41ca updated build files 2017-10-23 13:43:59 -07:00
aa3c6d5fc0 bump pxt-core to 2.3.1, bump pxt-common-packages to 0.10.16, 2017-10-23 13:41:38 -07:00
6a719e7718 Use field toggle for switching the motor on / off 2017-10-04 17:04:26 -04:00
b18b8333d0 Remove button group 2017-10-03 02:31:06 -04:00
84d80131d4 Various UI fixes. Block refactoring and adding touch and color blocks. 2017-10-03 02:28:44 -04:00
4977358718 0.0.19 2017-09-15 10:06:47 -07:00
15b2ef6c92 Update theme.config 2017-09-15 10:06:33 -07:00
e0288ed741 bump pxt-core to 2.0.49, bump pxt-common-packages to 0.9.6, 2017-09-15 10:04:01 -07:00
df1caf9741 0.0.18 2017-09-01 16:50:18 -07:00
a755420d06 bump pxt-core to 2.0.34, bump pxt-common-packages to 0.9.3, 2017-09-01 16:50:13 -07:00
a139727fea 0.0.17 2017-08-28 21:52:26 -07:00
48e081e584 Update json strings 2017-08-28 21:52:09 -07:00
124ad5c915 bump pxt-core to 2.0.29, 2017-08-28 21:51:33 -07:00
75a571fda7 Update README.md 2017-08-14 14:35:03 -07:00
bb842056d4 0.0.16 2017-08-10 17:11:02 -07:00
41b023f83f bump pxt-core to 2.0.12, 2017-08-10 17:10:57 -07:00
1ff058460f Split out blockly into blockly.less 2017-08-10 17:10:08 -07:00
cb0895f166 Moving UF2 related code away from this repo 2017-08-10 09:49:30 -07:00
1340fd0162 0.0.15 2017-08-09 10:03:14 -07:00
a3f56f4c9a Fix pattern enum decompilation and setSpeed when no speed is set. 2017-08-09 10:02:58 -07:00
c0e2252157 0.0.14 2017-08-08 13:45:39 -07:00
92ad67315b bump pxt-core to 2.0.10, 2017-08-08 13:45:33 -07:00
385 changed files with 28258 additions and 17817 deletions

1
.gitignore vendored
View File

@ -31,3 +31,4 @@ videos/**
lib/
.vscode/
bin
scripts/out.*

View File

@ -1,8 +1,11 @@
# LEGO Mindstorms EV3 target for PXT
[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Private/pxt_project_pink/master/pxt-ev3_Push)](https://ci2.dot.net/job/Private/job/pxt_project_pink/job/master/job/pxt-ev3_Push/)
[![Build Status](https://ci2.dot.net/buildStatus/icon?job=Private/pxt_project_rainbow/master/pxt-ev3_Push)](https://ci2.dot.net/job/Private/job/pxt_project_rainbow/job/master/job/pxt-ev3_Push/)
This repo contains the editor target hosted at https://lego.makecode.com
This repo contains the editor target hosted at https://d541eec2-1e96-4b7b-a223-da9d01d0337a.pxt.io/
LEGO Auth: https://src.education.lego.com/groups/ev3-makecode (use Google Authenticator)
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square
## Local Dev setup
@ -14,7 +17,7 @@ These instructions assume familiarity with dev tools and languages.
In a common folder,
* clone https://github.com/Microsoft/pxt to ``pxt`` folder (currently, build against `freshcoat` branch)
* clone https://github.com/Microsoft/pxt to ``pxt`` folder
* clone https://github.com/Microsoft/pxt-common-packages to ``pxt-common-packages`` folder
* clone https://github.com/Microsoft/pxt-ev3 to ``pxt-ev3`` folder
* go to ``pxt`` and run

View File

@ -1,12 +0,0 @@
all: mod uf2
mod:
$(MAKE) -C .. MOD=d_usbdev M=`pwd`/kernel ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
@mkdir -p bin
cp kernel/*.ko bin/
uf2:
$(MAKE) -C uf2daemon
@mkdir -p bin
cp uf2daemon/server bin/uf2d

View File

@ -1,35 +0,0 @@
# Support code to run on EV3 brick
## Kernel module
Kernel module is based on LEGO's `d_usbdev` module, with the addition of slightly modified `g_mass_storage`
module from the Linux kernel. The module and supporting sources are licensed under GPLv2 (since
they are derived from GPLv2 code).
### Modifications
* the `d_usbdev` uses the composite framework to register an additional mass storage function in addtion
to the pre-existing custom USB HID function
* the `g_mass_storage` module has the following changes:
* additional `/sys/.../lun0/active` entry is added, which allows for signaling drive eject to the host
* `d_usbdev` has an additional `ioctl()` to pretend data came from the USB host - this can be used to direct
the VM to do stuff
### Kernel modifications
The kernel itself has modified FIFO queue sizes. The LEGO kernel uses `1024` for `ep1in` and `ep1out`,
and then `64` for `ep2` and `ep3`. Note that this is non-standard modification done with a kernel patch,
that I didn't manage to find. The MSD requires `512` for `ep2` and `ep3`. I have binary edited the kernel
to do so.
Note that there's 4k of FIFO memory in the hardware. If you set the queue sizes with a sum of more than
4k, the kernel will hang, and you will not know why.
## UF2 Daemon
The [UF2](https://github.com/Microsoft/uf2) daemon is based on
[UF2 ATSAMD21](https://github.com/Microsoft/uf2-samd21) bootloader code. It exposes a virtual
FAT16 file system over Linux Network Block Device interface (`/dev/nbd0` to be precise).
This device is then exposed via the `g_mass_storage` module to the host computer.
The Daemon is licensed under MIT.

View File

@ -1,10 +0,0 @@
#!/bin/sh
set -ex
echo Y > /sys/module/printk/parameters/time
cd /mnt/ramdisk/prjs/ko
#echo 3 > /proc/sys/kernel/printk
insmod ./nbd.ko
sleep 1
./uf2d /dev/nbd1 > /tmp/uf2d.log 2> /tmp/uf2derr.log
sleep 1
insmod ./d_usbdev.ko file=/dev/nbd1 HostStr=EV3 SerialStr=0016535543af

View File

@ -1,2 +0,0 @@
obj-m += $(MOD).o

File diff suppressed because it is too large Load Diff

View File

@ -1,762 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* This UsbDev file is based on and inheritated from
* the original file (zero.c) and work done by David Brownell
*
* >> zero.c -- Gadget Zero, for USB development <<
*
* >> Copyright (C) 2003-2008 David Brownell <<
* >> Copyright (C) 2008 by Nokia Corporation <<
*
*/
/*! \page UsbdevModule USB device Module
*
*
*- \subpage UsbdevModuleResources
*/
#ifndef PCASM
#include <asm/types.h>
#endif
#include "source/lms2012.h"
#include "source/am1808.h"
#define MODULE_NAME "usbdev_module"
#define DEVICE1_NAME USBDEV_DEVICE
static int ModuleInit(void);
static void ModuleExit(void);
#define __USE_POSIX
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#ifndef PCASM
#include <linux/hrtimer.h>
#include <linux/mm.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <linux/ioport.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/hid.h>
#include <linux/utsname.h>
#include <linux/device.h>
static struct fsg_common *fsg_common;
#include "computil.c" // The composite framework used as utility file
#include <../drivers/usb/gadget/gadget_chips.h>
#include <../drivers/usb/gadget/usbstring.c>
#include <../drivers/usb/gadget/config.c>
#include <../drivers/usb/gadget/epautoconf.c>
#include "f_mass_storage.c"
/*-------------------------------------------------------------------------*/
/*
* Kbuild is not very cooperative with respect to linking separately
* compiled library objects into one module. So for now we won't use
* separate compilation ... ensuring init/exit sections work to shrink
* the runtime footprint, and giving us at least some parts of what
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
*/
#include <../drivers/usb/gadget/g_zero.h>
#define MAX_EP_SIZE 1024
#define MAX_FULLSPEED_EP_SIZE 64
unsigned buflen = MAX_EP_SIZE ;
char usb_char_buffer_in[MAX_EP_SIZE];
char usb_full_buffer_in[MAX_FULLSPEED_EP_SIZE];
int usb_char_in_length = 0;
char usb_char_buffer_out[MAX_EP_SIZE];
char usb_full_buffer_out[MAX_FULLSPEED_EP_SIZE];
int usb_char_out_length = 0;
#define SHM_LENGTH (sizeof(UsbSpeedDefault))
#define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
static void *kmalloc_ptr;
#include "usb_function.c" // Specific USB functionality
/*-------------------------------------------------------------------------*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("The LEGO Group");
MODULE_DESCRIPTION(MODULE_NAME);
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME);
module_init(ModuleInit);
module_exit(ModuleExit);
#else
// Keep Eclipse happy
#endif
// USB main stuff
#define DRIVER_VERSION "31jan2011->"
#ifndef PCASM
module_param(buflen, uint, 0);
#else
// Keep Eclipse happy
#endif
static int loopdefault = 0;
#ifndef PCASM
module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
#else
// Keep Eclipse happy
#endif
#define DRIVER_VENDOR_NUM 0x0694 // LEGO Group
#define DRIVER_PRODUCT_NUM 0x0005 // No. 5 in a row
#define DEFAULT_AUTORESUME 0
/* If the optional "autoresume" mode is enabled, it provides good
* functional coverage for the "USBCV" test harness from USB-IF.
* It's always set if OTG mode is enabled.
*/
unsigned autoresume = DEFAULT_AUTORESUME;
module_param(autoresume, uint, S_IRUGO);
#ifndef PCASM
MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
#else
// Keep Eclipse happy
#endif
/*-------------------------------------------------------------------------*/
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = 0xEF,
.bDeviceSubClass = 2,
.bDeviceProtocol = 1,
/*.bMaxPacketSize0 = f(hardware) */
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bNumConfigurations = 1,
};
#ifdef CONFIG_USB_OTG
struct usb_otg_descriptor otg_descriptor = {
.bLength = sizeof otg_descriptor,
.bDescriptorType = USB_DT_OTG,
/* REVISIT SRP-only hardware is possible, although
* it would not be called "OTG" ...
*/
.bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
};
const struct usb_descriptor_header *otg_desc[] = {
(struct usb_descriptor_header *) &otg_descriptor,
NULL,
};
#endif
/* string IDs are assigned dynamically */
#define STRING_MANUFACTURER_IDX 0
#define STRING_PRODUCT_IDX 1
#define STRING_SERIAL_IDX 2
static char manufacturer[] = "LEGO Group";
static char serial[] = "123456789ABC ";
static char longname[] = "EV3 brick ";
static struct usb_string strings_dev[3] = {
[STRING_MANUFACTURER_IDX].s = manufacturer,
[STRING_PRODUCT_IDX].s = longname,
[STRING_SERIAL_IDX].s = serial
};
static struct usb_gadget_strings stringtab_dev = {
.language = 0x0409, /* en-us */
.strings = strings_dev,
};
static struct usb_gadget_strings *dev_strings[] = {
&stringtab_dev,
NULL,
};
/*-------------------------------------------------------------------------*/
struct usb_request *alloc_ep_req(struct usb_ep *ep)
{
struct usb_request *req;
req = usb_ep_alloc_request(ep, GFP_ATOMIC);
if (req) {
req->length = buflen;
req->buf = kmalloc(buflen, GFP_ATOMIC);
if (!req->buf) {
usb_ep_free_request(ep, req);
req = NULL;
}
}
return req;
}
void free_ep_req(struct usb_ep *ep, struct usb_request *req)
{
kfree(req->buf);
usb_ep_free_request(ep, req);
}
static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
{
int value;
if (ep->driver_data) {
value = usb_ep_disable(ep);
if (value < 0)
DBG(cdev, "disable %s --> %d\n",
ep->name, value);
ep->driver_data = NULL;
}
}
void disable_endpoints(struct usb_composite_dev *cdev,
struct usb_ep *in, struct usb_ep *out)
{
disable_ep(cdev, in);
disable_ep(cdev, out);
}
/*-------------------------------------------------------------------------*/
static struct timer_list autoresume_timer;
static void zero_autoresume(unsigned long _c)
{
struct usb_composite_dev *cdev = (void *)_c;
struct usb_gadget *g = cdev->gadget;
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("zero_autoresume\n\r");
#endif
/* unconfigured devices can't issue wakeups */
if (!cdev->config)
return;
/* Normally the host would be woken up for something
* more significant than just a timer firing; likely
* because of some direct user request.
*/
if (g->speed != USB_SPEED_UNKNOWN) {
int status = usb_gadget_wakeup(g);
INFO(cdev, "%s --> %d\n", __func__, status);
}
}
static void zero_suspend(struct usb_composite_dev *cdev)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("zero_suspend\n\r");
#endif
if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
return;
if (autoresume) {
mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
} else
DBG(cdev, "%s\n", __func__);
}
static void zero_resume(struct usb_composite_dev *cdev)
{
DBG(cdev, "%s\n", __func__);
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("zero_resume\n\r");
#endif
del_timer(&autoresume_timer);
}
/*-------------------------------------------------------------------------*/
static int msg_bind(struct usb_composite_dev *cdev);
static void msg_bind2(struct usb_composite_dev *cdev);
static int zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int id;
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/
id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_MANUFACTURER_IDX].id = id;
device_desc.iManufacturer = id;
id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_PRODUCT_IDX].id = id;
device_desc.iProduct = id;
id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
id = msg_bind(cdev);
if (id < 0)
return id;
setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
rudolf_add(cdev, autoresume != 0);
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
else {
/* gadget zero is so simple (for now, no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
* so just warn about unrcognized controllers -- don't panic.
*
* things like configuration and altsetting numbering
* can need hardware-specific attention though.
*/
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x9999);
}
msg_bind2(cdev);
return 0;
}
static int zero_unbind(struct usb_composite_dev *cdev)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("zero_unbind\n\r");
#endif
del_timer_sync(&autoresume_timer);
return 0;
}
static struct usb_composite_driver zero_driver = {
.name = "zero",
.dev = &device_desc,
.strings = dev_strings,
.bind = zero_bind,
.unbind = zero_unbind,
.suspend = zero_suspend,
.resume = zero_resume,
};
static int dUsbInit(void)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("dUsbInit\n\r");
#endif
UsbSpeed.Speed = FULL_SPEED; // default to FULL_SPEED if not connected to a HIGH-SPEED
(*pUsbSpeed).Speed = FULL_SPEED; // HOST. If not connected to HIGH-SPEED we assume we're
// wanting (or at least doing) Daisy Chain
return usb_composite_register(&zero_driver);
}
static void dUsbExit(void)
{
usb_composite_unregister(&zero_driver);
}
// DEVICE1 char device stuff ********************************************************************
static ssize_t Device1Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
{
// Write data for the HOST to poll - Stuff sent to the HOST
int BytesWritten = 0;
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("Device1Write - usb_char_in_length = %d\n", usb_char_in_length);
#endif
if (usb_char_in_length == 0) // ready for more
{ // else wait in USER layer
BytesWritten = Count;
copy_from_user(usb_char_buffer_in, Buffer, BytesWritten);
usb_char_in_length = BytesWritten;
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("WR = %d, %d -- ", usb_char_buffer_in[2], usb_char_buffer_in[3]);
#endif
if(USB_DATA_PENDING == input_state)
{
// Already we've a failed tx (HOST part starwing??
input_state = USB_DATA_READY;
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("DATA_PENDING SECOND time and reset!! in Device1Write\n\r");
#endif
}
if(USB_DATA_READY == input_state)
{
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("USB_DATA_READY in Device1Write\n\r");
#endif
input_state = USB_DATA_BUSY;
write_data_to_the_host(save_in_ep, save_in_req);
usb_req_arm(save_in_ep, save_in_req); // new request
}
else
{
input_state = USB_DATA_PENDING;
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("DATA_PENDING in Device1Write\n\r");
#endif
}
}
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("usbdev %d written\n\r", BytesWritten);
#endif
return (BytesWritten); // Zero means USB was not ready yet
}
static ssize_t Device1Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
{
// Read the bits'n'bytes from the HOST
int BytesRead = 0;
if (usb_char_out_length > 0) // Something to look at
{
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("Some bytes to READ?\n\r");
#endif
copy_to_user(Buffer, usb_char_buffer_out, Count);
BytesRead = usb_char_out_length;
usb_char_out_length = 0;
}
return (BytesRead);
}
static int Device1Mmap(struct file *filp, struct vm_area_struct *vma)
{
int ret;
ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((void*)((unsigned long)pUsbSpeed)) >> PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
if (ret != 0)
{
ret = -EAGAIN;
}
return (ret);
}
#define FEED_DATA _IOC(_IOC_WRITE, 't', 108, 1024)
static int Device1Ioctl(struct inode *pNode, struct file *File, unsigned int Request, unsigned long Pointer)
{
if (Request != FEED_DATA)
return -EINVAL;
copy_from_user(usb_char_buffer_out,(void*)Pointer,1024);
usb_char_out_length = 1024;
return 0;
}
static const struct file_operations Device1Entries =
{
.owner = THIS_MODULE,
.read = Device1Read,
.write = Device1Write,
.mmap = Device1Mmap,
.ioctl = Device1Ioctl
};
static struct miscdevice Device1 =
{
MISC_DYNAMIC_MINOR,
DEVICE1_NAME,
&Device1Entries
};
static int Device1Init(void)
{
int Result = -1;
UWORD *pTemp;
int i;
Result = misc_register(&Device1);
if (Result)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk(" %s device register failed\n",DEVICE1_NAME);
#endif
}
else
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk(" %s device register OK\n",DEVICE1_NAME);
#endif
// allocate kernel shared memory for DaisyChain Speed info
if ((kmalloc_ptr = kmalloc((NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) != NULL)
{
pTemp = (UWORD*)((((unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
for (i = 0; i < NPAGES * PAGE_SIZE; i += PAGE_SIZE)
{
SetPageReserved(virt_to_page(((unsigned long)pTemp) + i));
}
pUsbSpeed = (USB_SPEED*)pTemp;
}
dUsbInit();
}
return (Result);
}
static void Device1Exit(void)
{
int i;
UWORD *pTemp = (UWORD*)pUsbSpeed;
dUsbExit();
pUsbSpeed = &UsbSpeedDefault;
for (i = 0; i < NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
{
ClearPageReserved(virt_to_page(((unsigned long)pTemp) + i));
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk(" %s memory page %d unmapped\n",DEVICE1_NAME,i);
#endif
}
kfree(kmalloc_ptr);
misc_deregister(&Device1);
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk(" %s device unregistered\n",DEVICE1_NAME);
#endif
}
// MODULE *********************************************************************
char *HostStr; // Used for HostName - or NOT used at all
char *SerialStr; // Used for Serial number (I.e. BT number)
module_param (HostStr, charp, 0);
module_param (SerialStr, charp, 0);
static int ModuleInit(void)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("%s Module init started\r\n",MODULE_NAME);
#endif
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("This is DEFAULT NAME: %s\n\r", longname);
#endif
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("\n\rThis is the HostStr: %s\n\r", HostStr);
#endif
strcpy(longname, HostStr);
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("\n\rThis is the INSMODed NAME: %s\n\r", longname);
#endif
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("\n\rThis is the DEFAULT SerialNumber: %s\n\r", serial);
#endif
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("\n\rThis is the SerialStr: %s\n\r", SerialStr);
#endif
strcpy(serial, SerialStr);
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("\n\rThis is the INSMODed SerialNumber (BT mac): %s\n\r", serial);
#endif
Device1Init();
return (0);
}
static void ModuleExit(void)
{
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
printk("%s exit started\n",MODULE_NAME);
#endif
Device1Exit();
}
// MSG
/****************************** Configurations ******************************/
static struct fsg_module_parameters fsg_mod_data = {
.stall = 1
};
FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
/****************************** Gadget Bind ******************************/
static void msg_bind2(struct usb_composite_dev *cdev)
{
fsg_common_put(fsg_common);
}
static int msg_bind(struct usb_composite_dev *cdev)
{
/* set up mass storage function */
fsg_common = fsg_common_from_params(0, cdev, &fsg_mod_data);
if (IS_ERR(fsg_common)) {
return PTR_ERR(fsg_common);
}
return 0;
}
static int msg_config(struct usb_configuration *c) {
return fsg_add(c->cdev, c, fsg_common);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +0,0 @@
/*
* USB device controllers have lots of quirks. Use these macros in
* gadget drivers or other code that needs to deal with them, and which
* autoconfigures instead of using early binding to the hardware.
*
* This SHOULD eventually work like the ARM mach_is_*() stuff, driven by
* some config file that gets updated as new hardware is supported.
* (And avoiding all runtime comparisons in typical one-choice configs!)
*
* NOTE: some of these controller drivers may not be available yet.
* Some are available on 2.4 kernels; several are available, but not
* yet pushed in the 2.6 mainline tree.
*/
#ifndef __GADGET_CHIPS_H
#define __GADGET_CHIPS_H
#ifdef CONFIG_USB_GADGET_NET2280
#define gadget_is_net2280(g) !strcmp("net2280", (g)->name)
#else
#define gadget_is_net2280(g) 0
#endif
#ifdef CONFIG_USB_GADGET_AMD5536UDC
#define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name)
#else
#define gadget_is_amd5536udc(g) 0
#endif
#ifdef CONFIG_USB_GADGET_DUMMY_HCD
#define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name)
#else
#define gadget_is_dummy(g) 0
#endif
#ifdef CONFIG_USB_GADGET_PXA25X
#define gadget_is_pxa(g) !strcmp("pxa25x_udc", (g)->name)
#else
#define gadget_is_pxa(g) 0
#endif
#ifdef CONFIG_USB_GADGET_GOKU
#define gadget_is_goku(g) !strcmp("goku_udc", (g)->name)
#else
#define gadget_is_goku(g) 0
#endif
/* SH3 UDC -- not yet ported 2.4 --> 2.6 */
#ifdef CONFIG_USB_GADGET_SUPERH
#define gadget_is_sh(g) !strcmp("sh_udc", (g)->name)
#else
#define gadget_is_sh(g) 0
#endif
/* not yet stable on 2.6 (would help "original Zaurus") */
#ifdef CONFIG_USB_GADGET_SA1100
#define gadget_is_sa1100(g) !strcmp("sa1100_udc", (g)->name)
#else
#define gadget_is_sa1100(g) 0
#endif
#ifdef CONFIG_USB_GADGET_LH7A40X
#define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name)
#else
#define gadget_is_lh7a40x(g) 0
#endif
/* handhelds.org tree (?) */
#ifdef CONFIG_USB_GADGET_MQ11XX
#define gadget_is_mq11xx(g) !strcmp("mq11xx_udc", (g)->name)
#else
#define gadget_is_mq11xx(g) 0
#endif
#ifdef CONFIG_USB_GADGET_OMAP
#define gadget_is_omap(g) !strcmp("omap_udc", (g)->name)
#else
#define gadget_is_omap(g) 0
#endif
/* not yet ported 2.4 --> 2.6 */
#ifdef CONFIG_USB_GADGET_N9604
#define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name)
#else
#define gadget_is_n9604(g) 0
#endif
/* various unstable versions available */
#ifdef CONFIG_USB_GADGET_PXA27X
#define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name)
#else
#define gadget_is_pxa27x(g) 0
#endif
#ifdef CONFIG_USB_GADGET_ATMEL_USBA
#define gadget_is_atmel_usba(g) !strcmp("atmel_usba_udc", (g)->name)
#else
#define gadget_is_atmel_usba(g) 0
#endif
#ifdef CONFIG_USB_GADGET_S3C2410
#define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name)
#else
#define gadget_is_s3c2410(g) 0
#endif
#ifdef CONFIG_USB_GADGET_AT91
#define gadget_is_at91(g) !strcmp("at91_udc", (g)->name)
#else
#define gadget_is_at91(g) 0
#endif
#ifdef CONFIG_USB_GADGET_IMX
#define gadget_is_imx(g) !strcmp("imx_udc", (g)->name)
#else
#define gadget_is_imx(g) 0
#endif
#ifdef CONFIG_USB_GADGET_FSL_USB2
#define gadget_is_fsl_usb2(g) !strcmp("fsl-usb2-udc", (g)->name)
#else
#define gadget_is_fsl_usb2(g) 0
#endif
/* Mentor high speed function controller */
/* from Montavista kernel (?) */
#ifdef CONFIG_USB_GADGET_MUSBHSFC
#define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name)
#else
#define gadget_is_musbhsfc(g) 0
#endif
/* Mentor high speed "dual role" controller, in peripheral role */
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
#define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name)
#else
#define gadget_is_musbhdrc(g) 0
#endif
#ifdef CONFIG_USB_GADGET_LANGWELL
#define gadget_is_langwell(g) (!strcmp("langwell_udc", (g)->name))
#else
#define gadget_is_langwell(g) 0
#endif
/* from Montavista kernel (?) */
#ifdef CONFIG_USB_GADGET_MPC8272
#define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name)
#else
#define gadget_is_mpc8272(g) 0
#endif
#ifdef CONFIG_USB_GADGET_M66592
#define gadget_is_m66592(g) !strcmp("m66592_udc", (g)->name)
#else
#define gadget_is_m66592(g) 0
#endif
/* Freescale CPM/QE UDC SUPPORT */
#ifdef CONFIG_USB_GADGET_FSL_QE
#define gadget_is_fsl_qe(g) !strcmp("fsl_qe_udc", (g)->name)
#else
#define gadget_is_fsl_qe(g) 0
#endif
#ifdef CONFIG_USB_GADGET_CI13XXX
#define gadget_is_ci13xxx(g) (!strcmp("ci13xxx_udc", (g)->name))
#else
#define gadget_is_ci13xxx(g) 0
#endif
// CONFIG_USB_GADGET_SX2
// CONFIG_USB_GADGET_AU1X00
// ...
#ifdef CONFIG_USB_GADGET_R8A66597
#define gadget_is_r8a66597(g) !strcmp("r8a66597_udc", (g)->name)
#else
#define gadget_is_r8a66597(g) 0
#endif
/**
* usb_gadget_controller_number - support bcdDevice id convention
* @gadget: the controller being driven
*
* Return a 2-digit BCD value associated with the peripheral controller,
* suitable for use as part of a bcdDevice value, or a negative error code.
*
* NOTE: this convention is purely optional, and has no meaning in terms of
* any USB specification. If you want to use a different convention in your
* gadget driver firmware -- maybe a more formal revision ID -- feel free.
*
* Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
* to change their behavior accordingly. For example it might help avoiding
* some chip bug.
*/
static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
{
if (gadget_is_net2280(gadget))
return 0x01;
else if (gadget_is_dummy(gadget))
return 0x02;
else if (gadget_is_pxa(gadget))
return 0x03;
else if (gadget_is_sh(gadget))
return 0x04;
else if (gadget_is_sa1100(gadget))
return 0x05;
else if (gadget_is_goku(gadget))
return 0x06;
else if (gadget_is_mq11xx(gadget))
return 0x07;
else if (gadget_is_omap(gadget))
return 0x08;
else if (gadget_is_lh7a40x(gadget))
return 0x09;
else if (gadget_is_n9604(gadget))
return 0x10;
else if (gadget_is_pxa27x(gadget))
return 0x11;
else if (gadget_is_s3c2410(gadget))
return 0x12;
else if (gadget_is_at91(gadget))
return 0x13;
else if (gadget_is_imx(gadget))
return 0x14;
else if (gadget_is_musbhsfc(gadget))
return 0x15;
else if (gadget_is_musbhdrc(gadget))
return 0x16;
else if (gadget_is_mpc8272(gadget))
return 0x17;
else if (gadget_is_atmel_usba(gadget))
return 0x18;
else if (gadget_is_fsl_usb2(gadget))
return 0x19;
else if (gadget_is_amd5536udc(gadget))
return 0x20;
else if (gadget_is_m66592(gadget))
return 0x21;
else if (gadget_is_fsl_qe(gadget))
return 0x22;
else if (gadget_is_ci13xxx(gadget))
return 0x23;
else if (gadget_is_langwell(gadget))
return 0x24;
else if (gadget_is_r8a66597(gadget))
return 0x25;
return -ENOENT;
}
/**
* gadget_supports_altsettings - return true if altsettings work
* @gadget: the gadget in question
*/
static inline bool gadget_supports_altsettings(struct usb_gadget *gadget)
{
/* PXA 21x/25x/26x has no altsettings at all */
if (gadget_is_pxa(gadget))
return false;
/* PXA 27x and 3xx have *broken* altsetting support */
if (gadget_is_pxa27x(gadget))
return false;
/* SH3 hardware just doesn't do altsettings */
if (gadget_is_sh(gadget))
return false;
/* Everything else is *presumably* fine ... */
return true;
}
#endif /* __GADGET_CHIPS_H */

View File

@ -1,249 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef AM1808_H_
#define AM1808_H_
#ifndef PCASM
#include <mach/da8xx.h>
#else
#define __iomem
#endif
enum
{
GP0_0,GP0_1,GP0_2,GP0_3,GP0_4,GP0_5,GP0_6,GP0_7,GP0_8,GP0_9,GP0_10,GP0_11,GP0_12,GP0_13,GP0_14,GP0_15,
GP1_0,GP1_1,GP1_2,GP1_3,GP1_4,GP1_5,GP1_6,GP1_7,GP1_8,GP1_9,GP1_10,GP1_11,GP1_12,GP1_13,GP1_14,GP1_15,
GP2_0,GP2_1,GP2_2,GP2_3,GP2_4,GP2_5,GP2_6,GP2_7,GP2_8,GP2_9,GP2_10,GP2_11,GP2_12,GP2_13,GP2_14,GP2_15,
GP3_0,GP3_1,GP3_2,GP3_3,GP3_4,GP3_5,GP3_6,GP3_7,GP3_8,GP3_9,GP3_10,GP3_11,GP3_12,GP3_13,GP3_14,GP3_15,
GP4_0,GP4_1,GP4_2,GP4_3,GP4_4,GP4_5,GP4_6,GP4_7,GP4_8,GP4_9,GP4_10,GP4_11,GP4_12,GP4_13,GP4_14,GP4_15,
GP5_0,GP5_1,GP5_2,GP5_3,GP5_4,GP5_5,GP5_6,GP5_7,GP5_8,GP5_9,GP5_10,GP5_11,GP5_12,GP5_13,GP5_14,GP5_15,
GP6_0,GP6_1,GP6_2,GP6_3,GP6_4,GP6_5,GP6_6,GP6_7,GP6_8,GP6_9,GP6_10,GP6_11,GP6_12,GP6_13,GP6_14,GP6_15,
GP7_0,GP7_1,GP7_2,GP7_3,GP7_4,GP7_5,GP7_6,GP7_7,GP7_8,GP7_9,GP7_10,GP7_11,GP7_12,GP7_13,GP7_14,GP7_15,
GP8_0,GP8_1,GP8_2,GP8_3,GP8_4,GP8_5,GP8_6,GP8_7,GP8_8,GP8_9,GP8_10,GP8_11,GP8_12,GP8_13,GP8_14,GP8_15,
NO_OF_GPIOS,
UART0_TXD,UART0_RXD,UART1_TXD,UART1_RXD,
SPI0_MOSI,SPI0_MISO,SPI0_SCL,SPI0_CS,
SPI1_MOSI,SPI1_MISO,SPI1_SCL,SPI1_CS,
EPWM1A,EPWM1B,APWM0,APWM1,EPWM0B,AXR3,AXR4
};
typedef struct
{
int Pin;
u16 MuxReg;
u32 Mask;
u32 Mode;
}
MRM;
MRM MuxRegMap[] =
{ // Pin MuxReg Mask Mode
{ GP0_1 , 1, 0xF0FFFFFF, 0x08000000 },
{ GP0_2 , 1, 0xFF0FFFFF, 0x00800000 },
{ GP0_3 , 1, 0xFFF0FFFF, 0x00080000 },
{ GP0_4 , 1, 0xFFFF0FFF, 0x00008000 },
{ GP0_5 , 1, 0xFFFFF0FF, 0x00000800 },
{ GP0_6 , 1, 0xFFFFFF0F, 0x00000080 },
{ GP0_7 , 1, 0xFFFFFFF0, 0x00000008 },
{ GP0_11, 0, 0xFFF0FFFF, 0x00080000 },
{ GP0_12, 0, 0xFFFF0FFF, 0x00008000 },
{ GP0_13, 0, 0xFFFFF0FF, 0x00000800 },
{ GP0_14, 0, 0xFFFFFF0F, 0x00000080 },
{ GP0_15, 0, 0xFFFFFFF0, 0x00000008 },
{ GP1_0 , 4, 0x0FFFFFFF, 0x80000000 },
{ GP1_8 , 3, 0xFFFFFFF0, 0x00000004 },
{ GP1_9, 2, 0xF0FFFFFF, 0x04000000 },
{ GP1_10, 2, 0xFF0FFFFF, 0x00400000 },
{ GP1_11, 2, 0xFFF0FFFF, 0x00040000 },
{ GP1_12, 2, 0xFFFF0FFF, 0x00004000 },
{ GP1_13, 2, 0xFFFFF0FF, 0x00000400 },
{ GP1_14, 2, 0xFFFFFF0F, 0x00000040 },
{ GP1_15, 2, 0xFFFFFFF0, 0x00000008 },
{ GP2_0, 6, 0x0FFFFFFF, 0x80000000 },
{ GP2_1, 6, 0xF0FFFFFF, 0x08000000 },
{ GP2_2, 6, 0xFF0FFFFF, 0x00800000 },
{ GP2_3, 6, 0xFFF0FFFF, 0x00080000 },
{ GP2_4, 6, 0xFFFF0FFF, 0x00008000 },
{ GP2_5, 6, 0xFFFFF0FF, 0x00000800 },
{ GP2_6, 6, 0xFFFFFF0F, 0x00000080 },
{ GP2_7, 6, 0xFFFFFFF0, 0x00000008 },
{ GP2_8, 5, 0x0FFFFFFF, 0x80000000 },
{ GP2_9, 5, 0xF0FFFFFF, 0x08000000 },
{ GP2_10, 5, 0xFF0FFFFF, 0x00800000 },
{ GP2_11, 5, 0xFFF0FFFF, 0x00080000 },
{ GP2_12, 5, 0xFFFF0FFF, 0x00008000 },
{ GP2_13, 5, 0xFFFFF0FF, 0x00000800 },
{ GP3_0, 8, 0x0FFFFFFF, 0x80000000 },
{ GP3_1 , 8, 0xF0FFFFFF, 0x08000000 },
{ GP3_2, 8, 0xFF0FFFFF, 0x00800000 },
{ GP3_3, 8, 0xFFF0FFFF, 0x00080000 },
{ GP3_4, 8, 0xFFFF0FFF, 0x00008000 },
{ GP3_5, 8, 0xFFFFF0FF, 0x00000800 },
{ GP3_6, 8, 0xFFFFFF0F, 0x00000080 },
{ GP3_7, 8, 0xFFFFFFF0, 0x00000008 },
{ GP3_8, 7, 0x0FFFFFFF, 0x80000000 },
{ GP3_9, 7, 0xF0FFFFFF, 0x08000000 },
{ GP3_10, 7, 0xFF0FFFFF, 0x00800000 },
{ GP3_11, 7, 0xFFF0FFFF, 0x00080000 },
{ GP3_12, 7, 0xFFFF0FFF, 0x00008000 },
{ GP3_13, 7, 0xFFFFF0FF, 0x00000800 },
{ GP3_14, 7, 0xFFFFFF0F, 0x00000080 },
{ GP3_15, 7, 0xFFFFFFF0, 0x00000008 },
{ GP4_1, 10, 0xF0FFFFFF, 0x08000000 },
{ GP4_8, 9, 0x0FFFFFFF, 0x80000000 },
{ GP4_9, 9, 0xF0FFFFFF, 0x08000000 },
{ GP4_10, 9, 0xFF0FFFFF, 0x00800000 },
{ GP4_12, 9, 0xFFFF0FFF, 0x00008000 },
{ GP4_14, 9, 0xFFFFFF0F, 0x00000080 },
{ GP5_0, 12, 0x0FFFFFFF, 0x80000000 },
{ GP5_1, 12, 0xF0FFFFFF, 0x08000000 },
{ GP5_2, 12, 0xFF0FFFFF, 0x00800000 },
{ GP5_3, 12, 0xFFF0FFFF, 0x00080000 },
{ GP5_4, 12, 0xFFFF0FFF, 0x00008000 },
{ GP5_5, 12, 0xFFFFF0FF, 0x00000800 },
{ GP5_6, 12, 0xFFFFFF0F, 0x00000080 },
{ GP5_7, 12, 0xFFFFFFF0, 0x00000008 },
{ GP5_8, 11, 0x0FFFFFFF, 0x80000000 },
{ GP5_9, 11, 0xF0FFFFFF, 0x08000000 },
{ GP5_10, 11, 0xFF0FFFFF, 0x00800000 },
{ GP5_11, 11, 0xFFF0FFFF, 0x00080000 },
{ GP5_12, 11, 0xFFFF0FFF, 0x00008000 },
{ GP5_13, 11, 0xFFFFF0FF, 0x00000800 },
{ GP5_14, 11, 0xFFFFFF0F, 0x00000080 },
{ GP5_15, 11, 0xFFFFFFF0, 0x00000008 },
{ GP6_0 , 19, 0xF0FFFFFF, 0x08000000 },
{ GP6_1, 19, 0xFF0FFFFF, 0x00800000 },
{ GP6_2, 19, 0xFFF0FFFF, 0x00080000 },
{ GP6_3, 19, 0xFFFF0FFF, 0x00008000 },
{ GP6_4, 19, 0xFFFFF0FF, 0x00000800 },
{ GP6_5, 16, 0xFFFFFF0F, 0x00000080 },
{ GP6_6, 14, 0xFFFFFF0F, 0x00000080 },
{ GP6_7, 14, 0xFFFFFFF0, 0x00000008 },
{ GP6_8, 13, 0x0FFFFFFF, 0x80000000 },
{ GP6_9, 13, 0xF0FFFFFF, 0x08000000 },
{ GP6_10, 13, 0xFF0FFFFF, 0x00800000 },
{ GP6_11, 13, 0xFFF0FFFF, 0x00080000 },
{ GP6_12, 13, 0xFFFF0FFF, 0x00008000 },
{ GP6_13, 13, 0xFFFFF0FF, 0x00000800 },
{ GP6_14, 13, 0xFFFFFF0F, 0x00000080 },
{ GP6_15, 13, 0xFFFFFFF0, 0x00000008 },
{ GP7_4, 17, 0xFF0FFFFF, 0x00800000 },
{ GP7_8, 17, 0xFFFFFF0F, 0x00000080 },
{ GP7_9, 17, 0xFFFFFFF0, 0x00000008 },
{ GP7_10, 16, 0x0FFFFFFF, 0x80000000 },
{ GP7_11, 16, 0xF0FFFFFF, 0x08000000 },
{ GP7_12, 16, 0xFF0FFFFF, 0x00800000 },
{ GP7_13, 16, 0xFFF0FFFF, 0x00080000 },
{ GP7_14, 16, 0xFFFF0FFF, 0x00008000 },
{ GP7_15, 16, 0xFFFFF0FF, 0x00000800 },
{ GP8_2 , 3 , 0xF0FFFFFF, 0x04000000 },
{ GP8_3 , 3 , 0xFF0FFFFF, 0x00400000 },
{ GP8_5 , 3 , 0xFFFF0FFF, 0x00004000 },
{ GP8_6 , 3 , 0xFFFFF0FF, 0x00000400 },
{ GP8_8 , 19, 0xFFFFFF0F, 0x00000080 },
{ GP8_9 , 19, 0xFFFFFFF0, 0x00000008 },
{ GP8_10, 18, 0x0FFFFFFF, 0x80000000 },
{ GP8_11, 18, 0xF0FFFFFF, 0x08000000 },
{ GP8_12, 18, 0xFF0FFFFF, 0x00800000 },
{ GP8_13, 18, 0xFFF0FFFF, 0x00080000 },
{ GP8_14, 18, 0xFFFF0FFF, 0x00008000 },
{ GP8_15, 18, 0xFFFFF0FF, 0x00000800 },
{ UART0_TXD, 3, 0xFF0FFFFF, 0x00200000 },
{ UART0_RXD, 3, 0xFFF0FFFF, 0x00020000 },
{ UART1_TXD, 4, 0x0FFFFFFF, 0x20000000 },
{ UART1_RXD, 4, 0xF0FFFFFF, 0x02000000 },
{ SPI0_MOSI, 3, 0xFFFF0FFF, 0x00001000 },
{ SPI0_MISO, 3, 0xFFFFF0FF, 0x00000100 },
{ SPI0_SCL, 3, 0xFFFFFFF0, 0x00000001 },
{ SPI0_CS, 3, 0xF0FFFFFF, 0x01000000 },
{ SPI1_MOSI, 5, 0xFF0FFFFF, 0x00100000 },
{ SPI1_MISO, 5, 0xFFF0FFFF, 0x00010000 },
{ SPI1_SCL, 5, 0xFFFFF0FF, 0x00000100 },
{ SPI1_CS, 5, 0xFFFF0FFF, 0x00008000 },
{ EPWM1A, 5, 0xFFFFFFF0, 0x00000002 },
{ EPWM1B, 5, 0xFFFFFF0F, 0x00000020 },
{ APWM0, 2, 0x0FFFFFFF, 0x20000000 },
{ APWM1, 1, 0x0FFFFFFF, 0x40000000 },
{ EPWM0B, 3, 0xFFFFFF0F, 0x00000020 },
{ AXR3, 2, 0xFFF0FFFF, 0x00010000 },
{ AXR4, 2, 0xFFFF0FFF, 0x00001000 },
{-1 }
};
typedef struct gpio_controller *__iomem GPIOC;
typedef struct
{
int Pin; // GPIO pin number
GPIOC pGpio; // GPIO bank base address
u32 Mask; // GPIO pin mask
}
INPIN;
#define REGUnlock {\
iowrite32(0x83E70B13,da8xx_syscfg0_base + 0x38);\
iowrite32(0x95A4F1E0,da8xx_syscfg0_base + 0x3C);\
}
#define REGLock {\
iowrite32(0x00000000,da8xx_syscfg0_base + 0x38);\
iowrite32(0x00000000,da8xx_syscfg0_base + 0x3C);\
}
#else
extern MRM MuxRegMap[];
#endif /* AM1808_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef C_BRANCH_H_
#define C_BRANCH_H_
void cBranchJr(void);
void cBranchJrFalse(void);
void cBranchJrTrue(void);
void cBranchJrNan(void);
void cBranchJrLt8(void);
void cBranchJrLt16(void);
void cBranchJrLt32(void);
void cBranchJrLtF(void);
void cBranchJrGt8(void);
void cBranchJrGt16(void);
void cBranchJrGt32(void);
void cBranchJrGtF(void);
void cBranchJrLtEq8(void);
void cBranchJrLtEq16(void);
void cBranchJrLtEq32(void);
void cBranchJrLtEqF(void);
void cBranchJrGtEq8(void);
void cBranchJrGtEq16(void);
void cBranchJrGtEq32(void);
void cBranchJrGtEqF(void);
void cBranchJrEq8(void);
void cBranchJrEq16(void);
void cBranchJrEq32(void);
void cBranchJrEqF(void);
void cBranchJrNEq8(void);
void cBranchJrNEq16(void);
void cBranchJrNEq32(void);
void cBranchJrNEqF(void);
#endif /* C_BRANCH_H_ */

View File

@ -1,81 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef C_COMPARE_H_
#define C_COMPARE_H_
void cCompareLt8(void);
void cCompareLt16(void);
void cCompareLt32(void);
void cCompareLtF(void);
void cCompareGt8(void);
void cCompareGt16(void);
void cCompareGt32(void);
void cCompareGtF(void);
void cCompareEq8(void);
void cCompareEq16(void);
void cCompareEq32(void);
void cCompareEqF(void);
void cCompareNEq8(void);
void cCompareNEq16(void);
void cCompareNEq32(void);
void cCompareNEqF(void);
void cCompareLtEq8(void);
void cCompareLtEq16(void);
void cCompareLtEq32(void);
void cCompareLtEqF(void);
void cCompareGtEq8(void);
void cCompareGtEq16(void);
void cCompareGtEq32(void);
void cCompareGtEqF(void);
void cCompareSelect8(void);
void cCompareSelect16(void);
void cCompareSelect32(void);
void cCompareSelectF(void);
#endif /* C_COMPARE_H_ */

View File

@ -1,88 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef C_MATH_H_
#define C_MATH_H_
#define DegToRad(D) (D * 0.0174532925)
#define RadToDeg(R) (R * 57.2957795)
void cMathAdd8(void);
void cMathAdd16(void);
void cMathAdd32(void);
void cMathAddF(void);
void cMathSub8(void);
void cMathSub16(void);
void cMathSub32(void);
void cMathSubF(void);
void cMathMul8(void);
void cMathMul16(void);
void cMathMul32(void);
void cMathMulF(void);
void cMathDiv8(void);
void cMathDiv16(void);
void cMathDiv32(void);
void cMathDivF(void);
void cMathOr8(void);
void cMathOr16(void);
void cMathOr32(void);
void cMathAnd8(void);
void cMathAnd16(void);
void cMathAnd32(void);
void cMathXor8(void);
void cMathXor16(void);
void cMathXor32(void);
void cMathRl8(void);
void cMathRl16(void);
void cMathRl32(void);
void cMath(void);
#endif /* C_MATH_H_ */

View File

@ -1,76 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef C_MOVE_H_
#define C_MOVE_H_
void cMove8to8(void);
void cMove8to16(void);
void cMove8to32(void);
void cMove8toF(void);
void cMove16to8(void);
void cMove16to16(void);
void cMove16to32(void);
void cMove16toF(void);
void cMove32to8(void);
void cMove32to16(void);
void cMove32to32(void);
void cMove32toF(void);
void cMoveFto8(void);
void cMoveFto16(void);
void cMoveFto32(void);
void cMoveFtoF(void);
void cMoveInitBytes(void);
void cMoveRead8(void);
void cMoveRead16(void);
void cMoveRead32(void);
void cMoveReadF(void);
void cMoveWrite8(void);
void cMoveWrite16(void);
void cMoveWrite32(void);
void cMoveWriteF(void);
#endif /* C_MOVE_H_ */

View File

@ -1,38 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef C_TIMER_H_
#define C_TIMER_H_
#if (HARDWARE != SIMULATION)
ULONG cTimerGetuS(void);
ULONG cTimerGetmS(void);
#endif
void cTimerWait(void);
void cTimerReady(void);
void cTimerRead(void);
void cTimerReaduS(void);
#endif /* C_TIMER_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,195 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception, if other files instantiate templates or use macros or
* inline functions from this file, or you compile this file and link it with
* other works to produce a work based on this file, this file does not by itself
* cause the resulting work to be covered by the GNU General Public License.
* However the source code for this file must still be made available in accordance
* with section (3) of the GNU General Public License.
*
*/
#ifndef LMSTYPES_H_
#define LMSTYPES_H_
// BASIC DATA TYPES
#ifndef LEGO_SIMULATION
typedef unsigned char UBYTE; //!< Basic Type used to symbolise 8 bit unsigned values
typedef unsigned short UWORD; //!< Basic Type used to symbolise 16 bit unsigned values
typedef unsigned int ULONG; //!< Basic Type used to symbolise 32 bit unsigned values
typedef signed char SBYTE; //!< Basic Type used to symbolise 8 bit signed values
typedef signed short SWORD; //!< Basic Type used to symbolise 16 bit signed values
typedef signed int SLONG; //!< Basic Type used to symbolise 32 bit signed values
typedef float FLOAT; //!< Basic Type used to symbolise 32 bit floating point values
#define LFILE FILE
#else
#include <Base/BasicTypes.h>
#include <VMCalls.h>
typedef LEGO::UInt8 UBYTE; //!< Basic Type used to symbolise 8 bit unsigned values
typedef LEGO::UInt16 UWORD; //!< Basic Type used to symbolise 16 bit unsigned values
typedef unsigned long ULONG; //!< Basic Type used to symbolise 32 bit unsigned values
typedef LEGO::Int8 SBYTE; //!< Basic Type used to symbolise 8 bit signed values
typedef LEGO::Int16 SWORD; //!< Basic Type used to symbolise 16 bit signed values
typedef LEGO::Int32 SLONG; //!< Basic Type used to symbolise 32 bit signed values
typedef LEGO::Real32 FLOAT; //!< Basic Type used to symbolise 32 bit floating point values
#endif
// VM DATA TYPES
typedef SBYTE DATA8; //!< VM Type for 1 byte signed value
typedef SWORD DATA16; //!< VM Type for 2 byte signed value
typedef SLONG DATA32; //!< VM Type for 4 byte signed value
typedef FLOAT DATAF; //!< VM Type for 4 byte floating point value
// VM VARIABLE TYPES
typedef UBYTE VARDATA; //!< Variable base type
typedef UBYTE IMGDATA; //!< Image base type
typedef UWORD PRGID; //!< Program id type
typedef UWORD OBJID; //!< Object id type
typedef IMGDATA* IP; //!< Instruction pointer type
typedef VARDATA* LP; //!< Local variable pointer type
typedef VARDATA* GP; //!< global variable pointer type
typedef ULONG IMINDEX; //!< ImageData index type
typedef ULONG GBINDEX; //!< GlobalBytes index type
typedef ULONG LBINDEX; //!< LocalBytes index type
typedef UWORD TRIGGER; //!< TriggerCount type
typedef UBYTE PARS; //!< NoOfParameters type
typedef SLONG IMOFFS; //!< ImageData offset type
typedef DATA16 HANDLER; //!< Memory list index
/*! \page imagelayout Image Layout
* The image consists of three different components in this fixed order: imageheader, objectheaders and byte codes.
*
* The imageheader tells something about image version, filesize, no of objectheaders (objects) and no of global variable bytes.
*
*
* Objectheaders contains different informations depending on the nature of the object:
*
*- The VMTHREAD object (former TBC_TOPVI) \n
* - OffsetToInstructions tells were to find the corresponding byte codes (offset from image start) \n
* - OwnerObjectId must be zero \n
* - TriggerCount is used but must be zero \n
* - LocalBytes describes the number of bytes for local variables \n
*
*- The SUBCALL object (former TBC_VI and TBC_VI_ALIAS) \n
* - OffsetToInstructions tells were to find the corresponding byte codes (if alias this is equal to mother object) \n
* - OwnerObjectId must be zero \n
* - TriggerCount is used and must be one \n
* - LocalBytes describes the number of bytes for local variables \n
*
*- The BLOCK object (former CLUMP) \n
* - OffsetToInstructions tells were to find the corresponding byte codes (offset from image start) \n
* - OwnerObjectId is equal to object id it belongs to (not equal to zero) \n
* - TriggerCount is used to determine how many triggers needed before the BLOCK object is activated \n
* - LocalBytes must be zero (locals are defined in the owner object) \n
*
* Byte codes are described in a different section.
*
* Little Endian are used (addresses and data are represented with LSB on lowest address and MSB on highest address).
*
* Offset to instructions is number of bytes from start of image to start of object instructions.
*
* Index to global variables are byte based and counted from start of globals (zero based).
*
* Index to local variables are byte based and counted from start of object locals (zero based).
*
* Object ID's is not zero based - First object (VMTHEAD) is named 1.
*
*/
/*! \page imagelayout
*
* FILE layout (aligned)
*
*- IMGHEAD (aligned)
* - Sign (4 bytes)
* - ImageSize (4 bytes)
* - VersionInfo (2 bytes)
* - NumberOfObjects (2 bytes)
* - GlobalBytes (4 bytes)
*/
/*! \struct IMGHEAD
* Image header
*/
typedef struct
{
UBYTE Sign[4]; //!< Place holder for the file type identifier
IMINDEX ImageSize; //!< Image size
UWORD VersionInfo; //!< Version identifier
OBJID NumberOfObjects; //!< Total number of objects in image
GBINDEX GlobalBytes; //!< Number of bytes to allocate for global variables
}
IMGHEAD;
/*! \page imagelayout
*
*- OBJHEAD (aligned)
* - OffsetToInstructions (4 bytes)
* - OwnerObjectId (2 bytes)
* - TriggerCount (2 bytes)
* - LocalBytes (4 bytes)
*
*/
/*! \struct OBJHEAD
* Object header used for all types of objects (VMTHREAD, SUBCALL, BLOCK and ALIAS)
*/
typedef struct // Object header
{
IP OffsetToInstructions; //!< Offset to instructions from image start
OBJID OwnerObjectId; //!< Used by BLOCK's to hold the owner id
TRIGGER TriggerCount; //!< Used to determine how many triggers needed before the BLOCK object is activated
LBINDEX LocalBytes; //!< Number of bytes to allocate for local variables
}
OBJHEAD;
/*! \struct LABEL
* Label data hold information used for labels
*/
typedef struct
{
IMINDEX Addr; //!< Offset to breakpoint address from image start
}
LABEL;
#endif /* LMSTYPES_H_ */

View File

@ -1,56 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef VALIDATE_H_
#define VALIDATE_H_
RESULT cValidateInit(void);
RESULT cValidateExit(void);
RESULT cValidateDisassemble(IP pI,IMINDEX *pIndex,LABEL *pLabel);
RESULT cValidateProgram(PRGID PrgId,IP pI,LABEL *pLabel,DATA8 Disassemble);
typedef struct
{
//*****************************************************************************
// Validate Global variables
//*****************************************************************************
int Row;
IMINDEX ValidateErrorIndex;
}
VALIDATE_GLOBALS;
#ifndef LEGO_SIMULATION
extern VALIDATE_GLOBALS ValidateInstance;
#else
extern VALIDATE_GLOBALS * gValidateInstance;
#define ValidateInstance (*gValidateInstance)
void setValidateInstance(VALIDATE_GLOBALS * _Instance);
VALIDATE_GLOBALS * getValidateInstance();
#endif
#endif /* VALIDATE_H_ */

View File

@ -1,779 +0,0 @@
/*
* storage_common.c -- Common definitions for mass storage functionality
*
* Copyright (C) 2003-2008 Alan Stern
* Copyeight (C) 2009 Samsung Electronics
* Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This file requires the following identifiers used in USB strings to
* be defined (each of type pointer to char):
* - fsg_string_manufacturer -- name of the manufacturer
* - fsg_string_product -- name of the product
* - fsg_string_serial -- product's serial
* - fsg_string_config -- name of the configuration
* - fsg_string_interface -- name of the interface
* The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
* macro is defined prior to including this file.
*/
/*
* When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
* fsg_hs_intr_in_desc objects as well as
* FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
* macros are not defined.
*
* When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
* FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
* defined (as well as corresponding entries in string tables are
* missing) and FSG_STRING_INTERFACE has value of zero.
*
* When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
*/
/*
* When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included
* the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN
* characters rather then a pointer to void.
*/
#include <asm/unaligned.h>
/* Thanks to NetChip Technologies for donating this product ID.
*
* DO NOT REUSE THESE IDs with any other driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures. */
#define FSG_VENDOR_ID 0x0525 /* NetChip */
#define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */
/*-------------------------------------------------------------------------*/
#ifndef DEBUG
#undef VERBOSE_DEBUG
#undef DUMP_MSGS
#endif /* !DEBUG */
#ifdef VERBOSE_DEBUG
#define VLDBG LDBG
#else
#define VLDBG(lun, fmt, args...) do { } while (0)
#endif /* VERBOSE_DEBUG */
#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args)
#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args)
#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args)
/* Keep those macros in sync with thos in
* include/linux/ubs/composite.h or else GCC will complain. If they
* are identical (the same names of arguments, white spaces in the
* same places) GCC will allow redefinition otherwise (even if some
* white space is removed or added) warning will be issued. No
* checking if those symbols is defined is performed because warning
* is desired when those macros were defined by someone else to mean
* something else. */
#define DBG(d, fmt, args...) dev_dbg(&(d)->gadget->dev , fmt , ## args)
#define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev , fmt , ## args)
#define ERROR(d, fmt, args...) dev_err(&(d)->gadget->dev , fmt , ## args)
#define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args)
#define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev , fmt , ## args)
#ifdef DUMP_MSGS
# define dump_msg(fsg, /* const char * */ label, \
/* const u8 * */ buf, /* unsigned */ length) do { \
if (length < 512) { \
DBG(fsg, "%s, length %u:\n", label, length); \
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
16, 1, buf, length, 0); \
} \
} while (0)
# define dump_cdb(fsg) do { } while (0)
#else
# define dump_msg(fsg, /* const char * */ label, \
/* const u8 * */ buf, /* unsigned */ length) do { } while (0)
# ifdef VERBOSE_DEBUG
# define dump_cdb(fsg) \
print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \
16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \
# else
# define dump_cdb(fsg) do { } while (0)
# endif /* VERBOSE_DEBUG */
#endif /* DUMP_MSGS */
/*-------------------------------------------------------------------------*/
/* SCSI device types */
#define TYPE_DISK 0x00
#define TYPE_CDROM 0x05
/* USB protocol value = the transport method */
#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */
#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */
#define USB_PR_BULK 0x50 /* Bulk-only */
/* USB subclass value = the protocol encapsulation */
#define USB_SC_RBC 0x01 /* Reduced Block Commands (flash) */
#define USB_SC_8020 0x02 /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
#define USB_SC_QIC 0x03 /* QIC-157 (tape) */
#define USB_SC_UFI 0x04 /* UFI (floppy) */
#define USB_SC_8070 0x05 /* SFF-8070i (removable) */
#define USB_SC_SCSI 0x06 /* Transparent SCSI */
/* Bulk-only data structures */
/* Command Block Wrapper */
struct fsg_bulk_cb_wrap {
__le32 Signature; /* Contains 'USBC' */
u32 Tag; /* Unique per command id */
__le32 DataTransferLength; /* Size of the data */
u8 Flags; /* Direction in bit 7 */
u8 Lun; /* LUN (normally 0) */
u8 Length; /* Of the CDB, <= MAX_COMMAND_SIZE */
u8 CDB[16]; /* Command Data Block */
};
#define USB_BULK_CB_WRAP_LEN 31
#define USB_BULK_CB_SIG 0x43425355 /* Spells out USBC */
#define USB_BULK_IN_FLAG 0x80
/* Command Status Wrapper */
struct bulk_cs_wrap {
__le32 Signature; /* Should = 'USBS' */
u32 Tag; /* Same as original command */
__le32 Residue; /* Amount not transferred */
u8 Status; /* See below */
};
#define USB_BULK_CS_WRAP_LEN 13
#define USB_BULK_CS_SIG 0x53425355 /* Spells out 'USBS' */
#define USB_STATUS_PASS 0
#define USB_STATUS_FAIL 1
#define USB_STATUS_PHASE_ERROR 2
/* Bulk-only class specific requests */
#define USB_BULK_RESET_REQUEST 0xff
#define USB_BULK_GET_MAX_LUN_REQUEST 0xfe
/* CBI Interrupt data structure */
struct interrupt_data {
u8 bType;
u8 bValue;
};
#define CBI_INTERRUPT_DATA_LEN 2
/* CBI Accept Device-Specific Command request */
#define USB_CBI_ADSC_REQUEST 0x00
/* Length of a SCSI Command Data Block */
#define MAX_COMMAND_SIZE 16
/* SCSI commands that we recognize */
#define SC_FORMAT_UNIT 0x04
#define SC_INQUIRY 0x12
#define SC_MODE_SELECT_6 0x15
#define SC_MODE_SELECT_10 0x55
#define SC_MODE_SENSE_6 0x1a
#define SC_MODE_SENSE_10 0x5a
#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
#define SC_READ_6 0x08
#define SC_READ_10 0x28
#define SC_READ_12 0xa8
#define SC_READ_CAPACITY 0x25
#define SC_READ_FORMAT_CAPACITIES 0x23
#define SC_READ_HEADER 0x44
#define SC_READ_TOC 0x43
#define SC_RELEASE 0x17
#define SC_REQUEST_SENSE 0x03
#define SC_RESERVE 0x16
#define SC_SEND_DIAGNOSTIC 0x1d
#define SC_START_STOP_UNIT 0x1b
#define SC_SYNCHRONIZE_CACHE 0x35
#define SC_TEST_UNIT_READY 0x00
#define SC_VERIFY 0x2f
#define SC_WRITE_6 0x0a
#define SC_WRITE_10 0x2a
#define SC_WRITE_12 0xaa
/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
#define SS_NO_SENSE 0
#define SS_COMMUNICATION_FAILURE 0x040800
#define SS_INVALID_COMMAND 0x052000
#define SS_INVALID_FIELD_IN_CDB 0x052400
#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
#define SS_MEDIUM_NOT_PRESENT 0x023a00
#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
#define SS_RESET_OCCURRED 0x062900
#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
#define SS_UNRECOVERED_READ_ERROR 0x031100
#define SS_WRITE_ERROR 0x030c02
#define SS_WRITE_PROTECTED 0x072700
#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */
#define ASC(x) ((u8) ((x) >> 8))
#define ASCQ(x) ((u8) (x))
/*-------------------------------------------------------------------------*/
struct fsg_lun {
struct file *filp;
loff_t file_length;
loff_t num_sectors;
unsigned int initially_ro:1;
unsigned int ro:1;
unsigned int removable:1;
unsigned int cdrom:1;
unsigned int prevent_medium_removal:1;
unsigned int registered:1;
unsigned int info_valid:1;
u32 sense_data;
u32 sense_data_info;
u32 unit_attention_data;
struct device dev;
};
#define fsg_lun_is_open(curlun) ((curlun)->filp != NULL)
static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
{
return container_of(dev, struct fsg_lun, dev);
}
/* Big enough to hold our biggest descriptor */
#define EP0_BUFSIZE 256
#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */
/* Number of buffers we will use. 2 is enough for double-buffering */
#define FSG_NUM_BUFFERS 2
/* Default size of buffer length. */
#define FSG_BUFLEN ((u32)16384)
/* Maximal number of LUNs supported in mass storage function */
#define FSG_MAX_LUNS 8
enum fsg_buffer_state {
BUF_STATE_EMPTY = 0,
BUF_STATE_FULL,
BUF_STATE_BUSY
};
struct fsg_buffhd {
#ifdef FSG_BUFFHD_STATIC_BUFFER
char buf[FSG_BUFLEN];
#else
void *buf;
#endif
enum fsg_buffer_state state;
struct fsg_buffhd *next;
/* The NetChip 2280 is faster, and handles some protocol faults
* better, if we don't submit any short bulk-out read requests.
* So we will record the intended request length here. */
unsigned int bulk_out_intended_length;
struct usb_request *inreq;
int inreq_busy;
struct usb_request *outreq;
int outreq_busy;
};
enum fsg_state {
/* This one isn't used anywhere */
FSG_STATE_COMMAND_PHASE = -10,
FSG_STATE_DATA_PHASE,
FSG_STATE_STATUS_PHASE,
FSG_STATE_IDLE = 0,
FSG_STATE_ABORT_BULK_OUT,
FSG_STATE_RESET,
FSG_STATE_INTERFACE_CHANGE,
FSG_STATE_CONFIG_CHANGE_DISABLE,
FSG_STATE_CONFIG_CHANGE,
FSG_STATE_DISCONNECT,
FSG_STATE_EXIT,
FSG_STATE_TERMINATED
};
enum data_direction {
DATA_DIR_UNKNOWN = 0,
DATA_DIR_FROM_HOST,
DATA_DIR_TO_HOST,
DATA_DIR_NONE
};
/*-------------------------------------------------------------------------*/
static inline u32 get_unaligned_be24(u8 *buf)
{
return 0xffffff & (u32) get_unaligned_be32(buf - 1);
}
/*-------------------------------------------------------------------------*/
enum {
#ifndef FSG_NO_DEVICE_STRINGS
FSG_STRING_MANUFACTURER = 1,
FSG_STRING_PRODUCT,
FSG_STRING_SERIAL,
FSG_STRING_CONFIG,
#endif
FSG_STRING_INTERFACE
};
#ifndef FSG_NO_OTG
static struct usb_otg_descriptor
fsg_otg_desc = {
.bLength = sizeof fsg_otg_desc,
.bDescriptorType = USB_DT_OTG,
.bmAttributes = USB_OTG_SRP,
};
#endif
/* There is only one interface. */
static struct usb_interface_descriptor
fsg_intf_desc = {
.bLength = sizeof fsg_intf_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bNumEndpoints = 2, /* Adjusted during fsg_bind() */
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
.bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */
.bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */
.iInterface = FSG_STRING_INTERFACE,
};
/* Three full-speed endpoint descriptors: bulk-in, bulk-out,
* and interrupt-in. */
static struct usb_endpoint_descriptor
fsg_fs_bulk_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
/* wMaxPacketSize set by autoconfiguration */
};
static struct usb_endpoint_descriptor
fsg_fs_bulk_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
/* wMaxPacketSize set by autoconfiguration */
};
#ifndef FSG_NO_INTR_EP
static struct usb_endpoint_descriptor
fsg_fs_intr_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(2),
.bInterval = 32, /* frames -> 32 ms */
};
#ifndef FSG_NO_OTG
# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2
#else
# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1
#endif
#endif
static struct usb_descriptor_header *fsg_fs_function[] = {
#ifndef FSG_NO_OTG
(struct usb_descriptor_header *) &fsg_otg_desc,
#endif
(struct usb_descriptor_header *) &fsg_intf_desc,
(struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
(struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
#ifndef FSG_NO_INTR_EP
(struct usb_descriptor_header *) &fsg_fs_intr_in_desc,
#endif
NULL,
};
/*
* USB 2.0 devices need to expose both high speed and full speed
* descriptors, unless they only run at full speed.
*
* That means alternate endpoint descriptors (bigger packets)
* and a "device qualifier" ... plus more construction options
* for the config descriptor.
*/
static struct usb_endpoint_descriptor
fsg_hs_bulk_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
fsg_hs_bulk_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = cpu_to_le16(512),
.bInterval = 1, /* NAK every 1 uframe */
};
#ifndef FSG_NO_INTR_EP
static struct usb_endpoint_descriptor
fsg_hs_intr_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(2),
.bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
};
#ifndef FSG_NO_OTG
# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2
#else
# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1
#endif
#endif
static struct usb_descriptor_header *fsg_hs_function[] = {
#ifndef FSG_NO_OTG
(struct usb_descriptor_header *) &fsg_otg_desc,
#endif
(struct usb_descriptor_header *) &fsg_intf_desc,
(struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
(struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
#ifndef FSG_NO_INTR_EP
(struct usb_descriptor_header *) &fsg_hs_intr_in_desc,
#endif
NULL,
};
/* Maxpacket and other transfer characteristics vary by speed. */
static struct usb_endpoint_descriptor *
fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
struct usb_endpoint_descriptor *hs)
{
if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
return hs;
return fs;
}
/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
static struct usb_string fsg_strings[] = {
#ifndef FSG_NO_DEVICE_STRINGS
{FSG_STRING_MANUFACTURER, fsg_string_manufacturer},
{FSG_STRING_PRODUCT, fsg_string_product},
{FSG_STRING_SERIAL, fsg_string_serial},
{FSG_STRING_CONFIG, fsg_string_config},
#endif
{FSG_STRING_INTERFACE, fsg_string_interface},
{}
};
static struct usb_gadget_strings fsg_stringtab = {
.language = 0x0409, /* en-us */
.strings = fsg_strings,
};
/*-------------------------------------------------------------------------*/
/* If the next two routines are called while the gadget is registered,
* the caller must own fsg->filesem for writing. */
static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
{
int ro;
struct file *filp = NULL;
int rc = -EINVAL;
struct inode *inode = NULL;
loff_t size;
loff_t num_sectors;
loff_t min_sectors;
/* R/W if we can, R/O if we must */
ro = curlun->initially_ro;
if (!ro) {
filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
if (-EROFS == PTR_ERR(filp))
ro = 1;
}
if (ro)
filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
if (IS_ERR(filp)) {
LINFO(curlun, "unable to open backing file: %s\n", filename);
return PTR_ERR(filp);
}
if (!(filp->f_mode & FMODE_WRITE))
ro = 1;
if (filp->f_path.dentry)
inode = filp->f_path.dentry->d_inode;
if (inode && S_ISBLK(inode->i_mode)) {
if (bdev_read_only(inode->i_bdev))
ro = 1;
} else if (!inode || !S_ISREG(inode->i_mode)) {
LINFO(curlun, "invalid file type: %s\n", filename);
goto out;
}
/* If we can't read the file, it's no good.
* If we can't write the file, use it read-only. */
if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
LINFO(curlun, "file not readable: %s\n", filename);
goto out;
}
if (!(filp->f_op->write || filp->f_op->aio_write))
ro = 1;
size = i_size_read(inode->i_mapping->host);
if (size < 0) {
LINFO(curlun, "unable to find file size: %s\n", filename);
rc = (int) size;
goto out;
}
num_sectors = size >> 9; /* File size in 512-byte blocks */
min_sectors = 1;
if (curlun->cdrom) {
num_sectors &= ~3; /* Reduce to a multiple of 2048 */
min_sectors = 300*4; /* Smallest track is 300 frames */
if (num_sectors >= 256*60*75*4) {
num_sectors = (256*60*75 - 1) * 4;
LINFO(curlun, "file too big: %s\n", filename);
LINFO(curlun, "using only first %d blocks\n",
(int) num_sectors);
}
}
if (num_sectors < min_sectors) {
LINFO(curlun, "file too small: %s\n", filename);
rc = -ETOOSMALL;
goto out;
}
get_file(filp);
curlun->ro = ro;
curlun->filp = filp;
curlun->file_length = size;
curlun->num_sectors = num_sectors;
LDBG(curlun, "open backing file: %s\n", filename);
rc = 0;
out:
filp_close(filp, current->files);
return rc;
}
static void fsg_lun_close(struct fsg_lun *curlun)
{
if (curlun->filp) {
LDBG(curlun, "close backing file\n");
fput(curlun->filp);
curlun->filp = NULL;
}
}
/*-------------------------------------------------------------------------*/
/* Sync the file data, don't bother with the metadata.
* This code was copied from fs/buffer.c:sys_fdatasync(). */
static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
{
struct file *filp = curlun->filp;
if (curlun->ro || !filp)
return 0;
return vfs_fsync(filp, filp->f_path.dentry, 1);
}
static void store_cdrom_address(u8 *dest, int msf, u32 addr)
{
if (msf) {
/* Convert to Minutes-Seconds-Frames */
addr >>= 2; /* Convert to 2048-byte frames */
addr += 2*75; /* Lead-in occupies 2 seconds */
dest[3] = addr % 75; /* Frames */
addr /= 75;
dest[2] = addr % 60; /* Seconds */
addr /= 60;
dest[1] = addr; /* Minutes */
dest[0] = 0; /* Reserved */
} else {
/* Absolute sector */
put_unaligned_be32(addr, dest);
}
}
/*-------------------------------------------------------------------------*/
static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
? curlun->ro
: curlun->initially_ro);
}
static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
struct rw_semaphore *filesem = dev_get_drvdata(dev);
char *p;
ssize_t rc;
down_read(filesem);
if (fsg_lun_is_open(curlun)) { /* Get the complete pathname */
p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
if (IS_ERR(p))
rc = PTR_ERR(p);
else {
rc = strlen(p);
memmove(buf, p, rc);
buf[rc] = '\n'; /* Add a newline */
buf[++rc] = 0;
}
} else { /* No file, return 0 bytes */
*buf = 0;
rc = 0;
}
up_read(filesem);
return rc;
}
static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
ssize_t rc = count;
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
struct rw_semaphore *filesem = dev_get_drvdata(dev);
int i;
if (sscanf(buf, "%d", &i) != 1)
return -EINVAL;
/* Allow the write-enable status to change only while the backing file
* is closed. */
down_read(filesem);
if (fsg_lun_is_open(curlun)) {
LDBG(curlun, "read-only status change prevented\n");
rc = -EBUSY;
} else {
curlun->ro = !!i;
curlun->initially_ro = !!i;
LDBG(curlun, "read-only status set to %d\n", curlun->ro);
}
up_read(filesem);
return rc;
}
static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
struct rw_semaphore *filesem = dev_get_drvdata(dev);
int rc = 0;
if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
LDBG(curlun, "eject attempt prevented\n");
return -EBUSY; /* "Door is locked" */
}
/* Remove a trailing newline */
if (count > 0 && buf[count-1] == '\n')
((char *) buf)[count-1] = 0; /* Ugh! */
/* Eject current medium */
down_write(filesem);
if (fsg_lun_is_open(curlun)) {
fsg_lun_close(curlun);
curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
}
/* Load new medium */
if (count > 0 && buf[0]) {
rc = fsg_lun_open(curlun, buf);
if (rc == 0)
curlun->unit_attention_data =
SS_NOT_READY_TO_READY_TRANSITION;
}
up_write(filesem);
return (rc < 0 ? rc : count);
}

View File

@ -1,738 +0,0 @@
/*
* LEGO® MINDSTORMS EV3
*
* Copyright (C) 2010-2013 The LEGO Group
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* This UsbFunction file is based on and inheritated from
* the original file (f_sourcesink.c) and work done by
* David Brownell
*
* >> f_sourcesink.c - USB peripheral source/sink configuration driver <<
*
* >> Copyright (C) 2003-2008 David Brownell <<
* >> Copyright (C) 2008 by Nokia Corporation <<
*
*/
/*
*
* HID IN/OUT Interrupt transfer FUNCTION ...
*
*/
struct f_rudolf {
struct usb_function function;
struct usb_ep *in_ep;
struct usb_ep *out_ep;
};
enum // Used for signaling the IN stuff USB-state
{ // Data from the Brick to the HOST
USB_DATA_IDLE, //
USB_DATA_BUSY, // Ongoing USB request
USB_DATA_PENDING, // Data ready for X-fer, but USB busy
USB_DATA_READY, // Initial setting
};
int input_state = USB_DATA_IDLE;
struct usb_ep *save_in_ep;
struct usb_request *save_in_req;
#ifndef PCASM
static inline struct f_rudolf *func_to_rudolf(struct usb_function *f)
{
return container_of(f, struct f_rudolf, function);
}
#else
// Keep Eclipse happy
#endif
static struct usb_interface_descriptor rudolf_intf = {
.bLength = sizeof rudolf_intf,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 2, // Just plain in and out
.bInterfaceClass = USB_CLASS_HID, // We go for NONE custom-driver
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
/* .iInterface = DYNAMIC */
};
static struct hid_descriptor hs_hid_rudolf_desc = {
.bLength = sizeof hs_hid_rudolf_desc,
.bDescriptorType = HID_DT_HID,
.bcdHID = cpu_to_le16(0x0110),
.bCountryCode = 0x00,
.bNumDescriptors = 0x01, // "The one and only"
.desc[0].bDescriptorType = 0x22, // Report Descriptor Type - 0x22 = HID
.desc[0].wDescriptorLength = sizeof hs_hid_report_descriptor,
/*.desc[0].bDescriptorType = DYNAMIC */
/*.desc[0].wDescriptorLenght= DYNAMIC */
};
static struct hid_descriptor fs_hid_rudolf_desc = {
.bLength = sizeof fs_hid_rudolf_desc,
.bDescriptorType = HID_DT_HID,
.bcdHID = cpu_to_le16(0x0110),
.bCountryCode = 0x00,
.bNumDescriptors = 0x01, // "The one and only"
.desc[0].bDescriptorType = 0x22, // Report Descriptor Type - 0x22 = HID
.desc[0].wDescriptorLength = sizeof fs_hid_report_descriptor,
};
/* full speed support: */
static struct usb_endpoint_descriptor rudolf_out_fs_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval = 1, /* 1 = 1 mSec POLL rate for FS */
};
static struct usb_endpoint_descriptor rudolf_in_fs_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval = 1, /* 1 = 1 mSec POLL rate for FS */
};
/* high speed support: */
static struct usb_endpoint_descriptor rudolf_in_hs_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = 4, /* Calculated as :
* 2^(value-1) * 125uS
* i.e. value 1: 2^(1-1) * 125 uSec = 125 uSec
* - 4: 2^(4-1) * 125 uSec = 1 mSec
*/
};
static struct usb_endpoint_descriptor rudolf_out_hs_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = 4, /* Calculated as :
* 2^(value-1) * 125uS
* i.e. value 1: 2^(1-1) * 125 uSec = 125 uSec
* - 4: 2^(4-1) * 125 uSec = 1 mSec
*/
};
static struct usb_descriptor_header *hs_rudolf_descs[] = {
(struct usb_descriptor_header *) &rudolf_intf,
(struct usb_descriptor_header *) &hs_hid_rudolf_desc,
(struct usb_descriptor_header *) &rudolf_in_hs_desc,
(struct usb_descriptor_header *) &rudolf_out_hs_desc,
NULL,
};
static struct usb_descriptor_header *fs_rudolf_descs[] = {
(struct usb_descriptor_header *) &rudolf_intf,
(struct usb_descriptor_header *) &fs_hid_rudolf_desc,
(struct usb_descriptor_header *) &rudolf_in_fs_desc,
(struct usb_descriptor_header *) &rudolf_out_fs_desc,
NULL,
};
/* function-specific strings: */
static struct usb_string strings_rudolf[] = {
[0].s = "Xfer data to and from EV3 brick",
{ } /* end of list */
};
static struct usb_gadget_strings stringtab_rudolf = {
.language = 0x0409, /* en-us */
.strings = strings_rudolf,
};
static struct usb_gadget_strings *rudolf_strings[] = {
&stringtab_rudolf,
NULL,
};
/*-------------------------------------------------------------------------*/
static int
f_rudolf_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_composite_dev *cdev = c->cdev;
struct f_rudolf *rudolf = func_to_rudolf(f);
int id;
/* allocate interface ID(s) */
id = usb_interface_id(c, f);
if (id < 0)
return id;
rudolf_intf.bInterfaceNumber = id;
/* allocate endpoints */
rudolf->in_ep = usb_ep_autoconfig(cdev->gadget, &rudolf_in_fs_desc);
if (!rudolf->in_ep) {
autoconf_fail:
ERROR(cdev, "%s: can't autoconfigure on %s\n",
f->name, cdev->gadget->name);
return -ENODEV;
}
rudolf->in_ep->driver_data = cdev; /* claim */
rudolf->out_ep = usb_ep_autoconfig(cdev->gadget, &rudolf_out_fs_desc);
if (!rudolf->out_ep)
goto autoconf_fail;
rudolf->out_ep->driver_data = cdev; /* claim */
/* support high speed hardware */
if (gadget_is_dualspeed(c->cdev->gadget)) {
rudolf_in_hs_desc.bEndpointAddress =
rudolf_in_fs_desc.bEndpointAddress;
rudolf_out_hs_desc.bEndpointAddress =
rudolf_out_fs_desc.bEndpointAddress;
f->hs_descriptors = hs_rudolf_descs;
f->descriptors = fs_rudolf_descs;
}
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
f->name, rudolf->in_ep->name, rudolf->out_ep->name);
return 0;
}
static void
f_rudolf_unbind(struct usb_configuration *c, struct usb_function *f)
{
kfree(func_to_rudolf(f));
}
static void usb_req_arm(struct usb_ep *ep, struct usb_request *req)
{
int status;
if (UsbSpeed.Speed == FULL_SPEED)
{
req->length = 64;
req->actual = 64;
}
else
{
req->length = 1024;
req->actual = 1024;
}
status = usb_ep_queue(ep, req, GFP_ATOMIC);
if (status) {
usb_ep_set_halt(ep);
/* FIXME recover later ... somehow */
}
}
static int read_data_from_host(struct usb_request *req)
{
unsigned i;
u8 *buf = req->buf;
int from_host_length = 0; // NO ACCESS LOCKS YET
// test for actual length > 0
for (i = 0; i < req->actual; i++, buf++)
{
usb_char_buffer_out[i] = *buf;
from_host_length++;
}
return (from_host_length);
}
static void write_data_to_the_host(struct usb_ep *ep, struct usb_request *req)
{
unsigned i;
u8 *buf = req->buf;
//#define DEBUG
#ifdef DEBUG
printk("WR to HOST req->length = %d\r\n", req->length);
#endif
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
printk("USB = %d, %d\r\n", usb_char_buffer_in[2], usb_char_buffer_in[3]);
#endif
#undef DEBUG
for (i = 0; i < req->length; i++)
*buf++ = usb_char_buffer_in[i];
usb_char_in_length = 0; // Reset and ready
}
static void rudolf_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_rudolf *rudolf = ep->driver_data;
int status = req->status;
switch ( status ) {
case 0: /* normal completion? */
if (ep == rudolf->out_ep) // An OUT completion?
{
//#define DEBUG
#ifdef DEBUG
printk("Rudolf_complete OUT\n");
#endif
usb_char_out_length = read_data_from_host(req);
usb_req_arm(ep, req);
}
else // We have an INPUT request complete
{
//#define DEBUG
#ifdef DEBUG
printk("Rudolf_complete IN\n");
#endif
switch(input_state) // State of Brick data x-fer
{
case USB_DATA_READY: //should be BUSY or PENDING....
#ifdef DEBUG
printk("IN_IN_IN - READY ?????\n");
#endif
break;
case USB_DATA_PENDING: //
// #define DEBUG
#ifdef DEBUG
printk("IN_IN_IN - PENDING settes to BUSY\n");
#endif
input_state = USB_DATA_BUSY;
write_data_to_the_host(ep, req);
usb_req_arm(ep, req); // new request
break;
case USB_DATA_BUSY: //
#ifdef DEBUG
printk("IN_IN_IN - BUSY settes to READY\n");
#endif
#undef DEBUG
input_state = USB_DATA_READY;
// and relax
break;
case USB_DATA_IDLE: // too lazy
#ifdef DEBUG
printk("IN_IN_IN - IDLE\n");
#endif
//#undef DEBUG
break;
default: break; // hmmm.
}
// Reset the buffer size - Ready again
usb_char_in_length = 0;
}
break;
/* this endpoint is normally active while we're configured */
case -ESHUTDOWN: /* disconnect from host */
// REMOVED 26102012 (*pUsbSpeed).Speed = FULL_SPEED;
case -ECONNABORTED: /* hardware forced ep reset */
case -ECONNRESET: /* request dequeued */
//case -ESHUTDOWN: /* disconnect from host */
if (ep == rudolf->out_ep)
read_data_from_host(req);
free_ep_req(ep, req);
return;
case -EOVERFLOW: /* buffer overrun on read means that
we didn't provide a big enough
buffer.
*/
default:
//#if 1
// DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name,
// status, req->actual, req->length);
//#endif
case -EREMOTEIO: /* short read */
break;
}
}
static int rudolf_start_ep(struct f_rudolf *rudolf, bool is_in)
{
struct usb_ep *ep;
struct usb_request *req;
int status;
ep = is_in ? rudolf->in_ep : rudolf->out_ep;
req = alloc_ep_req(ep);
if (!req)
return -ENOMEM;
req->complete = rudolf_complete;
#ifdef DEBUG
printk("UsbSpeed.Speed = %d\n\r", UsbSpeed.Speed);
#endif
if (UsbSpeed.Speed == FULL_SPEED)
{
#ifdef DEBUG
printk("rudolf_start_ep FULL\n\r");
#endif
(*pUsbSpeed).Speed = FULL_SPEED;
req->length = 64; // Full speed max buffer size
req->actual = 64;
}
else
{
#ifdef DEBUG
printk("rudolf_start_ep HIGH\n\r");
#endif
(*pUsbSpeed).Speed = HIGH_SPEED;
req->length = 1024; // High speed max buffer size
req->actual = 1024;
}
if (is_in)
{
save_in_ep = ep;
save_in_req = req;
#ifdef DEBUG
printk("req->length = %d ***** Rudolf_Start_Ep_in\n\r", req->length);
#endif
// reinit_write_data(ep, req);
input_state = USB_DATA_BUSY;
}
else
{
#ifdef DEBUG
printk("***** Rudolf_Start_Ep_out\n");
#endif
}
status = usb_ep_queue(ep, req, GFP_ATOMIC);
if (status) {
struct usb_composite_dev *cdev;
cdev = rudolf->function.config->cdev;
ERROR(cdev, "start %s %s --> %d\n",
is_in ? "IN" : "OUT",
ep->name, status);
free_ep_req(ep, req);
}
return status;
}
static void disable_rudolf(struct f_rudolf *rudolf)
{
struct usb_composite_dev *cdev;
cdev = rudolf->function.config->cdev;
disable_endpoints(cdev, rudolf->in_ep, rudolf->out_ep);
VDBG(cdev, "%s disabled\n", rudolf->function.name);
}
static int
enable_rudolf(struct usb_composite_dev *cdev, struct f_rudolf *rudolf)
{
int result = 0;
const struct usb_endpoint_descriptor *ep_in, *ep_out;
struct usb_ep *ep;
ep_in = ep_choose(cdev->gadget, &rudolf_in_hs_desc, &rudolf_in_fs_desc);
ep_out = ep_choose(cdev->gadget, &rudolf_out_hs_desc, &rudolf_out_fs_desc);
ep = rudolf->in_ep;
result = usb_ep_enable(ep, ep_in);
if (result < 0)
return result;
ep->driver_data = rudolf;
result = rudolf_start_ep(rudolf, true);
if (result < 0) {
fail:
ep = rudolf->in_ep;
usb_ep_disable(ep);
ep->driver_data = NULL;
return result;
}
/* one endpoint reads (sinks) anything OUT (from the host) */
ep = rudolf->out_ep;
result = usb_ep_enable(ep, ep_out);
if (result < 0)
goto fail;
ep->driver_data = rudolf;
result = rudolf_start_ep(rudolf, false);
if (result < 0) {
usb_ep_disable(ep);
ep->driver_data = NULL;
goto fail;
}
DBG(cdev, "%s enabled\n", rudolf->function.name);
return result;
}
static int f_rudolf_set_alt(struct usb_function *f,
unsigned intf, unsigned alt)
{
struct f_rudolf *rudolf = func_to_rudolf(f);
struct usb_composite_dev *cdev = f->config->cdev;
/* we know alt is zero */
if (rudolf->in_ep->driver_data)
disable_rudolf(rudolf);
return enable_rudolf(cdev, rudolf);
}
static void f_rudolf_disable(struct usb_function *f)
{
struct f_rudolf *rudolf = func_to_rudolf(f);
disable_rudolf(rudolf);
}
/*-------------------------------------------------------------------------*/
static int msg_config(struct usb_configuration *c);
static int rudolf_bind_config(struct usb_configuration *c)
{
struct f_rudolf *rudolf;
int status;
rudolf = kzalloc(sizeof *rudolf, GFP_KERNEL);
if (!rudolf)
return -ENOMEM;
rudolf->function.name = "rudolf xfer";
rudolf->function.descriptors = hs_rudolf_descs;
rudolf->function.bind = f_rudolf_bind;
rudolf->function.unbind = f_rudolf_unbind;
rudolf->function.set_alt = f_rudolf_set_alt;
rudolf->function.disable = f_rudolf_disable;
status = usb_add_function(c, &rudolf->function);
if (status) {
kfree(rudolf);
return status;
}
status = msg_config(c);
if (status) {
kfree(rudolf);
return status;
}
return status;
}
#ifndef PCASM
static int rudolf_setup(struct usb_configuration *c,
const struct usb_ctrlrequest *ctrl)
{
struct usb_request *req = c->cdev->req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
u16 length = 0;
/* composite driver infrastructure handles everything except
* the two control test requests.
*/
switch (ctrl->bRequest) {
/*
* These are the same vendor-specific requests supported by
* Intel's USB 2.0 compliance test devices. We exceed that
* device spec by allowing multiple-packet requests.
*
* NOTE: the Control-OUT data stays in req->buf ... better
* would be copying it into a scratch buffer, so that other
* requests may safely intervene.
*/
case 0x5b: /* control WRITE test -- fill the buffer */
if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
goto unknown;
if (w_value || w_index)
break;
/* just read that many bytes into the buffer */
if (w_length > req->length)
break;
value = w_length;
break;
case 0x5c: /* control READ test -- return the buffer */
if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
goto unknown;
if (w_value || w_index)
break;
/* expect those bytes are still in the buffer; send back */
if (w_length > req->length)
break;
value = w_length;
break;
default:
unknown:
VDBG(c->cdev,
"unknown control req%02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
}
//HER SKAL HID DESC SENDES!!!
switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
| USB_REQ_GET_DESCRIPTOR):
switch (w_value >> 8) {
case HID_DT_REPORT:
//VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n");
length = w_length;
length = min_t(unsigned short, length,
sizeof hs_hid_report_descriptor);
memcpy(req->buf, hs_hid_report_descriptor, length);
value = length;
goto respond;
break;
default:
//VDBG(cdev, "Unknown decriptor request 0x%x\n",
// value >> 8);
goto stall;
break;
}
break;
default:
//VDBG(cdev, "Unknown request 0x%x\n",
// ctrl->bRequest);
goto stall;
break;
}
//HERTIL
/* respond with data transfer or status phase? */
stall:
return -EOPNOTSUPP;
respond:
if (value >= 0) {
VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
req->zero = 0;
req->length = value;
value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
if (value < 0)
ERROR(c->cdev, "source/sinkc response, err %d\n",
value);
}
/* device either stalls (value < 0) or reports success */
return value;
}
#else
// Keep Eclipse happy
#endif
static struct usb_configuration rudolf_driver = {
.label = "rudolf driver",
.strings = rudolf_strings,
.bind = rudolf_bind_config,
.setup = rudolf_setup,
.bConfigurationValue = 1,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
/* .iConfiguration = DYNAMIC */
};
/**
*
*/
int rudolf_add(struct usb_composite_dev *cdev, bool autoresume)
{
int id;
/* allocate string ID(s) */
id = usb_string_id(cdev);
if (id < 0)
return id;
strings_rudolf[0].id = id;
rudolf_intf.iInterface = id;
rudolf_driver.iConfiguration = 1; // id;
/* support autoresume for remote wakeup testing */
if (autoresume)
rudolf_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
/* support OTG systems */
if (gadget_is_otg(cdev->gadget)) {
rudolf_driver.descriptors = otg_desc;
rudolf_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}
return usb_add_config(cdev, &rudolf_driver);
}

View File

@ -1,7 +0,0 @@
#!/bin/sh
set -xe
scp -qr kernel uf2daemon Makefile vm:linux/pxt/
ssh vm "cd linux/pxt; make $1"
mkdir -p bin
scp vm:linux/pxt/bin/* bin/

View File

@ -1,14 +0,0 @@
# Patched EV3 image
The file `ev3-fs.patch` summarizes the changes done to the original V1.09D image.
You can see some text files are edited, the `d_usbdev.ko` is updated (sources in `../kernel`),
`uf2d` added (sources in `../uf2daemon`), and a stock `nbd.ko` module is added.
Additionally, the `edimax01.ko` is replaced by now much more popular `rtl8192cu.ko` (also stock).
The init script has a hook for running a shell script from `/mnt/ramdisk/`. This can be used
for testing different modules etc.
The kernel command line has been modified to:
* disable DMA for the MUSB driver - otherwise the mass storage device is very unstable
* increase the size of dmesg buffer to 128k

View File

@ -1,34 +0,0 @@
#!/bin/sh
let fs = require("fs")
let styles = {
"0": "rxtx",
"1": " tx",
"2": "rx ",
}
function build() {
let kern = fs.readFileSync( "foo")
let off = 0x0001df30
kern = kern.slice(off + 6 * 5, off + 6 * (5 + 6))
console.log(kern.toString("hex"))
off = 0
for (let i = 0; i < 30; ++i) {
if (kern[off+4] == 64) {
kern[off+4] = 0
kern[off+5] = 2
}
if(kern[off] == 3 || kern[off] == 4) {
kern[off+4] = 0
kern[off+5] = 1
}
console.log(`ep=${kern[off]} style=${styles[kern[off+1]]} buf=${kern[off+2] == 0 ? "sin" : kern[off+2] == 1 ? "dbl" : "XXX"} pad=${kern[off+3]} sz=${kern[off+4]+(kern[off+5]<<8)}`)
off += 6
}
console.log(kern.toString("hex"))
}
build()

View File

@ -1,53 +0,0 @@
diff -ur orig-ev3/etc/init.d/ev3init.sh dev-ev3/etc/init.d/ev3init.sh
--- orig-ev3/etc/init.d/ev3init.sh 1970-01-01 01:00:00.000000000 +0100
+++ dev-ev3/etc/init.d/ev3init.sh 2017-07-27 12:19:43.195041798 +0100
@@ -1,5 +1,7 @@
#!/bin/sh
+echo Y > /sys/module/printk/parameters/time
+
bluetoothd -n > /dev/null 2>&1 &
echo "Setting up VirtualDrive...";
@@ -60,3 +62,6 @@
sleep 2
hciattach /dev/ttyS2 texas 2000000 "flow" "nosleep" $STRING
sdptool add SP
+
+insmod /lib/modules/2.6.33-rc4/kernel/drivers/net/wireless/rtl8192cu.ko
+. /mnt/ramdisk/rc.local || :
Only in orig-ev3/home/root/lms2012/sys: exit~
diff -ur orig-ev3/home/root/lms2012/sys/init dev-ev3/home/root/lms2012/sys/init
--- orig-ev3/home/root/lms2012/sys/init 1970-01-01 01:00:00.000000000 +0100
+++ dev-ev3/home/root/lms2012/sys/init 2017-07-27 12:23:43.072605126 +0100
@@ -5,13 +5,15 @@
var=$(printf 'HostStr=%s SerialStr=%s' $(cat /home/root/lms2012/sys/settings/BrickName) $(cat /home/root/lms2012/sys/settings/BTser))
echo $var > /home/root/lms2012/sys/settings/UsbInfo.dat
+insmod ${PWD}/mod/nbd.ko
+${PWD}/uf2d
insmod ${PWD}/mod/d_iic.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_uart.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_power.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_pwm.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_ui.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_analog.ko `cat /home/root/lms2012/sys/settings/HwId`
-insmod ${PWD}/mod/d_usbdev.ko `cat /home/root/lms2012/sys/settings/UsbInfo.dat`
+insmod ${PWD}/mod/d_usbdev.ko `cat /home/root/lms2012/sys/settings/UsbInfo.dat` file=/dev/nbd0
insmod ${PWD}/mod/d_usbhost.ko
insmod ${PWD}/mod/d_sound.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_bt.ko `cat /home/root/lms2012/sys/settings/HwId`
@@ -29,6 +31,8 @@
chmod 666 /dev/lms_iic
chmod 666 /dev/lms_bt
+echo 4 > /proc/sys/kernel/printk
+
cd ..
ls -R > /dev/null
cd sys
Binary files orig-ev3/home/root/lms2012/sys/mod/d_usbdev.ko and dev-ev3/home/root/lms2012/sys/mod/d_usbdev.ko differ
Only in dev-ev3/home/root/lms2012/sys/mod: nbd.ko
Only in dev-ev3/home/root/lms2012/sys: uf2d
Only in orig-ev3/lib/modules/2.6.33-rc4/kernel/drivers/net/wireless: edimax01.ko
Only in dev-ev3/lib/modules/2.6.33-rc4/kernel/drivers/net/wireless: rtl8192cu.ko

View File

@ -1,55 +0,0 @@
#!/bin/sh
let fs = require("fs")
// we try to use shorter versions of all parameters for the additional parameters to fit
let bootargs = "mem=${memsize} initrd=${filesysaddr},${filesyssize} root=/dev/ram0 rw rootfstype=cramfs console=${console} ip=${ipaddr} lpj=747520 quiet"
let bootnews = "mem=64M initrd=0xC1180000,10M root=1:0 rw rootfstype=cramfs console=${console} lpj=747520 musb_hdrc.use_dma=0 log_buf_len=128k quiet"
let piggy = true
function build() {
if (bootnews.length > bootargs.length) {
console.log("args too long")
return
}
while (bootnews.length < bootargs.length)
bootnews += " "
let cr = fs.readFileSync("cram.bin")
if (cr.length > 10485760) {
console.log("too big by " + (cr.length - 10485760))
return
}
let img = fs.readFileSync("EV3 Firmware V1.09D.bin")
for (let i = 0; i < bootnews.length; ++i) {
if (img[0x21DDA + i] != bootargs.charCodeAt(i)) {
console.log("boot args mismatch")
return
}
img[0x21DDA + i] = bootnews.charCodeAt(i)
}
let off = 0x250000
if (img[off] != 0x45 || img[off + 1] != 0x3d) {
console.log("bad magic: " + img[off] + " / " + img[off+1])
return
}
cr.copy(img, off)
let kern = fs.readFileSync(piggy ? "piggy-patched.gzip" : "linux/arch/arm/boot/uImage")
off = piggy ? 0x0005540f : 0x00050000
if (img[off] != kern[0] || img[off+1] != kern[1]) {
console.log("bad kernel magic: " + img[off] + " / " + img[off+1])
return
}
kern.copy(img, off)
fs.writeFileSync("firmware.bin", img)
}
build()

View File

@ -1,9 +0,0 @@
#!/bin/sh
# dd if=EV3\ Firmware\ V1.09D.bin of=orig.cram bs=65536 skip=37 count=400
sudo cp linux/pxt/uf2daemon/server dev-ev3/home/root/lms2012/sys/uf2d
sudo cp linux/pxt/kernel/d_usbdev.ko dev-ev3/home/root/lms2012/sys/mod/d_usbdev.ko
sudo chown -R root:root dev-ev3/home/root/lms2012
sudo mkfs.cramfs dev-ev3 cram.bin
node img
ls -l firmware.bin

View File

@ -1,8 +0,0 @@
let small = "010100000004010200000004020100004000020200004000030100000004040000008000"
let big = "010100000004010200000004020100000002020200000002030100000001040000000001"
let fs = require("fs")
let kern = fs.readFileSync( "foo")
let kern2 = new Buffer(kern.toString("hex").replace(small, big), "hex")
fs.writeFileSync("foo2", kern2)

View File

@ -1,10 +0,0 @@
#!/bin/sh
./mk
ev3duder up bin/d_usbdev.ko ../prjs/ko/d_usbdev.ko
ev3duder up bin/nbd.ko ../prjs/ko/nbd.ko
ev3duder up ins ../prjs/ko/ins
ev3duder exec 'rm ../prjs/ko/uf2d'
ev3duder up bin/uf2d ../prjs/ko/uf2d
#ev3duder exec 'echo . /mnt/ramdisk/prjs/ko/ins > /mnt/ramdisk/rc.local'

View File

@ -1,6 +0,0 @@
CFLAGS = -std=c99 -W -Wall
SRC = main.c fat.c
all:
gcc -DX86=1 -g $(CFLAGS) $(SRC) -o server86
arm-none-linux-gnueabi-gcc -Os -s $(CFLAGS) $(SRC) -o server

View File

@ -1,784 +0,0 @@
#define VENDOR_NAME "The LEGO Group"
#define PRODUCT_NAME "Mindstorms EV3"
#define VOLUME_LABEL "EV3"
#define INDEX_URL "https://makecode.com/lego"
#define BOARD_ID "LEGO-EV3-v0"
#define _XOPEN_SOURCE 500
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#define max(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define min(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
#include "uf2.h"
#define DBG LOG
typedef struct {
uint8_t JumpInstruction[3];
uint8_t OEMInfo[8];
uint16_t SectorSize;
uint8_t SectorsPerCluster;
uint16_t ReservedSectors;
uint8_t FATCopies;
uint16_t RootDirectoryEntries;
uint16_t TotalSectors16;
uint8_t MediaDescriptor;
uint16_t SectorsPerFAT;
uint16_t SectorsPerTrack;
uint16_t Heads;
uint32_t HiddenSectors;
uint32_t TotalSectors32;
uint8_t PhysicalDriveNum;
uint8_t Reserved;
uint8_t ExtendedBootSig;
uint32_t VolumeSerialNumber;
char VolumeLabel[11];
uint8_t FilesystemIdentifier[8];
} __attribute__((packed)) FAT_BootBlock;
typedef struct {
char name[8];
char ext[3];
uint8_t attrs;
uint8_t reserved;
uint8_t createTimeFine;
uint16_t createTime;
uint16_t createDate;
uint16_t lastAccessDate;
uint16_t highStartCluster;
uint16_t updateTime;
uint16_t updateDate;
uint16_t startCluster;
uint32_t size;
} __attribute__((packed)) DirEntry;
typedef struct {
uint8_t seqno;
uint16_t name0[5];
uint8_t attrs;
uint8_t type;
uint8_t checksum;
uint16_t name1[6];
uint16_t startCluster;
uint16_t name2[2];
} __attribute__((packed)) VFatEntry;
STATIC_ASSERT(sizeof(DirEntry) == 32);
#define STR0(x) #x
#define STR(x) STR0(x)
const char infoUf2File[] = //
"UF2 Bootloader " UF2_VERSION "\r\n"
"Model: " PRODUCT_NAME "\r\n"
"Board-ID: " BOARD_ID "\r\n";
const char indexFile[] = //
"<!doctype html>\n"
"<html>"
"<body>"
"<script>\n"
"location.replace(\"" INDEX_URL "\");\n"
"</script>"
"</body>"
"</html>\n";
#define RESERVED_SECTORS 1
#define ROOT_DIR_SECTORS 4
#define SECTORS_PER_FAT ((NUM_FAT_BLOCKS * 2 + 511) / 512)
#define START_FAT0 RESERVED_SECTORS
#define START_FAT1 (START_FAT0 + SECTORS_PER_FAT)
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
#define ROOT_DIR_ENTRIES (ROOT_DIR_SECTORS * 512 / 32)
#define F_TEXT 1
#define F_UF2 2
#define F_DIR 4
#define F_CONT 8
static const FAT_BootBlock BootBlock = {
.JumpInstruction = {0xeb, 0x3c, 0x90},
.OEMInfo = "UF2 UF2 ",
.SectorSize = 512,
.SectorsPerCluster = 1,
.ReservedSectors = RESERVED_SECTORS,
.FATCopies = 2,
.RootDirectoryEntries = ROOT_DIR_ENTRIES,
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
.MediaDescriptor = 0xF8,
.SectorsPerFAT = SECTORS_PER_FAT,
.SectorsPerTrack = 1,
.Heads = 1,
.ExtendedBootSig = 0x29,
.VolumeSerialNumber = 0x00420042,
.VolumeLabel = VOLUME_LABEL,
.FilesystemIdentifier = "FAT16 ",
};
int currCluster = 2;
struct FsEntry *rootDir;
struct ClusterData *firstCluster, *lastCluster;
typedef struct ClusterData {
int flags;
int numclusters;
struct stat st;
struct ClusterData *dnext;
struct ClusterData *cnext;
struct FsEntry *dirdata;
struct FsEntry *myfile;
char name[0];
} ClusterData;
typedef struct FsEntry {
int startCluster;
uint8_t attrs;
int size;
int numdirentries;
time_t ctime, mtime;
struct FsEntry *next;
struct ClusterData *data;
char fatname[12];
char vfatname[0];
} FsEntry;
struct DirMap {
const char *mapName;
const char *fsName;
};
struct DirMap dirMaps[] = { //
#ifdef X86
{"foo qux baz", "dirs/bar"}, //
{"foo", "dirs/foo"}, //
{"xyz", "dirs/bar2"}, //
#else
{"Projects", "/mnt/ramdisk/prjs/BrkProg_SAVE"},
{"SD Card", "/media/card/myapps"},
{"USB Stick", "/media/usb/myapps"},
#endif
{NULL, NULL}};
void timeToFat(time_t t, uint16_t *dateP, uint16_t *timeP) {
struct tm tm;
localtime_r(&t, &tm);
if (timeP)
*timeP = (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec / 2);
if (dateP)
*dateP = (max(0, tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday;
}
void padded_memcpy(char *dst, const char *src, int len) {
for (int i = 0; i < len; ++i) {
if (*src)
*dst = *src++;
else
*dst = ' ';
dst++;
}
}
char *expandMap(const char *mapName) {
static char mapbuf[300];
const char *rest = "";
for (int i = 0; i < (int)sizeof(mapbuf); ++i) {
char c = mapName[i];
if (c == '/' || c == 0) {
mapbuf[i] = 0;
rest = mapName + i;
break;
}
mapbuf[i] = c;
}
for (int i = 0; dirMaps[i].mapName; ++i) {
if (strcmp(dirMaps[i].mapName, mapbuf) == 0) {
strcpy(mapbuf, dirMaps[i].fsName);
strcat(mapbuf, rest);
return mapbuf;
}
}
return NULL;
}
ClusterData *mkClusterData(int namelen) {
ClusterData *c = malloc(sizeof(*c) + namelen + 1);
memset(c, 0, sizeof(*c) + namelen + 1);
return c;
}
ClusterData *readDir(const char *mapName) {
DIR *d = opendir(expandMap(mapName));
if (!d)
return NULL;
ClusterData *res = NULL;
for (;;) {
struct dirent *ent = readdir(d);
if (!ent)
break;
ClusterData *c = mkClusterData(strlen(mapName) + 1 + strlen(ent->d_name));
c->flags = F_UF2;
c->dnext = res;
sprintf(c->name, "%s/%s", mapName, ent->d_name);
int err = stat(expandMap(c->name), &c->st);
assert(err >= 0);
if (S_ISREG(c->st.st_mode) && strlen(c->name) < UF2_FILENAME_MAX) {
c->numclusters = (c->st.st_size + 255) / 256;
} else {
free(c);
continue;
}
res = c;
}
closedir(d);
return res;
}
int filechar(int c) {
if (!c)
return 0;
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') ||
strchr("_-", c);
}
void copyFsChars(char *dst, const char *src, int len) {
for (int i = 0; i < len; ++i) {
if (filechar(*src))
dst[i] = toupper(*src++);
else {
if (*src == '.')
src = "";
if (*src == 0)
dst[i] = ' ';
else
dst[i] = '_';
while (*src && !filechar(*src))
src++;
}
}
}
FsEntry *mkFsEntry(const char *name) {
int sz = sizeof(FsEntry) + strlen(name) + 1;
FsEntry *e = malloc(sz);
memset(e, 0, sz);
e->startCluster = currCluster;
e->next = NULL;
// +1 for final 0x0000, and +12 for alignment
e->numdirentries = 1 + (strlen(name) + 1 + 12) / 13;
strcpy(e->vfatname, name);
const char *src = name;
copyFsChars(e->fatname, src, 8);
while (*src && *src != '.')
src++;
if (*src == '.')
src++;
else
src = "";
copyFsChars(e->fatname + 8, src, 3);
return e;
}
void addClusterData(ClusterData *c, FsEntry *e) {
currCluster += c->numclusters;
if (firstCluster == NULL) {
firstCluster = c;
} else {
lastCluster->cnext = c;
}
lastCluster = c;
if (c->st.st_ctime)
e->ctime = min(e->ctime, c->st.st_ctime);
e->mtime = max(e->mtime, c->st.st_mtime);
c->myfile = e;
DBG("add cluster: flags=%d size=%d numcl=%d", c->flags, (int)c->st.st_size, c->numclusters);
}
FsEntry *addRootText(const char *filename, const char *contents) {
FsEntry *e = mkFsEntry(filename);
e->next = rootDir;
rootDir = e;
int sz = strlen(contents);
e->size = sz;
if (sz > 0) {
assert(sz <= 512);
ClusterData *c = mkClusterData(sz);
c->st.st_mtime = c->st.st_ctime = time(NULL);
c->flags = F_TEXT;
strcpy(c->name, contents);
c->st.st_size = sz;
c->numclusters = 1;
addClusterData(c, e);
}
return e;
}
int baseLen(const char *a) {
int len = 0;
while (*a && *a != '.') {
a++;
len++;
}
return len;
}
int nameMatches(const char *a, const char *b) {
for (;;) {
if ((*a == 0 || *a == '.') && (*b == 0 || *b == '.'))
return 1;
if (*a != *b)
return 0;
a++;
b++;
}
}
void setFatNames(FsEntry *dirent) {
for (FsEntry *p = dirent; p; p = p->next) {
// check for collisions
int k = 1;
retry:
for (FsEntry *o = dirent; o && o != p; o = o->next) {
if (strcmp(o->fatname, p->fatname) == 0) {
char buf[20];
sprintf(buf, "~%d", k++);
int len = strlen(buf);
memcpy(p->fatname + 8 - len, buf, len);
goto retry;
}
}
DBG("setname: %s [%s] cl=%s @ %d sz=%d dents=%d", p->vfatname, p->fatname,
p->data ? p->data->name : "(no data)", p->startCluster, p->size, p->numdirentries);
}
}
void addFullDir(const char *mapName) {
int numEntries = 0;
FsEntry *dirents = NULL;
time_t mtime = 0, ctime = 0;
for (ClusterData *cl = readDir(mapName); cl; cl = cl->dnext) {
if (cl->cnext || cl == lastCluster)
continue; // already done
// vfat entries
const char *filename = strchr(cl->name, '/') + 1;
int len = baseLen(filename) + 4;
char namebuf[len];
memcpy(namebuf, filename, len - 4);
strcpy(namebuf + len - 4, ".uf2");
assert(cl->flags & F_UF2);
FsEntry *fent = mkFsEntry(namebuf);
numEntries += fent->numdirentries;
fent->next = dirents;
fent->data = cl;
fent->size = cl->numclusters * 512;
dirents = fent;
addClusterData(cl, fent);
for (ClusterData *other = cl->dnext; other; other = other->dnext) {
if (nameMatches(cl->name, other->name)) {
other->flags |= F_CONT;
fent->size += other->numclusters * 512;
addClusterData(other, fent);
}
}
if (mtime == 0) {
mtime = fent->mtime;
ctime = fent->ctime;
} else {
mtime = max(mtime, fent->mtime);
ctime = min(ctime, fent->ctime);
}
}
setFatNames(dirents);
FsEntry *dent = mkFsEntry(mapName);
dent->data = mkClusterData(0);
dent->data->dirdata = dirents;
dent->data->numclusters = (numEntries + 16) / 16; // at least 1
addClusterData(dent->data, dent);
dent->mtime = mtime;
dent->ctime = ctime;
dent->next = rootDir;
dent->attrs = 0x10;
dent->data->flags = F_DIR;
rootDir = dent;
}
void setupFs() {
addRootText("info_uf2.txt", infoUf2File);
addRootText("index.html", indexFile);
for (int i = 0; dirMaps[i].mapName; ++i) {
addFullDir(dirMaps[i].mapName);
}
setFatNames(rootDir); // make names unique
FsEntry *e = addRootText(BootBlock.VolumeLabel, "");
e->numdirentries = 1;
e->attrs = 0x28;
}
#define WRITE_ENT(v) \
do { \
if (skip++ >= 0) \
*dest++ = v; \
if (skip >= 256) \
return; \
cl++; \
} while (0)
void readFat(uint16_t *dest, int skip) {
int cl = 0;
skip = -skip;
WRITE_ENT(0xfff0);
WRITE_ENT(0xffff);
for (ClusterData *c = firstCluster; c; c = c->cnext) {
for (int i = 0; i < c->numclusters - 1; i++)
WRITE_ENT(cl + 1);
if (c->cnext && c->cnext->flags & F_CONT)
WRITE_ENT(cl + 1);
else
WRITE_ENT(0xffff);
}
}
// note that ptr might be unaligned
const char *copyVFatName(const char *ptr, void *dest, int len) {
uint8_t *dst = dest;
for (int i = 0; i < len; ++i) {
if (ptr == NULL) {
*dst++ = 0xff;
*dst++ = 0xff;
} else {
*dst++ = *ptr;
*dst++ = 0;
if (*ptr)
ptr++;
else
ptr = NULL;
}
}
return ptr;
}
uint8_t fatChecksum(const char *name) {
uint8_t sum = 0;
for (int i = 0; i < 11; ++i)
sum = ((sum & 1) << 7) + (sum >> 1) + *name++;
return sum;
}
void readDirData(uint8_t *dest, FsEntry *dirdata, int blkno) {
DirEntry *d = (void *)dest;
int idx = blkno * -16;
for (FsEntry *e = dirdata; e; e = e->next) {
if (idx >= 16)
break;
// DBG("dir idx=%d %s", idx, e->vfatname);
for (int i = 0; i < e->numdirentries; ++i, ++idx) {
if (0 <= idx && idx < 16) {
if (i == e->numdirentries - 1) {
memcpy(d->name, e->fatname, 11);
d->attrs = e->attrs;
d->size = e->size;
d->startCluster = e->startCluster;
timeToFat(e->mtime, &d->updateDate, &d->updateTime);
timeToFat(e->ctime, &d->createDate, &d->createTime);
} else {
VFatEntry *f = (void *)d;
int seq = e->numdirentries - i - 2;
f->seqno = seq + 1; // they start at 1
if (i == 0)
f->seqno |= 0x40;
f->attrs = 0x0F;
f->type = 0x00;
f->checksum = fatChecksum(e->fatname);
f->startCluster = 0;
const char *ptr = e->vfatname + (13 * seq);
ptr = copyVFatName(ptr, f->name0, 5);
ptr = copyVFatName(ptr, f->name1, 6);
ptr = copyVFatName(ptr, f->name2, 2);
}
d++;
}
}
}
}
void readBlock(uint8_t *dest, int blkno) {
// DBG("readbl %d", blkno);
int blkno0 = blkno;
for (ClusterData *c = firstCluster; c; c = c->cnext) {
// DBG("off=%d sz=%d", blkno, c->numclusters);
if (blkno >= c->numclusters) {
blkno -= c->numclusters;
continue;
}
// DBG("readbl off=%d %p", blkno, c);
if (c->dirdata) {
readDirData(dest, c->dirdata, blkno);
} else if (c->flags & F_TEXT) {
strcpy((char *)dest, c->name);
} else if (c->flags & F_UF2) {
UF2_Block *bl = (void *)dest;
bl->magicStart0 = UF2_MAGIC_START0;
bl->magicStart1 = UF2_MAGIC_START1;
bl->magicEnd = UF2_MAGIC_END;
bl->flags = UF2_FLAG_FILE;
bl->blockNo = blkno0 - (c->myfile->startCluster - 2);
bl->numBlocks = c->myfile->size / 512;
bl->targetAddr = blkno * 256;
bl->payloadSize = 256;
bl->fileSize = c->st.st_size;
int fd = open(expandMap(c->name), O_RDONLY);
if (fd >= 0) {
lseek(fd, bl->targetAddr, SEEK_SET);
bl->payloadSize = read(fd, bl->data, 256);
close(fd);
} else {
bl->payloadSize = -1;
}
if (bl->payloadSize < 475 - strlen(c->name))
strcpy((char *)bl->data + bl->payloadSize, c->name);
}
return;
}
}
void read_block(uint32_t block_no, uint8_t *data) {
memset(data, 0, 512);
uint32_t sectionIdx = block_no;
if (block_no == 0) {
memcpy(data, &BootBlock, sizeof(BootBlock));
data[510] = 0x55;
data[511] = 0xaa;
// logval("data[0]", data[0]);
} else if (block_no < START_ROOTDIR) {
sectionIdx -= START_FAT0;
if (sectionIdx >= SECTORS_PER_FAT) // second copy of fat?
sectionIdx -= SECTORS_PER_FAT;
readFat((void *)data, sectionIdx * 256);
} else if (block_no < START_CLUSTERS) {
sectionIdx -= START_ROOTDIR;
readDirData(data, rootDir, sectionIdx);
} else {
sectionIdx -= START_CLUSTERS;
readBlock(data, sectionIdx);
}
}
char rbfPath[300];
uint8_t stopApp[] = {
0x05, 0x00, // size
0x00, 0x00, // seq. no.
0x3f, 0x3d, // usb magic,
0x02, // req. no.
};
uint8_t runStart[] = {0x00, 0x00, // size
0x00, 0x00, // seq. no.
0x00, 0x00, 0x08, // something
0xC0, 0x08, 0x82, 0x01, 0x00, 0x84};
uint8_t runEnd[] = {0x00, 0x60, 0x64, 0x03, 0x01, 0x60, 0x64, 0x00};
#define FEED_DATA _IOC(_IOC_WRITE, 't', 108, 1024)
void startRbf() {
char buf[1024];
memset(buf, 0, sizeof(buf));
memcpy(buf, stopApp, sizeof(stopApp));
int fd = open("/dev/lms_usbdev", O_RDWR);
ioctl(fd, FEED_DATA, buf);
usleep(500000);
int off = 0;
memcpy(buf + off, runStart, sizeof(runStart));
off += sizeof(runStart);
strcpy(buf + off, rbfPath);
off += strlen(rbfPath);
memcpy(buf + off, runEnd, sizeof(runEnd));
off += sizeof(runEnd);
off -= 2;
buf[0] = off & 0xff;
buf[1] = off >> 8;
ioctl(fd, FEED_DATA, buf);
close(fd);
}
#define MAX_BLOCKS 8000
typedef struct {
uint32_t numBlocks;
uint32_t numWritten;
uint8_t writtenMask[MAX_BLOCKS / 8 + 1];
} WriteState;
void restartProgram() {
if (!rbfPath[0])
exit(0);
startRbf();
exit(0); // causes parent to eject MSD etc
}
int numWrites = 0;
static WriteState wrState;
void write_block(uint32_t block_no, uint8_t *data) {
WriteState *state = &wrState;
UF2_Block *bl = (void *)data;
if (bl->magicStart0 == 0x20da6d81 && bl->magicStart1 == 0x747e09d4) {
DBG("restart req, #wr=%d", numWrites);
if (numWrites) {
exit(0);
}
return;
}
numWrites++;
if (!is_uf2_block(bl)) {
return;
}
(void)block_no;
bl->data[475] = 0; // make sure we have NUL terminator
char *fn0 = (char *)bl->data + bl->payloadSize;
int namelen = 0;
if (bl->payloadSize <= UF2_MAX_PAYLOAD) {
namelen = strlen(fn0);
}
if ((bl->flags & UF2_FLAG_FILE) && bl->fileSize <= UF2_MAX_FILESIZE &&
bl->targetAddr < bl->fileSize && 1 <= namelen && namelen <= UF2_FILENAME_MAX) {
char *firstSL = strchr(fn0, '/');
char *lastSL = strrchr(fn0, '/');
if (!lastSL)
lastSL = fn0;
else
lastSL++;
int baseLen = strlen(lastSL);
char fallback[strlen(dirMaps[0].fsName) + 1 + baseLen + 1];
sprintf(fallback, "%s/%s", dirMaps[0].fsName, lastSL);
char *fn = NULL;
if (firstSL && firstSL + 1 == lastSL)
fn = expandMap(fn0);
if (!fn)
fn = fallback;
char *p = strrchr(fn, '/');
*p = 0;
mkdir(fn, 0777);
*p = '/';
int fd = open(fn, O_WRONLY | O_CREAT, 0777);
if (fd < 0 && errno == ETXTBSY) {
unlink(fn);
fd = open(fn, O_WRONLY | O_CREAT, 0777);
}
if (fd >= 0) {
ftruncate(fd, bl->fileSize);
lseek(fd, bl->targetAddr, SEEK_SET);
// DBG("write %d bytes at %d to %s", bl->payloadSize, bl->targetAddr, fn);
write(fd, bl->data, bl->payloadSize);
close(fd);
if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".rbf")) {
strcpy(rbfPath, fn);
}
}
}
if (state && bl->numBlocks) {
if (state->numBlocks != bl->numBlocks) {
if (bl->numBlocks >= MAX_BLOCKS || state->numBlocks)
state->numBlocks = 0xffffffff;
else
state->numBlocks = bl->numBlocks;
}
if (bl->blockNo < MAX_BLOCKS) {
uint8_t mask = 1 << (bl->blockNo % 8);
uint32_t pos = bl->blockNo / 8;
if (!(state->writtenMask[pos] & mask)) {
// logval("incr", state->numWritten);
state->writtenMask[pos] |= mask;
state->numWritten++;
DBG("write %d/%d #%d", state->numWritten, state->numBlocks, bl->blockNo);
}
if (state->numWritten >= state->numBlocks) {
restartProgram();
}
}
} else {
// TODO timeout for restart?
}
}

View File

@ -1,231 +0,0 @@
#define _GNU_SOURCE 1
#include <sys/types.h>
#include <linux/nbd.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdarg.h>
#include "uf2.h"
const char *dev_file = "/dev/nbd0";
#define NUM_BLOCKS NUM_FAT_BLOCKS
uint64_t ntohll(uint64_t a) {
return ((uint64_t)ntohl(a & 0xffffffff) << 32) | ntohl(a >> 32);
}
#define htonll ntohll
void mylog(const char *fmt, ...) {
va_list args;
char *p, *p2;
va_start(args, fmt);
vasprintf(&p, fmt, args);
vprintf(fmt, args);
va_end(args);
if (p[0] != '<')
asprintf(&p2, "<6>%s\n", p);
else
asprintf(&p2, "%s\n", p);
int len = strlen(p2);
#ifdef X86
write(2, p2, len);
#else
int fd = open("/dev/kmsg", O_WRONLY);
write(fd, p2, len);
close(fd);
#endif
free(p);
free(p2);
}
void readAll(int fd, void *dst, uint32_t length) {
while (length) {
int curr = read(fd, dst, length);
if (curr < 0)
FAIL("read failed on fd:%d", fd);
length -= curr;
dst = (char *)dst + curr;
}
}
void writeAll(int fd, void *dst, uint32_t length) {
while (length) {
int curr = write(fd, dst, length);
if (curr < 0)
FAIL("write failed on fd:%d", fd);
length -= curr;
dst = (char *)dst + curr;
}
}
int nbd;
int sock;
int sockets[2];
struct nbd_request request;
struct nbd_reply reply;
void nbd_ioctl(unsigned id, int arg) {
int err = ioctl(nbd, id, arg);
if (err < 0)
FAIL("ioctl(%ud) failed [%s]", id, strerror(errno));
}
void startclient() {
close(sockets[0]);
nbd_ioctl(NBD_SET_SOCK, sockets[1]);
nbd_ioctl(NBD_DO_IT, 0);
nbd_ioctl(NBD_CLEAR_QUE, 0);
nbd_ioctl(NBD_CLEAR_SOCK, 0);
exit(0);
}
void handleread(int off, int len) {
uint8_t buf[512];
LOG("read @%d len=%d", off, len);
reply.error = 0; // htonl(EPERM);
writeAll(sock, &reply, sizeof(struct nbd_reply));
for (int i = 0; i < len; ++i) {
read_block(off + i, buf);
writeAll(sock, buf, 512);
}
}
void handlewrite(int off, int len) {
uint8_t buf[512];
LOG("write @%d len=%d", off, len);
for (int i = 0; i < len; ++i) {
readAll(sock, buf, 512);
write_block(off + i, buf);
}
reply.error = 0;
writeAll(sock, &reply, sizeof(struct nbd_reply));
}
void setupFs();
void runNBD() {
setupFs();
int err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
assert(err >= 0);
nbd = open(dev_file, O_RDWR);
assert(nbd >= 0);
nbd_ioctl(BLKFLSBUF, 0);
nbd_ioctl(NBD_SET_BLKSIZE, 512);
nbd_ioctl(NBD_SET_SIZE_BLOCKS, NUM_BLOCKS);
nbd_ioctl(NBD_CLEAR_SOCK, 0);
if (!fork())
startclient();
int fd = open(dev_file, O_RDONLY);
assert(fd != -1);
close(fd);
close(sockets[1]);
sock = sockets[0];
reply.magic = htonl(NBD_REPLY_MAGIC);
reply.error = htonl(0);
for (;;) {
// nbd_ioctl(BLKFLSBUF, 0); // flush buffers - we don't want the kernel to cache the writes
int nread = read(sock, &request, sizeof(request));
if (nread < 0) {
FAIL("nbd read err %s", strerror(errno));
}
if (nread == 0)
return;
assert(nread == sizeof(request));
memcpy(reply.handle, request.handle, sizeof(reply.handle));
reply.error = htonl(0);
assert(request.magic == htonl(NBD_REQUEST_MAGIC));
uint32_t len = ntohl(request.len);
assert((len & 511) == 0);
len >>= 9;
uint64_t from = ntohll(request.from);
assert((from & 511) == 0);
from >>= 9;
switch (ntohl(request.type)) {
case NBD_CMD_READ:
handleread(from, len);
break;
case NBD_CMD_WRITE:
handlewrite(from, len);
break;
case NBD_CMD_DISC:
return;
default:
FAIL("invalid cmd: %d", ntohl(request.type));
}
}
}
void enableMSD(int enabled) {
#ifndef X86
int fd = open("/sys/devices/platform/musb_hdrc/gadget/lun0/active", O_WRONLY);
write(fd, enabled ? "1" : "0", 1);
close(fd);
#else
LOG("fake enable MSD: %d", enabled);
#endif
}
int main(int argc, char **argv) {
#ifndef X86
daemon(0, 1);
#endif
if (argc > 1)
dev_file = argv[1];
for (;;) {
pid_t child = fork();
if (child == 0) {
runNBD();
return 0;
}
sleep(1);
enableMSD(1);
int wstatus = 0;
waitpid(child, &wstatus, 0);
enableMSD(0); // force "eject"
if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
LOG("abnormal child return, %d", child);
sleep(5);
} else {
sleep(2);
}
}
return 0;
}

View File

@ -1,46 +0,0 @@
#ifndef UF2_H
#define UF2_H 1
#include "uf2format.h"
#include <stdio.h>
#include <string.h>
#ifndef INDEX_URL
#define INDEX_URL "https://www.pxt.io/"
#endif
#define UF2_VERSION_BASE "v0.1.0"
// needs to be more than ~4200 and less than ~65000 (to force FAT16)
#define NUM_FAT_BLOCKS 65000
#define UF2_VERSION UF2_VERSION_BASE " F"
//! Static block size for all memories
#define UDI_MSC_BLOCK_SIZE 512L
void read_block(uint32_t block_no, uint8_t *data);
void write_block(uint32_t block_no, uint8_t *data);
#define CONCAT_1(a, b) a##b
#define CONCAT_0(a, b) CONCAT_1(a, b)
#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }
extern const char infoUf2File[];
void readAll(int fd, void *dst, uint32_t length);
STATIC_ASSERT(sizeof(UF2_Block) == 512);
void mylog(const char *fmt, ...);
#define FAIL(args...) \
do { \
mylog("<4>" args); \
exit(1); \
} while (0)
#define LOG mylog
#endif

View File

@ -1,48 +0,0 @@
#ifndef UF2FORMAT_H
#define UF2FORMAT_H 1
#include <stdint.h>
#include <stdbool.h>
// All entries are little endian.
// if you increase that, you will also need to update the linker script file
#define APP_START_ADDRESS 0x00002000
#define UF2_MAGIC_START0 0x0A324655UL // "UF2\n"
#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected
#define UF2_MAGIC_END 0x0AB16F30UL // Ditto
// If set, the block is "comment" and should not be flashed to the device
#define UF2_FLAG_NOFLASH 0x00000001
#define UF2_FLAG_FILE 0x00001000
#define UF2_FILENAME_MAX 150
#define UF2_MAX_PAYLOAD (476 - 10) // leaving some space for filename
// for this bootloader
#define UF2_MAX_FILESIZE (64 * 1024 * 1024)
typedef struct {
// 32 byte header
uint32_t magicStart0;
uint32_t magicStart1;
uint32_t flags;
uint32_t targetAddr;
uint32_t payloadSize;
uint32_t blockNo;
uint32_t numBlocks;
uint32_t fileSize;
// raw data, followed by filename (NUL-terminated) at payloadSize
uint8_t data[476];
// store magic also at the end to limit damage from partial block reads
uint32_t magicEnd;
} UF2_Block;
static inline bool is_uf2_block(void *data) {
UF2_Block *bl = (UF2_Block *)data;
return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&
bl->magicEnd == UF2_MAGIC_END;
}
#endif

View File

@ -1,106 +0,0 @@
#ifndef UF2_HID_H
#define UF2_HID_H 1
#define HF2_CMD_BININFO 0x0001
// no arguments
#define HF2_MODE_BOOTLOADER 0x01
#define HF2_MODE_USERSPACE 0x02
struct HF2_BININFO_Result {
uint32_t mode;
uint32_t flash_page_size;
uint32_t flash_num_pages;
uint32_t max_message_size;
};
#define HF2_CMD_INFO 0x0002
// no arguments
// results is utf8 character array
#define HF2_CMD_RESET_INTO_APP 0x0003
// no arguments, no result
#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004
// no arguments, no result
#define HF2_CMD_START_FLASH 0x0005
// no arguments, no result
#define HF2_CMD_WRITE_FLASH_PAGE 0x0006
struct HF2_WRITE_FLASH_PAGE_Command {
uint32_t target_addr;
uint32_t data[0];
};
// no result
#define HF2_CMD_CHKSUM_PAGES 0x0007
struct HF2_CHKSUM_PAGES_Command {
uint32_t target_addr;
uint32_t num_pages;
};
struct HF2_CHKSUM_PAGES_Result {
uint16_t chksums[0 /* num_pages */];
};
#define HF2_CMD_READ_WORDS 0x0008
struct HF2_READ_WORDS_Command {
uint32_t target_addr;
uint32_t num_words;
};
struct HF2_READ_WORDS_Result {
uint32_t words[0 /* num_words */];
};
#define HF2_CMD_WRITE_WORDS 0x0009
struct HF2_WRITE_WORDS_Command {
uint32_t target_addr;
uint32_t num_words;
uint32_t words[0 /* num_words */];
};
// no result
#define HF2_CMD_DMESG 0x0010
// no arguments
// results is utf8 character array
typedef struct {
uint32_t command_id;
uint16_t tag;
uint8_t reserved0;
uint8_t reserved1;
union {
struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;
struct HF2_WRITE_WORDS_Command write_words;
struct HF2_READ_WORDS_Command read_words;
struct HF2_CHKSUM_PAGES_Command chksum_pages;
};
} HF2_Command;
typedef struct {
uint16_t tag;
union {
struct {
uint8_t status;
uint8_t status_info;
};
uint16_t status16;
};
union {
struct HF2_BININFO_Result bininfo;
uint8_t data8[0];
uint16_t data16[0];
uint32_t data32[0];
};
} HF2_Response;
#define HF2_FLAG_SERIAL_OUT 0x80
#define HF2_FLAG_SERIAL_ERR 0xC0
#define HF2_FLAG_CMDPKT_LAST 0x40
#define HF2_FLAG_CMDPKT_BODY 0x00
#define HF2_FLAG_MASK 0xC0
#define HF2_SIZE_MASK 63
#define HF2_STATUS_OK 0x00
#define HF2_STATUS_INVALID_CMD 0x01
#endif

View File

@ -1,16 +1,11 @@
/// <reference path="../node_modules/pxt-core/typings/globals/node/index.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
import * as fs from 'fs';
require("./editor")
declare namespace pxt.editor {
function deployCoreAsync(resp: pxtc.CompileResult, disconnect?: boolean): Promise<void>;
}
const deploy = require("./editor/deploy")
export function deployCoreAsync(resp: pxtc.CompileResult) {
return pxt.editor.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true)
return deploy.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true)
.then(() => {
fs.writeFileSync("built/full-" + pxtc.BINARY_UF2, resp.outfiles[pxtc.BINARY_UF2], {
encoding: "base64"

View File

@ -1,4 +1,3 @@
/// <reference path="../node_modules/pxt-core/typings/globals/node/index.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
import * as path from "path";

View File

@ -8,6 +8,7 @@
"module": "commonjs",
"rootDir": ".",
"newLine": "LF",
"sourceMap": false
"sourceMap": false,
"types": ["node"]
}
}

View File

@ -3,9 +3,3 @@
## Reference #reference
* [Reference](/reference)
* [input](/reference/input)
* [light](/reference/light)
* [music](/reference/music)
* [pins](/reference/pins)
* [control](/reference/control)
* [serial](/reference/serial)

171
docs/coding.md Normal file
View File

@ -0,0 +1,171 @@
# Coding Activites
12 computer science activities, with cross-curricular opportunities in design and technology, science, and math.
* [Download Curriculum Materials](https://education.lego.com/en-us/downloads/mindstorms-ev3)
## Three Point Turn
```codecard
[
{
"name": "Three Point Turn 1",
"description": "Activity 1",
"url":"/coding/three-point-turn-1",
"cardType": "example"
}, {
"name": "Three Point Turn 2",
"description": "Activity 2",
"url":"/coding/three-point-turn-2",
"cardType": "example"
}, {
"name": "Three Point Turn 3",
"description": "Activity 3",
"url":"/coding/three-point-turn-3",
"cardType": "example"
}]
```
## Reversing the robot
```codecard
[{
"name": "Reversing the robot 1",
"description": "Activity 1",
"url":"/coding/reversing-the-robot-1",
"cardType": "example"
}, {
"name": "Reversing the robot 2",
"description": "Activity 2",
"url":"/coding/reversing-the-robot-2",
"cardType": "example"
}, {
"name": "Reversing the robot 3",
"description": "Activity 3",
"url":"/coding/reversing-the-robot-3",
"cardType": "example"
}]
```
## Light the way
```codecard
[{
"name": "Light the way 1",
"description": "Activity 1",
"url":"/coding/light-the-way-1",
"cardType": "example"
}, {
"name": "Light the way 2",
"description": "Activity 2",
"url":"/coding/light-the-way-2",
"cardType": "example"
}, {
"name": "Light the way 3",
"description": "Activity 3",
"url":"/coding/light-the-way-3",
"cardType": "example"
}
]
```
## Traffic Lights
```codecard
[{
"name": "Traffic Lights 1",
"description": "Activity 1",
"url":"/coding/traffic-lights-1",
"cardType": "example"
}, {
"name": "Traffic Lights 2",
"description": "Activity 2",
"url":"/coding/traffic-lights-2",
"cardType": "example"
}, {
"name": "Traffic Lights 3",
"description": "Activity 3",
"url":"/coding/traffic-lights-3",
"cardType": "example"
}
]
```
## Reverse Bepper
```codecard
[{
"name": "Reverse Beeper 1",
"description": "Activity 1",
"url":"/coding/reverse-beeper-1",
"cardType": "example"
}, {
"name": "Reverse Beeper 2",
"description": "Activity 2",
"url":"/coding/reverse-beeper-2",
"cardType": "example"
}, {
"name": "Reverse Beeper 3",
"description": "Activity 3",
"url":"/coding/reverse-beeper-3",
"cardType": "example"
}]
```
## Ignition
```codecard
[{
"name": "Ignition 1",
"description": "Activity 1",
"url":"/coding/ingition-1",
"cardType": "example"
}, {
"name": "Ignition 2",
"description": "Activity 2",
"url":"/coding/ignition-2",
"cardType": "example"
}, {
"name": "Ignition 3",
"description": "Activity 3",
"url":"/coding/ignition-3",
"cardType": "example"
}]
```
## Cruise Control
```codecard
[{
"name": "Cruise Control 1",
"description": "Activity 1",
"url":"/coding/cruise-control-1",
"cardType": "example"
}, {
"name": "Cruise Control 2",
"description": "Activity 2",
"url":"/coding/cruise-control-2",
"cardType": "example"
}, {
"name": "Cruise Control 3",
"description": "Activity 3",
"url":"/coding/cruise-control-3",
"cardType": "example"
}]
```
## Roaming
```codecard
[{
"name": "Roaming 1",
"description": "Activity 1",
"url":"/coding/roaming-1",
"cardType": "example"
}, {
"name": "Roaming 2",
"description": "Activity 2",
"url":"/coding/roaming-2",
"cardType": "example"
}]
```

View File

@ -0,0 +1,10 @@
# Cruise Control Activity 1
```blocks
let speed = 0;
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
if (speed < 100)
speed = speed + 10;
motors.largeBC.setSpeed(speed);
})
```

View File

@ -0,0 +1,15 @@
# Cruise Control Activity 2
```blocks
let speed = 0;
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
if (speed < 100)
speed = speed + 10;
motors.largeBC.setSpeed(speed);
})
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {
if (speed > -100)
speed = speed - 10;
motors.largeBC.setSpeed(speed);
})
```

View File

@ -0,0 +1,28 @@
# Cruise Control Activity 3
```blocks
let speed = 0
function decelerate() {
if (speed > -100) {
speed = speed - 10
}
}
function accelerate() {
if (speed < 100) {
speed = speed + 10
}
}
function update() {
brick.clearScreen()
brick.showString("speed: " + speed, 1)
motors.largeBC.setSpeed(speed)
}
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {
accelerate()
update()
})
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
decelerate()
update()
})
```

11
docs/coding/ignition-1.md Normal file
View File

@ -0,0 +1,11 @@
# Ignition Activity 1
```blocks
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
brick.showImage(images.eyesDizzy)
})
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjectDetected, function () {
brick.showImage(images.eyesTiredMiddle)
})
brick.showImage(images.eyesSleeping)
```

12
docs/coding/ignition-2.md Normal file
View File

@ -0,0 +1,12 @@
# Ignition Activity 2
```blocks
while (true) {
if (sensors.touch1.wasPressed() &&
sensors.ultrasonic4.distance() < 10) {
music.playSoundEffectUntilDone(sounds.mechanicalMotorStart)
music.playSoundEffectUntilDone(sounds.mechanicalMotorIdle);
}
loops.pause(1);
}
```

13
docs/coding/ignition-3.md Normal file
View File

@ -0,0 +1,13 @@
# Ignition Activity 3
```blocks
while (true) {
if (sensors.ultrasonic4.distance() < 10 &&
sensors.touch1.wasPressed() &&
brick.buttonEnter.wasPressed()) {
music.playSoundEffectUntilDone(sounds.mechanicalMotorStart)
music.playSoundEffectUntilDone(sounds.mechanicalMotorIdle);
}
loops.pause(1);
}
```

View File

@ -0,0 +1,9 @@
# Light the way Activity 1
```blocks
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
brick.showImage(images.objectsLightOn)
loops.pause(5000)
brick.clearScreen()
})
```

View File

@ -0,0 +1,10 @@
# Light the way Activity 2
```blocks
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Bright, function () {
brick.clearScreen()
})
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
brick.showImage(images.objectsLightOn)
})
```

View File

@ -0,0 +1,13 @@
# Light the way Activity 3
```blocks
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Bright, function () {
brick.clearScreen()
})
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
brick.showImage(images.objectsLightOn)
})
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
brick.showImage(images.objectsLightOn);
})
```

View File

@ -0,0 +1,11 @@
# Reverse Beeper Activity 1
```blocks
loops.forever(function () {
music.playTone(440, sensors.ultrasonic4.distance());
loops.pause(50)
})
motors.largeBC.setSpeed(-20);
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.stop();
```

View File

@ -0,0 +1,13 @@
# Reverse Beeper Activity 2
```blocks
loops.forever(function () {
if (motors.largeB.speed() != 0 && sensors.ultrasonic4.distance() < 20) {
music.playTone(440, sensors.ultrasonic4.distance());
loops.pause(50)
}
})
motors.largeBC.setSpeed(-20);
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.stop();
```

View File

@ -0,0 +1,20 @@
# Reverse Beeper Activity 2
```blocks
let beep = false
beep = true
control.runInBackground(function () {
motors.largeBC.setSpeed(-20)
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear)
motors.largeBC.stop()
beep = false
})
control.runInBackground(function () {
while (beep) {
if (sensors.ultrasonic4.distance() < 20) {
music.playTone(440, sensors.ultrasonic4.distance())
loops.pause(50)
}
}
})
```

View File

@ -0,0 +1,14 @@
# Reversing the robot Activity 1
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
motors.largeBC.setSpeed(50)
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
motors.largeBC.setSpeed(0)
loops.pause(1000)
brick.setLight(LightsPattern.OrangeFlash)
motors.largeBC.setSpeed(-50)
loops.pause(2000)
motors.largeBC.setSpeed(0)
})
```

View File

@ -0,0 +1,15 @@
# Reversing the robot Activity 2
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
motors.largeBC.setSpeed(50)
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
motors.largeBC.setSpeed(0)
loops.pause(1000)
brick.setLight(LightsPattern.OrangeFlash)
motors.largeBC.setSpeed(-50)
loops.pause(2000)
motors.largeBC.setSpeed(0)
})
```

View File

@ -0,0 +1,19 @@
# Reversing the robot Activity 3
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
brick.showImage(images.eyesSleeping)
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
brick.showImage(images.eyesNeutral)
motors.largeBC.setSpeed(50)
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
brick.showImage(images.eyesTiredMiddle)
motors.largeBC.setSpeed(0)
loops.pause(1000)
brick.setLight(LightsPattern.OrangeFlash)
brick.showImage(images.eyesDizzy)
motors.largeBC.setSpeed(-50)
loops.pause(2000)
motors.largeBC.setSpeed(0)
})
```

36
docs/coding/roaming-1.md Normal file
View File

@ -0,0 +1,36 @@
# Roaming Activity 1
```blocks
let drive: number[] = []
brick.buttonLeft.onEvent(ButtonEvent.Click, function () {
drive.push(1)
})
brick.buttonRight.onEvent(ButtonEvent.Click, function () {
drive.push(3)
})
brick.buttonUp.onEvent(ButtonEvent.Click, function () {
drive.push(4)
})
brick.buttonDown.onEvent(ButtonEvent.Click, function () {
drive.push(5)
})
pauseUntil(() => drive.length >= 5)
loops.pause(1000)
music.playSoundEffectUntilDone(sounds.communicationGo)
for (let d of drive) {
if (d == 1) {
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeC.pauseUntilReady()
} else if (d == 3) {
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeB.pauseUntilReady()
} else if (d == 4) {
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeBC.pauseUntilReady()
} else {
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
motors.largeBC.pauseUntilReady()
}
}
music.playSoundEffectUntilDone(sounds.communicationGameOver)
```

40
docs/coding/roaming-2.md Normal file
View File

@ -0,0 +1,40 @@
# Roaming Activity 2
```blocks
let drive: number[] = []
brick.buttonLeft.onEvent(ButtonEvent.Click, function () {
drive.push(1)
music.playSoundEffectUntilDone(sounds.systemClick)
})
brick.buttonRight.onEvent(ButtonEvent.Click, function () {
drive.push(3)
music.playSoundEffectUntilDone(sounds.systemClick)
})
brick.buttonUp.onEvent(ButtonEvent.Click, function () {
drive.push(4)
music.playSoundEffectUntilDone(sounds.systemClick)
})
brick.buttonDown.onEvent(ButtonEvent.Click, function () {
drive.push(5)
music.playSoundEffectUntilDone(sounds.systemClick)
})
brick.buttonEnter.pauseUntil(ButtonEvent.Click);
loops.pause(1000)
music.playSoundEffectUntilDone(sounds.communicationGo)
for (let d of drive) {
if (d == 1) {
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeC.pauseUntilReady()
} else if (d == 3) {
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeB.pauseUntilReady()
} else if (d == 4) {
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
motors.largeBC.pauseUntilReady()
} else {
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
motors.largeBC.pauseUntilReady()
}
}
music.playSoundEffectUntilDone(sounds.communicationGameOver)
```

View File

@ -0,0 +1,12 @@
# Three Point Turn Activity 1
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
motors.largeBC.tank(75, 30)
loops.pause(1500)
motors.largeBC.tank(-30, -75)
loops.pause(1000)
motors.largeBC.tank(50, 50)
loops.pause(3000)
})
```

View File

@ -0,0 +1,14 @@
# Three Point Turn Activity 2
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
motors.largeBC.tank(75, 30)
loops.pause(1500)
motors.largeBC.tank(-30, -75)
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.tank(0, 0)
loops.pause(1000)
motors.largeBC.tank(50, 50)
loops.pause(3000)
})
```

View File

@ -0,0 +1,15 @@
# Three Point Turn Activity 3
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
motors.largeBC.tank(75, 30)
loops.pause(1500)
motors.largeBC.tank(-30, -75)
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
motors.largeBC.tank(0, 0)
music.playSoundEffect(sounds.animalsDogBark1)
loops.pause(1000)
motors.largeBC.tank(50, 50)
loops.pause(3000)
})
```

View File

@ -0,0 +1,9 @@
# Traffic Lights Activity 1
```blocks
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
motors.largeBC.tank(20, 20)
sensors.color3.pauseForColor(ColorSensorColor.Red)
motors.largeBC.tank(0, 0)
})
```

View File

@ -0,0 +1,10 @@
# Traffic Lights Activity 2
```blocks
sensors.color3.onColorDetected(ColorSensorColor.Red, function () {
motors.largeBC.tank(0, 0)
})
sensors.color3.onColorDetected(ColorSensorColor.Green, function () {
motors.largeBC.tank(20, 20)
})
```

View File

@ -0,0 +1,11 @@
# Traffic Lights Activity 3
```blocks
loops.forever(function () {
if (sensors.color3.light(LightIntensityMode.Reflected) < 15) {
motors.largeBC.tank(30, 12)
} else {
motors.largeBC.tank(12, 30)
}
})
```

View File

@ -4,5 +4,12 @@ Here are some fun programs for your @boardname@!
## Fun stuff
Coming soon.
```codecard
[
{
"name": "Happy unhappy",
"description": "Keep your brick entertained and happy",
"url":"/examples/happy-unhappy",
"cardType": "example"
}]
```

View File

@ -0,0 +1,12 @@
# Happy unhappy
Use a touch sensor to make the brick happy.
```blocks
sensors.touchSensor1.onEvent(TouchSensorEvent.Pressed, function () {
brick.showImage(images.expressionsBigSmile)
})
sensors.touchSensor1.onEvent(TouchSensorEvent.Released, function () {
brick.showImage(images.expressionsSick)
})
```

View File

@ -0,0 +1,50 @@
# Gradien follower PID + calibration
```blocks
let lasterror = 0
let D = 0
let I = 0
let P = 0
let error = 0
let setpoint = 0
let max = 0
let min = 0
let v = 0
v = sensors.color3.light(LightIntensityMode.Reflected)
min = v
max = v
setpoint = v
while (!(brick.buttonEnter.wasPressed())) {
brick.clearScreen()
brick.showString("Move robot on terrain", 1)
brick.showString("Press ENTER when done", 2)
v = sensors.color3.light(LightIntensityMode.Reflected)
min = Math.min(min, v)
max = Math.max(max, v)
setpoint = (max + min) / 2
brick.showValue("v", v, 3)
brick.showValue("min", min, 4)
brick.showValue("max", v, 5)
brick.showValue("setpoint", setpoint, 6)
loops.pause(100)
}
loops.forever(function () {
brick.clearScreen()
v = sensors.color3.light(LightIntensityMode.Reflected)
brick.showValue("light", v, 1)
error = v - setpoint
brick.showValue("error", error, 2)
P = error * 5
brick.showValue("P", P, 3)
I = I + error * 0.01
brick.showValue("I", I, 4)
D = (error - lasterror) * 0.2
brick.showValue("D", D, 5)
motors.largeBC.steer(P + (I + D), 100)
lasterror = error
if (brick.buttonEnter.wasPressed()) {
motors.largeBC.setSpeed(0)
brick.buttonDown.pauseUntil(ButtonEvent.Click)
}
})
```

47
docs/maker.md Normal file
View File

@ -0,0 +1,47 @@
# Maker Activites
These six activities require the LEGO® MINDSTORMS® Education EV3 Core Set (45544). Supporting materials for teachers and middle school students are provided, offering everything teachers and students need to explore their inner makers as they follow the design process to solve open-ended, themed challenges...
* [Download Curriculum Materials](https://education.lego.com/en-us/downloads/mindstorms-ev3)
## Activites
```codecard
[
{
"name": "Sound Machine",
"description": "Create instruments with your EV3 Brick!",
"url":"/maker/sound-machine",
"cardType": "example",
"imageUrl": "/static/maker/sound-machine.png"
},
{
"name": "Sound Of Color",
"description": "Play different sounds based on the color",
"url":"/maker/sound-of-color",
"cardType": "example",
"imageUrl": "/static/maker/sound-of-color.png"
},
{
"name": "Security Gadget",
"description": "Raise the alarm when your brick is lifted!",
"url":"/maker/security-gadget",
"cardType": "example",
"imageUrl": "/static/maker/security-gadget.png"
},
{
"name": "Intruder Detector",
"description": "Raise the alarm when an intruder sneaks in",
"url":"/maker/intruder-detector",
"cardType": "example",
"imageUrl": "/static/maker/intruder-detector.png"
},
{
"name": "Puppet",
"description": "Build an automated puppet",
"url":"/maker/puppet",
"cardType": "example",
"imageUrl": "/static/maker/puppet.png"
}
]
```

View File

@ -0,0 +1,11 @@
# Intruder Detector
This program will activate an alarm when an object moves in front of the Ultrasonic Sensor.
TODO support for event when value changes
```blocks
input.ultrasonic4.onObjectNear(function () {
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
})
```

17
docs/maker/puppet.md Normal file
View File

@ -0,0 +1,17 @@
# Puppet
Use this program with the Programmable Brick and Large Motor.
```blocks
loops.forever(function () {
output.largeMotorA.setPower(30)
output.largeMotorA.on(true)
loops.pause(100)
output.largeMotorA.on(false)
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
output.largeMotorA.setPower(-30)
output.largeMotorA.on(true)
loops.pause(100)
output.largeMotorA.on(false)
})
```

View File

@ -0,0 +1,9 @@
# Security Gadget
This program will activate an alarm when an object is lifted from the Touch Sensor.
```blocks
input.touchSensor1.onEvent(TouchSensorEvent.Released, function () {
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
})
```

View File

@ -0,0 +1,12 @@
# Sound Machine
This example program combined with the small model will make a beat and rhythm on any surface when the program is run.
```blocks
loops.forever(function () {
output.motorA.on(50)
loops.pause(200)
output.motorA.on(100)
loops.pause(200)
})
```

View File

@ -0,0 +1,15 @@
# Sound Of Color
This program will play different sounds when the wheel is rotated. The sound is determined by which color is placed in front of the color Sensor.
```blocks
input.color3.onColorDetected(ColorSensorColor.Blue, function () {
music.playTone(Note.G4, music.beat(BeatFraction.Half))
})
input.color3.onColorDetected(ColorSensorColor.Red, function () {
music.playTone(Note.C5, music.beat(BeatFraction.Half))
})
input.color3.onColorDetected(ColorSensorColor.Green, function () {
music.playTone(Note.D5, music.beat(BeatFraction.Half))
})
```

View File

@ -1,19 +1,8 @@
# Reference
```namespaces
input.onGesture(Gesture.Shake, () => {})
light.showRing('red red red red red red red red red red')
music.playTone(0, 0)
pins.pulseDuration()
control.runInBackground(() => {})
serial.writeLine("");
```
## See Also
[blocks](/blocks), [JavaScript](/javascript), [input](/reference/input), [light](/reference/light), [music](/reference/music),
[control](/reference/control), [pins](/reference/pins), [serial](/reference/serial)
```package
circuit-playground
```
[touch sensor](/reference/sensors/touch-sensor),
[color sensor](/reference/sensors/color-sensor)

BIN
docs/static/MC-LEGO-loader-eyes.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

93
docs/static/fonts/icons/iconfont.css vendored Normal file
View File

@ -0,0 +1,93 @@
@font-face {
font-family: "iconfont";
src: url("iconfont.eot?8b7e57577c2d1f1ae9e810b9e010bc84?#iefix") format("embedded-opentype"),
url("iconfont.woff2?8b7e57577c2d1f1ae9e810b9e010bc84") format("woff2"),
url("iconfont.woff?8b7e57577c2d1f1ae9e810b9e010bc84") format("woff");
}
.icon {
line-height: 1;
}
.icon:before {
font-family: iconfont !important;
font-style: normal;
font-weight: normal !important;
vertical-align: top;
}
.icon-ultrasonic:before {
content: "\f101";
}
.icon-color:before {
content: "\f102";
}
.icon-touch:before {
content: "\f103";
}
.icon-gyro:before {
content: "\f104";
}
.icon-addpackage:before {
content: "\f105";
}
.icon-brick:before {
content: "\f106";
}
.icon-controls:before {
content: "\f107";
}
.icon-functions:before {
content: "\f108";
}
.icon-list:before {
content: "\f109";
}
.icon-logic:before {
content: "\f10a";
}
.icon-loops:before {
content: "\f10b";
}
.icon-math:before {
content: "\f10c";
}
.icon-motors:before {
content: "\f10d";
}
.icon-music:before {
content: "\f10e";
}
.icon-sensors:before {
content: "\f10f";
}
.icon-text:before {
content: "\f110";
}
.icon-variables:before {
content: "\f111";
}
.icon-console:before {
content: "\f112";
}
.icon-advancedcollapsed:before {
content: "\f113";
}
.icon-advancedexpanded:before {
content: "\f114";
}
.icon-cancel:before {
content: "\f115";
}
.icon-check:before {
content: "\f116";
}
.icon-download:before {
content: "\f117";
}
.icon-save:before {
content: "\f118";
}
.icon-blocks:before {
content: "\f119";
}

BIN
docs/static/fonts/icons/iconfont.eot vendored Normal file

Binary file not shown.

87
docs/static/fonts/icons/iconfont.svg vendored Normal file
View File

@ -0,0 +1,87 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<font id="iconfont" horiz-adv-x="40">
<font-face font-family="iconfont"
units-per-em="40" ascent="40"
descent="0" />
<missing-glyph horiz-adv-x="0" />
<glyph glyph-name="ultrasonic"
unicode="&#xF101;"
horiz-adv-x="40" d=" M26.8 13H13.1C15.6 14.6 17 17.3 17 20.2C17 21.8 16.6 23.3 15.8 24.7S13.8 27 12.4 27.8H27.6C26.2 27 25.1 26.1 24.2 24.7S23 21.8 23 20.2C22.9 17.3 24.3 14.6 26.8 13L26.8 13L26.8 13z M8.6 12C4.1 12 0.4 15.7 0.4 20.2S4.1 28.4 8.6 28.4S16.8 24.7 16.8 20.2C16.7 15.7 13.1 12 8.6 12zM8.6 23.4C6.8 23.4 5.4 22 5.4 20.2S6.8 16.9 8.6 16.9S11.9 18.4 11.9 20.2S10.4 23.4 8.6 23.4z M31.4 12C26.9 12 23.2 15.7 23.2 20.2S26.9 28.4 31.4 28.4S39.6 24.7 39.6 20.2C39.5 15.7 35.9 12 31.4 12zM31.4 23.4C29.6 23.4 28.1 22 28.1 20.2S29.6 16.9 31.4 16.9S34.6 18.4 34.6 20.2S33.2 23.4 31.4 23.4z" />
<glyph glyph-name="color"
unicode="&#xF102;"
horiz-adv-x="43.35195530726257" d=" M38.7 -0.1H4.7C3.4 -0.1 2.5 0.6 2.5 1.5V6.8H0.9A0.9608938547486034 0.9608938547486034 0 0 0 0 7.7V31.5A0.9608938547486034 0.9608938547486034 0 0 0 0.9 32.4H2.5V38.4C2.5 39.3 3.6 40 4.7 40H38.7C40 40 40.9 39.3 40.9 38.4V32.4H42.5A0.9608938547486034 0.9608938547486034 0 0 0 43.4 31.5V7.8A0.9608938547486034 0.9608938547486034 0 0 0 42.5 6.9H40.9V1.6C41.1 0.7 40 -0.1 38.7 -0.1zM21.7 35.1A11.374301675977657 11.374301675977657 0 0 1 13.6 15.5A4.916201117318437 4.916201117318437 0 0 1 13.4 13.7A8.268156424581006 8.268156424581006 0 0 1 29.9 13.7A4.916201117318437 4.916201117318437 0 0 1 29.7 15.5A12.379888268156424 12.379888268156424 0 0 1 33.1 23.6A11.1731843575419 11.1731843575419 0 0 1 21.7 35.1zM41.6 18.3V10.9H42.5V18.3zM1.1 18.3V10.9H2V18.3zM41.6 28.6V21.2H42.5V28.6zM1.1 28.6V21.2H2V28.6z M21.9 7.4A6.480446927374302 6.480446927374302 0 0 0 15.4 13.9A9.497206703910615 9.497206703910615 0 0 0 15.9 16.3A9.87709497206704 9.87709497206704 0 0 0 12.3 23.9A9.608938547486035 9.608938547486035 0 0 0 31.5 23.9A9.87709497206704 9.87709497206704 0 0 0 27.9 16.3A8.022346368715086 8.022346368715086 0 0 0 28.4 13.9A6.703910614525141 6.703910614525141 0 0 0 21.9 7.4zM21.9 16.3A2.4581005586592184 2.4581005586592184 0 1 1 24.4 13.9A2.837988826815643 2.837988826815643 0 0 1 21.9 16.3zM21.9 27.7A4.46927374301676 4.46927374301676 0 1 1 26.4 23.2A4.804469273743018 4.804469273743018 0 0 1 21.9 27.7z" />
<glyph glyph-name="touch"
unicode="&#xF103;"
horiz-adv-x="40" d=" M34.3 3.3H4.9C3.8 3.3 2.8 3.9 2.8 4.8V9.3H1.5C1.1 9.3 0.7 9.7 0.7 10.1V30.5C0.7 30.9 1.1 31.3 1.5 31.3H2.8V36.6C2.8 37.4 3.7 38.1 4.9 38.1H16V36.6H22.7V38.1H34.2C35.3 38.1 36.3 37.5 36.3 36.6V31.3H37.6C37.9 31.3 38.3 30.9 38.3 30.5V10.1C38.3 9.7 37.9 9.3 37.6 9.3H36.3V4.8C36.3 3.9 35.3 3.3 34.3 3.3L34.3 3.3zM14.1 16.2C14.7 15.3 15.4 14.7 16.2 14.1V5.6H22.6V14.1C23.5 14.7 24.1 15.4 24.7 16.2H33.4V22.6H24.9C24.3 23.5 23.6 24.3 22.6 24.9V33.6H16.2V24.9C15.3 24.3 14.5 23.6 13.9 22.6H5.4V16.2H14.1L14.1 16.2zM36.6 19.2V13H37.4V19.2H36.6zM1.8 19.2V13H2.6V19.2H1.8zM36.6 28.1V21.9H37.4V28.1H36.6zM1.8 28.1V21.9H2.6V28.1H1.8zM19.4 15.4C18.8 15.4 18.5 15.4 18.1 15.6V17.1C18.1 17.5 17.9 17.7 17.5 17.7L17.5 17.7H16C15.8 18.1 15.6 18.6 15.6 19.2C15.6 19.8 15.6 20.3 16 20.7H17.3C18.1 20.7 18.1 21.6 18.1 21.6L18.1 21.6C18.1 21.8 18.1 22.4 18.1 22.9C18.5 23.1 19 23.1 19.4 23.1C20 23.1 20.5 23.1 21.1 22.9C21.1 22.5 21.1 22 21.1 21.6L21.1 21.6V21.4C21.1 21 21.3 20.8 21.7 20.8C21.7 20.8 21.7 20.8 21.9 20.8L21.9 20.8H23.4C23.8 20.4 23.8 19.9 23.8 19.3S23.6 18.2 23.4 17.8L23.4 17.8C23 17.8 22.5 17.6 22.1 17.6C21.7 17.6 21.3 17.4 21.3 17V15.5C20.7 15.3 20.4 15.3 19.8 15.3C19.4 15.4 19.4 15.4 19.4 15.4z" />
<glyph glyph-name="gyro"
unicode="&#xF104;"
horiz-adv-x="23.578015492438215" d=" M17 0H6.4A5.901881224640355 5.901881224640355 0 0 0 5.1 0.3H2.3A1.283659166359277 1.283659166359277 0 0 0 1 1.6V4.5H0.5A0.5016599040944301 0.5016599040944301 0 0 0 0 5V35.4A0.5016599040944301 0.5016599040944301 0 0 0 0.5 35.9H1V38.7A1.283659166359277 1.283659166359277 0 0 0 2.3 40H10.6V39.6H12.8V40H21.2A1.283659166359277 1.283659166359277 0 0 0 22.5 38.7V35.9H23.1A0.5016599040944301 0.5016599040944301 0 0 0 23.6 35.4V5.1A0.5016599040944301 0.5016599040944301 0 0 0 23.1 4.6H22.5V1.6A1.283659166359277 1.283659166359277 0 0 0 21.2 0.4H18.5C18.4 0.1 17.2 0 17 0zM6.2 34.5L3.7 33.8A1.0033198081888601 1.0033198081888601 0 0 1 3.4 33.7A0.2360752489856142 0.2360752489856142 0 0 1 3.3 33.5A0.20656584286241245 0.20656584286241245 0 0 1 3.4 33.3L4.1 32.8A7.657690888970861 7.657690888970861 0 0 1 3.1 30A8.51346366654371 8.51346366654371 0 0 1 4.8 23.5C5.8 24.2 6.5 24.7 6.5 24.7A7.377351530800443 7.377351530800443 0 0 0 5.4 26.9A6.300258207303577 6.300258207303577 0 0 0 6 31.8L6.5 31.5H6.5L6.6 31.5A0.3541128734784213 0.3541128734784213 0 0 1 6.8 31.4A0.17705643673921065 0.17705643673921065 0 0 1 7 31.5A0.6344522316488379 0.6344522316488379 0 0 1 7 32L6.2 34.5zM17.5 31.8H17.5A6.300258207303577 6.300258207303577 0 0 0 18 26.9A7.510143858354851 7.510143858354851 0 0 0 17 24.7L17.1 24.6L18.6 23.5A8.631501291036518 8.631501291036518 0 0 1 20.3 30A7.657690888970861 7.657690888970861 0 0 1 19.3 32.8L19.8 33.1L20 33.2A0.22132054592401326 0.22132054592401326 0 0 1 20.1 33.4A0.26558465510881596 0.26558465510881596 0 0 1 20 33.6A1.0033198081888601 1.0033198081888601 0 0 1 19.7 33.7L17.2 34.5S17.1 34.1 17 33.6S16.6 32.3 16.5 32A0.619697528587237 0.619697528587237 0 0 1 16.5 31.5A0.17705643673921065 0.17705643673921065 0 0 1 16.6 31.4A0.48690520103282936 0.48690520103282936 0 0 1 16.8 31.4L16.8 31.4L17.4 31.7zM11.7 30.6A1.9918849133161198 1.9918849133161198 0 1 1 13.7 28.6A1.9918849133161198 1.9918849133161198 0 0 1 11.7 30.6H11.7z" />
<glyph glyph-name="addpackage"
unicode="&#xF105;"
horiz-adv-x="40" d=" M20 35.7C11.3 35.7 4.3 28.7 4.3 20S11.3 4.3 20 4.3S35.7 11.3 35.7 20S28.7 35.7 20 35.7zM30.4 18.3H21.7V9.6H18.3V18.3H9.6V21.7H18.3V30.4H21.7V21.7H30.4V18.3z" />
<glyph glyph-name="brick"
unicode="&#xF106;"
horiz-adv-x="40" d=" M34.3 0.9H5.7V39.1H34.4V0.9zM10.4 32.7V18.4H29.6V32.7H10.4z" />
<glyph glyph-name="controls"
unicode="&#xF107;"
horiz-adv-x="40" d=" M6.1 33H9.6V5.2H6.1V33z M18.3 33H21.7V5.2H18.3V33z M30.4 33H33.9V5.2H30.4V33z M2.6 15.7H13V7H2.6V15.7z M14.8 31.3H25.2V22.6H14.8V31.3z M27 22.6H37.4V13.9H27V22.6z" />
<glyph glyph-name="functions"
unicode="&#xF108;"
horiz-adv-x="40" d=" M12.2 25.4H9.1C9.1 26.3 9.1 26.5 9.9 26.5C11.5 26.5 12.5 27.2 13.1 28.6C13.8 30.1 14.8 31.5 15.7 33.1C16.5 34.3 18.1 35.3 19.7 35.5C20.7 35.7 21.9 35.3 22.5 34.5C22.8 33.9 22.8 33.4 22.6 32.7C22.3 32.2 21.8 32 21.1 32.2C20.5 32.2 20.2 32.7 20.2 33.3C20.2 33.4 20.2 33.4 20.2 33.6C20.2 33.9 20.4 34.3 20.4 34.6C20 34.6 19.5 34.8 19.2 34.6C18.5 34.3 17.9 33.9 17.4 33.1C16.7 32 16.2 30.6 15.7 29.4C15.3 28.6 15 27.3 14.8 26.5H17.2C17.1 26.1 17.1 25.8 16.9 25.4H14.5C13.9 23.5 13.6 21.9 12.9 20.2C12.2 16.7 10.8 13.4 9.4 10.1C8.7 8.6 7.7 7.3 6.6 6.3C5.8 5.4 4.5 4.9 3.3 4.9C2.6 4.7 1.8 5.1 1.1 5.4C0.7 5.8 0.5 6.5 0.7 7.2C1.1 7.7 1.6 8 2.5 7.9C3 7.9 3.2 7.3 3.2 6.8C3.2 6.6 3 6.5 3 6.5C2.8 6.3 2.8 6.1 2.8 5.9C3 5.9 3.2 5.8 3.5 5.8C4.4 5.8 5.4 6.3 5.9 7.2C6.5 8 7 9.1 7.2 9.9C8.5 15.2 10.1 20.4 11.7 25.4C12.2 25.3 12.2 25.3 12.2 25.4z M32.5 4.7C32.7 4.9 32.7 5.1 32.9 5.3C34.8 6.3 36 8.4 36.4 10.5C37.1 13.9 37.1 17.4 36.2 20.9C35.7 22.8 34.5 24.2 33.1 25.4C32.9 25.6 32.7 25.8 32.7 25.9C36 24.7 39.2 20.6 39.2 15.3C39.3 10.8 36.7 6.5 32.5 4.7z M23.9 25.8C23.9 25.6 23.7 25.4 23.7 25.4C21.8 24.4 20.5 22.3 20.2 20.2C19.5 16.7 19.5 13.3 20.4 9.6C20.9 7.7 22.1 6.3 23.5 5.1C23.7 4.9 23.9 4.9 23.9 4.6C20 6.5 17.4 10.5 17.6 15C17.4 20.7 20.9 24.9 23.9 25.8z M32 12.2C32 12.2 32.2 12.2 32.4 12C32.4 12 32.4 12 32.4 11.9C31.9 11 31.3 10.1 30.3 9.6C29.9 9.3 29.2 9.1 28.5 9.6C28.4 9.8 28.2 9.9 28.2 10.3C27.9 11.3 27.7 12.4 27.5 13.4C27.5 13.6 27.5 13.6 27.3 13.8C27.2 13.4 27 13.1 26.6 12.7C26.1 12 25.6 11 24.7 10.3C24.4 9.9 24 9.6 23.5 9.4C23 9.3 22.5 9.4 21.9 9.9V10.1C21.9 10.5 21.9 10.8 22.3 11C22.5 11.2 22.8 11.2 23.2 11L23.3 10.8C23.9 10.5 24 10.3 24.4 11C25.1 12 25.9 13.4 26.8 14.5C26.8 14.6 26.8 14.8 26.8 15C26.6 15.7 26.5 16.6 26.3 17.3C25.9 18.5 25.4 19 24 19H23.9C23.7 19.2 23.9 19.3 24 19.3C24.7 19.5 25.8 19.7 26.5 19.7C26.6 19.7 26.8 19.7 27 19.5C27.5 18.8 27.9 18.1 28 17.1C28 16.9 28.2 16.6 28.2 16.4C28.4 16.7 28.7 17.3 29.1 17.6C29.6 18.1 30.1 18.8 30.8 19.3C31.2 19.5 31.5 19.7 31.9 19.7C32.4 19.7 32.7 19.3 32.7 18.8V18.6C32.5 18.1 32.2 17.9 31.7 18.1L31.7 18.1C31.5 18.1 31.5 18.1 31.3 18.1C30.8 18.5 30.1 18.3 29.6 17.8L29.6 17.8C29.2 17.3 28.7 16.6 28.4 15.9C28.4 15.7 28.4 15.7 28.4 15.5C28.7 14.3 28.9 12.9 29.2 11.5C29.2 11.3 29.2 11.3 29.4 11.2C29.6 10.6 29.9 10.5 30.3 11C31.3 11.3 31.5 11.9 32 12.2z" />
<glyph glyph-name="list"
unicode="&#xF109;"
horiz-adv-x="40" d=" M11.1 30.4H36.9V27.3H11.1V30.4z M11.1 22.4H36.9V19.3H11.1V22.4z M11.1 14.4H36.9V11.3H11.1V14.4z M5.6 27.3H3.8V33.6H2.4V34.6C3.3 34.6 4 35.1 4.2 36.2H5.6V27.3z M7.7 17.6V16H1.4V16.7C1.4 18.8 2.8 19.7 4 20.3C5.7 21.2 5.7 21.6 5.7 22.1C5.7 22.6 5.4 23.1 4.5 23.1C3.7 23.1 3.1 22.4 3.1 21.6H1.4C1.4 23.1 2.4 24.7 4.5 24.7C6.6 24.7 7.5 23.3 7.5 22.1C7.5 20.3 6.3 19.8 4.9 19C4 18.4 3.3 17.9 3.3 17.4H7.7z M4.5 4.5C2.4 4.5 1.4 5.9 1.2 7.5H3C3 6.6 3.5 6.1 4.5 6.1C5.6 6.1 6.1 6.6 6.1 7.3C6.1 8 5.6 8.5 4.7 8.5H4.2V9.9H4.5C5.6 9.9 5.9 10.4 5.9 11C5.9 11.7 5.4 12 4.7 12C3.8 12 3.3 11.3 3.3 10.6H1.6C1.6 12.2 2.6 13.6 4.5 13.6C6.4 13.6 7.5 12.3 7.5 11.1C7.5 10.4 7.1 9.7 6.3 9.4C7.3 9 7.7 8.2 7.7 7.3C7.8 6.1 6.8 4.5 4.5 4.5z" />
<glyph glyph-name="logic"
unicode="&#xF10A;"
horiz-adv-x="40" d=" M2.8 14.1H7.4C10 14.2 12.2 16 13.1 18.6C15 23.1 18.3 31.3 23.7 31.3S29.8 31.3 29.8 31.3V35.8L36.9 28.3L29.8 21.5V26.4H24.9C22.3 25.7 20.2 24 19.4 21.5C17.3 17 15.2 9.4 8.2 9.2C5.1 9.2 3 9.2 3 9.2V14.1z M2.8 31.1V26.2H8.2C8.2 26.2 11.4 26.2 13.1 22.1C13.8 23.8 14.7 25.4 15.7 26.9C15.7 26.9 12.2 30.9 8.4 30.9S2.8 31.1 2.8 31.1z M19.5 18.4C19.5 18.4 21.8 13.9 24.4 13.9H30V18.4L37.3 11.3L30 4.2V9H23.7C23.7 9 20.2 9 16.9 13.4C18 14.9 18.8 16.7 19.5 18.4z" />
<glyph glyph-name="loops"
unicode="&#xF10B;"
horiz-adv-x="40" d=" M6.3 12.7C4.5 15.2 2.6 17.4 0.9 20H4.5C4.5 24.2 6.3 28.4 9.2 31.3C11.3 33.4 13.7 34.8 16.7 35.3C21.9 36.6 27.3 35 31.1 31.2C30.3 30.3 29.4 29.4 28.7 28.7C24.2 32.6 19.3 33.3 14.1 30.5C10.3 28.4 8.2 24.4 8.2 20.2H11.8C9.7 17.6 7.8 15 6.3 12.7z M32.2 20H28.5C30.4 22.5 32.2 24.7 33.9 27.3C35.8 24.9 37.6 22.6 39.3 20H35.6C35.6 15.7 33.7 11.5 30.6 8.6C28.5 6.6 26.1 5.3 23.3 4.7C18.1 3.5 12.7 5.1 8.9 8.9L11.3 11.3C15.6 7.5 20.7 6.6 25.9 9.6C29.9 11.7 32.2 15.7 32.2 20z" />
<glyph glyph-name="math"
unicode="&#xF10C;"
horiz-adv-x="40" d=" M15.2 5.3C14.9 4.9 14.2 4.2 13.8 3.9L9.3 8.4C7.6 6.7 6.2 5.3 4.8 3.9C4.4 4.2 3.8 4.9 3.4 5.3L7.9 9.8C6.2 11.5 4.8 12.9 3.4 14.3C3.8 14.7 4.4 15.4 4.8 15.7L9.3 11.2L13.8 15.7C14.2 15.4 14.9 14.7 15.2 14.3L10.7 9.8C12.1 8.2 13.7 6.7 15.2 5.3z M1.5 28V30H7.9V36.4C8.6 36.4 9.1 36.4 9.8 36.4V30H16.3V28H9.8V21.6H7.8V28H1.5z M38.4 10.7H22V14.1H38.4V10.7z M38.4 7.2V3.7H22V7.2H38.4z M38.4 31V27.5H22V31H38.4z" />
<glyph glyph-name="motors"
unicode="&#xF10D;"
horiz-adv-x="40" d=" M28.9 25.8C27.5 24.4 25.9 22.9 24.5 21.5H35.7V32.6L32.2 29.1C29.6 32.3 25.9 34.3 21.8 34.9C18.3 35.4 14.6 34.5 11.7 32.6C4.2 28.1 1.9 18.3 6.5 10.9S20.7 1.1 28.2 5.6C30.8 7.2 32.7 9.5 34.1 12.1C32.7 12.6 31.3 13.3 29.9 13.8C28.5 11 25.9 9 23 8.1C20.7 7.4 18.3 7.6 16 8.4C10.3 10.7 7.3 17.1 9.4 22.9C10.6 26.3 13.6 29 17.1 29.8C21.6 31.2 26.3 29.5 28.9 25.8z M16.7 19C16.7 17.1 18.3 15.7 20 15.7S23.3 17.3 23.3 19C23.3 21 21.8 22.3 20 22.3C18.1 22.5 16.7 21 16.7 19C16.7 19 16.7 19 16.7 19z" />
<glyph glyph-name="music"
unicode="&#xF10E;"
horiz-adv-x="40" d=" M24.2 17.7C27.1 17.2 29.9 15.7 31.7 13.2C32.5 13.2 33.4 13.2 33.4 13.2S36 20.9 30.3 26.3S13.4 31.7 9.2 26.3C6.3 22.6 5.2 17.6 6.8 13.2C7.3 13.2 7.7 13.2 8.2 13.2C8.2 13.2 11.1 17.6 15.8 17.7C15.7 10.1 15.7 3.5 15.7 3.5C12.3 4.2 9.6 6.3 8 9.4C4.5 10.1 1.7 13.2 1.7 17C1.7 28.3 10.3 34.8 20 34.8S38.8 27.3 38.1 17C37.7 9.9 31.8 9.4 31.8 9.4C30.4 6.3 27.7 4 24.3 3.5C24.2 11.3 24.2 17.7 24.2 17.7z" />
<glyph glyph-name="sensors"
unicode="&#xF10F;"
horiz-adv-x="40" d=" M20 36.9C10.6 36.9 3 29.2 3 19.8C3 10.4 10.6 2.8 20 2.8S37 10.4 37 19.8C36.9 29.4 29.4 36.9 20 36.9zM20 8.2C13.4 8.2 8.2 13.6 8.2 20S13.6 31.8 20 31.8S31.8 26.4 31.8 20S26.6 8.2 20 8.2z M13.2 20C13.2 16.3 16.3 13.2 20 13.2C23.7 13.2 26.8 16.3 26.8 20C26.8 23.7 23.7 26.8 20 26.8C16.3 26.8 13.2 23.7 13.2 20z" />
<glyph glyph-name="text"
unicode="&#xF110;"
horiz-adv-x="40" d=" M23.1 30.6V2.8H16.5V30.6H7.7V36.7H32.3V30.6H23.1z" />
<glyph glyph-name="variables"
unicode="&#xF111;"
horiz-adv-x="40" d=" M36.8 12V7.8H3.4V12H36.8z M36.8 22.1V17.9H3.4V22.1H36.8z M36.7 32.2V28H3.3V32.2H36.7z" />
<glyph glyph-name="console"
unicode="&#xF112;"
horiz-adv-x="40" d=" M15.6 21.3L2.3 15L2.3 19.8L11.1 23.6L2.3 27.4L2.3 32.2L15.6 25.9L15.6 21.3z M36 9.1L16.6 9.1L16.6 12.2L36 12.2L36 9.1z" />
<glyph glyph-name="advancedcollapsed"
unicode="&#xF113;"
horiz-adv-x="40" d=" M39.7 28.2L36.2 31.5L20 15.3L3.8 31.5L0.3 28.2L18.3 10.3L18.3 10.3L20 8.5L20.5 9L20.5 9z" />
<glyph glyph-name="advancedexpanded"
unicode="&#xF114;"
horiz-adv-x="40" d=" M39.3 12L21.7 29.6L21.7 29.6L20 31.3L19.5 30.8L19.5 30.8L0.7 12L4 8.7L20 24.7L36 8.7z" />
<glyph glyph-name="cancel"
unicode="&#xF115;"
horiz-adv-x="40" d=" M33 29.6L29.4 33.2L20.2 24L11 33.2L7.3 29.6L16.5 20.3L7.3 11.1L11 7.3L20.2 16.5L29.4 7.3L33 11.1L23.8 20.3z" />
<glyph glyph-name="check"
unicode="&#xF116;"
horiz-adv-x="40" d=" M33.7 32.9L15.3 14.4L7.5 22.3L3.8 18.4L11.7 10.8L11.7 10.8L15.3 7.1L37.4 29.2z" />
<glyph glyph-name="download"
unicode="&#xF117;"
horiz-adv-x="40" d=" M5.2 15.7H36.5V1.7H5.2V15.7z M28.5 24.2L26.1 26.6L22.6 23.1L22.6 36.5L19.1 36.5L19.1 23.5L16 26.6L13.6 24.2L20.9 16.7L21 16.9L21.2 16.7z" />
<glyph glyph-name="save"
unicode="&#xF118;"
horiz-adv-x="40" d=" M25 34.5C25 33.6 25 32.8 25 31.9C25 31 24.7 30.9 24 30.9C23.5 30.9 22.8 30.9 22.4 30.9C22.1 30.9 21.4 31 21.4 31.7V31.9V36.9C21.4 37.3 21.6 37.8 22.3 38C22.3 38 22.3 38 22.4 38C23 38 23.7 38 24.2 38C24.7 38 25.2 37.6 25.2 37.1C25.2 37.1 25.2 37.1 25.2 36.9C25 36.3 25 35.2 25 34.5z M37.6 31.2C35.8 32.9 34.3 34.5 32.5 36.3C31 37.8 31 37.8 28.5 37.8C27.5 37.8 27.3 37.6 27.3 36.6V28.4C27.3 27.4 27.1 27.2 26.1 27.2H14.3C13.2 27.2 13 27.4 13 28.4V36.4C13 37.6 12.9 37.8 11.7 37.8H3.8C2.6 37.8 2.4 37.6 2.4 36.4V19.9C2.4 14.3 2.4 8.9 2.4 3.2C2.4 2 2.6 1.8 3.7 1.8H36.9C37.9 1.8 38.1 2.2 38.1 3.2V29.6C38.3 30.5 37.9 30.9 37.6 31.2zM33.7 6.7H7.1V23H33.7V6.7z" />
<glyph glyph-name="blocks"
unicode="&#xF119;"
horiz-adv-x="40" d=" M10.9 23H39V16.9H10.9V23z M39.2 27.1L39.2 33L0.9 33L0.9 31.1L0.9 27.1L0.9 12.9L0.9 7L39.2 7L39.2 12.9L6.9 12.9L6.9 27.1z" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/static/fonts/icons/iconfont.ttf vendored Normal file

Binary file not shown.

BIN
docs/static/fonts/icons/iconfont.woff vendored Normal file

Binary file not shown.

BIN
docs/static/fonts/icons/iconfont.woff2 vendored Normal file

Binary file not shown.

BIN
docs/static/hero.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

74
docs/static/lego-logo.svg vendored Normal file
View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="141.73"
height="141.731"
viewBox="0 0 141.73 141.73101"
enable-background="new 0 0 265.365 141.732"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="lego-logo.svg"><metadata
id="metadata26"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs24" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1199"
inkscape:window-height="604"
id="namedview22"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="1.6520876"
inkscape:cx="101.03204"
inkscape:cy="98.819336"
inkscape:window-x="372"
inkscape:window-y="149"
inkscape:window-maximized="0"
inkscape:current-layer="g6" /><g
id="product_logo" /><g
id="guides" /><g
id="LEGO_LOGO_SMALL_RGB"><g
id="g6"><path
d="m 0.961,0.948 0,139.839 139.84,0 0,-139.839 -139.84,0 z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 0.961,0.948 0,139.839 139.84,0 0,-139.839 -139.84,0 z m 130.536,58.127 c -0.23,4.356 -1.617,9.786 -2.839,13.414 -4.917,14.609 -10.618,23.666 -23.821,23.666 -3.887,0 -10.783,-1.031 -13.324,-7.947 l -0.602,-1.641 -1.082,1.371 C 85.7,93.168 79.564,96.186 72.998,96.217 67.96,96.24 63.912,94.553 61.293,91.334 l -0.718,-0.883 -0.765,0.844 c -2.797,3.088 -7.668,4.859 -13.364,4.859 -4.473,0 -8.335,-1.521 -10.876,-4.277 l -0.692,-0.752 -0.72,0.727 c -2.825,2.852 -7.276,4.289 -12.873,4.158 -6.79,-0.162 -10.924,-3.951 -11.058,-10.141 -0.205,-9.543 9.031,-29.622 12.854,-35.727 2.482,-4.078 5.895,-6.055 10.438,-6.055 3.092,0 5.207,0.646 6.463,1.977 1.144,1.211 1.37,2.232 1.472,4.688 l 0.131,3.175 1.676,-2.7 c 4.054,-6.532 10.773,-7.434 17.43,-7.434 4.628,0 8.667,1.702 10.289,4.336 l 0.599,0.971 0.866,-0.737 c 3.431,-2.916 8.271,-4.521 13.629,-4.521 5.849,0 10.099,1.454 12.634,4.322 0.576,0.651 0.957,1.106 1.486,2.219 l 0.651,1.366 0.977,-1.155 c 3.712,-4.39 8.779,-6.615 15.067,-6.615 4.98,0 8.761,1.324 11.235,3.935 3.104,3.271 3.547,7.875 3.373,11.161 z"
id="path10"
inkscape:connector-curvature="0"
style="fill:#f6ec36" /><path
d="m 0.961,0.948 0,139.839 139.84,0 0,-139.839 -139.84,0 z M 135.435,64.44 c -0.633,5.089 -4.072,14.518 -5.899,18.286 -4.903,10.102 -11.453,17.863 -24.074,17.863 -6.742,0 -12.288,-2.15 -15.531,-6.283 -4.749,4.162 -10.627,6.342 -16.956,6.342 -4.876,0 -9.185,-1.408 -12.471,-4.012 -3.626,2.555 -8.52,3.98 -13.943,3.98 -4.53,0 -8.606,-1.244 -11.796,-3.543 -3.529,2.342 -8.154,3.506 -13.583,3.377 C 12.149,100.237 5.912,94.507 5.733,86.188 5.497,75.137 14.803,54.911 19.189,47.907 c 3.282,-5.392 8.292,-8.293 14.431,-8.293 6.663,0 9.078,1.903 10.267,4.326 5.141,-4.366 11.956,-4.617 16.808,-4.617 5.356,0 8.717,1.422 11.575,3.697 3.948,-2.368 8.477,-3.599 13.871,-3.599 6.897,0 12.021,1.604 15.595,5.137 4.168,-3.469 9.388,-5.05 15.23,-5.05 7.725,0 12.808,2.786 15.793,6.94 4.203,5.859 3.451,11.757 2.676,17.992 z"
id="path12"
inkscape:connector-curvature="0"
style="fill:#d01012" /><path
d="m 0,0 0,141.731 141.73,0 L 141.73,0 0,0 Z m 139.781,1.952 0,137.832 -137.83,0 0,-137.832 137.83,0 z"
id="path14"
inkscape:connector-curvature="0" /><path
d="m 134.752,42.53 0,-0.965 0.655,0 c 0.479,0 0.728,0.168 0.728,0.479 0,0.247 -0.16,0.486 -0.647,0.486 l -0.736,0 z m 2.351,2.002 -0.408,-0.708 c -0.354,-0.619 -0.452,-0.717 -0.755,-0.823 l 0,-0.019 c 0.596,-0.07 0.95,-0.453 0.95,-0.983 0,-0.56 -0.354,-0.984 -1.109,-0.984 l -1.754,0 0,3.519 0.727,0 0,-1.441 0.133,0 c 0.311,0 0.435,0.035 0.576,0.176 0.142,0.144 0.354,0.443 0.479,0.69 l 0.284,0.575 0.877,-0.002 0,0 z m -1.731,-4.497 c 1.51,0 2.737,1.218 2.737,2.726 0,1.508 -1.229,2.731 -2.737,2.731 -1.506,0 -2.72,-1.225 -2.72,-2.731 0,-1.506 1.214,-2.726 2.72,-2.726 z m 0,-0.67 c -1.877,0 -3.392,1.516 -3.392,3.396 0,1.879 1.515,3.394 3.392,3.394 1.883,0 3.397,-1.515 3.397,-3.394 0.002,-1.882 -1.514,-3.396 -3.397,-3.396 z"
id="path16"
inkscape:connector-curvature="0" /><path
d="m 116.889,43.002 c -7.325,0 -12.386,2.904 -15.812,6.961 -0.579,-1.214 -1.019,-1.746 -1.638,-2.447 -2.805,-3.17 -7.313,-4.649 -13.364,-4.649 -5.912,0 -10.841,1.846 -14.263,4.754 -1.777,-2.89 -6.013,-4.803 -11.121,-4.803 -6.674,0 -13.946,0.944 -18.261,7.896 -0.104,-2.503 -0.33,-3.828 -1.737,-5.317 -1.71,-1.81 -4.477,-2.282 -7.173,-2.282 -4.912,0 -8.605,2.146 -11.266,6.515 -3.859,6.163 -13.212,26.441 -13.001,36.263 0.137,6.344 4.393,10.916 12.01,11.096 5.952,0.143 10.62,-1.449 13.59,-4.447 2.665,2.896 6.731,4.594 11.596,4.594 5.417,0 10.868,-1.627 14.088,-5.182 2.712,3.332 6.979,5.271 12.468,5.244 7.175,-0.035 13.477,-3.438 17.593,-8.652 2.259,6.148 7.985,8.59 14.241,8.59 13.709,0 19.729,-9.428 24.748,-24.332 1.13,-3.357 2.639,-8.963 2.889,-13.672 0.413,-7.839 -2.903,-16.13 -15.587,-16.13 z M 25.672,80.477 c 7.093,-1.232 8.876,1.332 8.653,3.707 -0.669,7.109 -7.191,8.699 -12.854,8.566 -4.107,-0.1 -7.8,-1.98 -7.903,-6.748 -0.18,-8.342 8.328,-27.641 12.333,-34.038 1.85,-3.037 4.104,-4.539 7.698,-4.539 3.406,0 4.25,1.749 4.2,3.844 -0.134,5.589 -9.164,22.574 -12.127,29.208 z M 48.77,73.925 c -0.469,1.27 -1.357,3.93 -2.076,6.75 2.328,-0.582 4.074,-0.986 7.065,-0.914 3.408,0.084 5.586,1.496 5.586,4.314 0,6.832 -7.551,8.838 -12.789,8.838 -5.751,0 -10.803,-3.275 -10.803,-9.564 0,-7.373 3.997,-18.553 7.748,-26.001 4.606,-9.146 9.312,-10.362 17.419,-10.362 3.562,0 7.667,1.524 7.667,4.888 0,4.662 -3.95,6.44 -7.866,6.665 -1.672,0.096 -4.246,0.188 -5.786,0.079 0,0 -1.303,1.985 -2.688,5.523 7.252,-1.021 10.327,0.625 9.103,4.82 -1.657,5.667 -6.567,6.04 -12.58,4.964 z M 84.438,56.293 c -1.961,0 -3.244,1.242 -4.198,2.583 -2.102,2.952 -6.656,14.781 -7.365,19.64 -0.486,3.328 0.951,4.006 2.522,4.006 2.52,0 5.345,-2.666 6.309,-7.064 0,0 -4.797,-0.117 -3.475,-4.371 1.285,-4.128 3.723,-5.022 7.764,-5.188 7.961,-0.325 7.175,5.553 6.538,8.688 -2.069,10.18 -9.314,18.355 -19.562,18.355 -7.016,0 -11.371,-3.881 -11.371,-11.035 0,-5.098 2.529,-13.101 4.534,-17.784 4.267,-9.968 8.742,-16.944 20.143,-16.944 6.84,0 12.235,2.458 11.444,8.866 -0.58,4.703 -2.934,7.465 -7.21,7.799 -1.196,0.093 -6.089,-0.031 -4.466,-4.66 0.565,-1.619 0.799,-2.891 -1.607,-2.891 z m 43.057,8.413 c -1.205,6.002 -3.916,13.101 -6.859,18.392 -4.801,8.633 -10.633,9.842 -15.723,9.781 -5.093,-0.061 -10.83,-1.941 -10.874,-9.795 -0.031,-5.639 2.401,-13.598 4.466,-18.815 3.599,-9.458 7.277,-17.17 18.904,-17.031 13.559,0.161 11.141,12.219 10.086,17.468 z M 115.993,56.49 c -1.164,-0.016 -2.18,0.212 -3.093,1.62 -2.051,2.657 -8.047,19.042 -7.941,22.31 0.038,1.174 0.687,2.201 2.133,2.201 1.659,0.002 2.581,-1.145 3.396,-2.529 1.887,-3.193 7.193,-17.676 7.339,-21.297 0.043,-1.055 -0.133,-2.284 -1.834,-2.305 z"
id="path18"
inkscape:connector-curvature="0" /></g></g></svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
docs/static/lego_education_logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

1
docs/static/loader_back.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g transform="translate(-41.005 -446.364)"><rect ry="30" rx="30" y="458.77" x="53.41" height="143.698" width="105.312" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect width="105.668" height="144.183" x="53.232" y="458.527" rx="30.101" ry="30.101" fill="#fff"/></g><g transform="translate(111.528 -446.364)"><rect width="105.312" height="143.698" x="53.41" y="458.77" rx="30" ry="30" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect ry="30.101" rx="30.101" y="458.527" x="53.232" height="144.183" width="105.668" fill="#fff"/></g></svg>

After

Width:  |  Height:  |  Size: 721 B

1
docs/static/loader_front.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g stroke="#000" stroke-linecap="round" stroke-linejoin="round"><g transform="translate(124.66 -243.829)"><circle r="25.968" cy="356.872" cx="-38.891" fill="none"/><circle cx="-38.891" cy="356.872" r="21.013" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g><g transform="translate(277.193 -243.829)"><circle cx="-38.891" cy="356.872" r="25.968" fill="none"/><circle r="21.013" cy="356.872" cx="-38.891" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g></g></svg>

After

Width:  |  Height:  |  Size: 728 B

1
docs/static/loader_full.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g transform="translate(-41.005 -446.364)"><rect ry="30" rx="30" y="458.77" x="53.41" height="143.698" width="105.312" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect width="105.668" height="144.183" x="53.232" y="458.527" rx="30.101" ry="30.101" fill="#fff"/></g><g transform="translate(124.66 -243.829)" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><circle r="25.968" cy="356.872" cx="-38.891" fill="none"/><circle cx="-38.891" cy="356.872" r="21.013" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g><g transform="translate(111.528 -446.364)"><rect width="105.312" height="143.698" x="53.41" y="458.77" rx="30" ry="30" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect ry="30.101" rx="30.101" y="458.527" x="53.232" height="144.183" width="105.668" fill="#fff"/></g><g transform="translate(277.193 -243.829)" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><circle cx="-38.891" cy="356.872" r="25.968" fill="none"/><circle r="21.013" cy="356.872" cx="-38.891" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
docs/static/maker/intruder-detector.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
docs/static/maker/puppet.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

BIN
docs/static/maker/security-gadget.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/static/maker/sound-machine.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
docs/static/maker/sound-of-color.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

134
editor/deploy.ts Normal file
View File

@ -0,0 +1,134 @@
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
import UF2 = pxtc.UF2;
export let ev3: pxt.editor.Ev3Wrapper
export function debug() {
return initAsync()
.then(w => w.downloadFileAsync("/tmp/dmesg.txt", v => console.log(pxt.Util.uint8ArrayToString(v))))
}
function hf2Async() {
return pxt.HF2.mkPacketIOAsync()
.then(h => {
let w = new pxt.editor.Ev3Wrapper(h)
ev3 = w
return w.reconnectAsync(true)
.then(() => w)
})
}
let noHID = false
let initPromise: Promise<pxt.editor.Ev3Wrapper>
export function initAsync() {
if (initPromise)
return initPromise
let canHID = false
if (pxt.U.isNodeJS) {
// doesn't seem to work ATM
canHID = false
} else {
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
if (pxt.Cloud.isLocalHost() && pxt.Cloud.localToken && !forceHexDownload)
canHID = true
}
if (noHID)
canHID = false
if (canHID) {
initPromise = hf2Async()
.catch(err => {
initPromise = null
noHID = true
return Promise.reject(err)
})
} else {
noHID = true
initPromise = Promise.reject(new Error("no HID"))
}
return initPromise
}
// this comes from aux/pxt.lms
const rbfTemplate = `
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
`
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let w: pxt.editor.Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
filename = filename.replace(/^lego-/, "")
let fspath = "../prjs/BrkProg_SAVE/"
let elfPath = fspath + filename + ".elf"
let rbfPath = fspath + filename + ".rbf"
let rbfHex = rbfTemplate
.replace(/\s+/g, "")
.replace("XX", pxt.U.toHex(pxt.U.stringToUint8Array(elfPath)))
let rbfBIN = pxt.U.fromHex(rbfHex)
pxt.HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()
f.filename = "Projects/" + filename + ext
if (data)
UF2.writeBytes(f, 0, data)
return f
}
let elfUF2 = mkFile(".elf")
for (let b of origElfUF2) {
UF2.writeBytes(elfUF2, b.targetAddr, b.data)
}
let r = UF2.concatFiles([elfUF2, mkFile(".rbf", rbfBIN)])
let data = UF2.serializeFile(r)
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
let saveUF2Async = () => {
if (isCli || !pxt.commands.saveOnlyAsync) {
return Promise.resolve()
} else {
return pxt.commands.saveOnlyAsync(resp)
}
}
if (noHID) return saveUF2Async()
return initAsync()
.then(w_ => {
w = w_
if (w.isStreaming)
pxt.U.userError("please stop the program first")
return w.stopAsync()
})
.then(() => w.rmAsync(elfPath))
.then(() => w.flashAsync(elfPath, UF2.readBytes(origElfUF2, 0, origElfUF2.length * 256)))
.then(() => w.flashAsync(rbfPath, rbfBIN))
.then(() => w.runAsync(rbfPath))
.then(() => {
if (isCli)
return w.disconnectAsync()
else
return Promise.resolve()
//return Promise.delay(1000).then(() => w.dmesgAsync())
}).catch(e => {
// if we failed to initalize, retry
if (noHID)
return saveUF2Async()
else
return Promise.reject(e)
})
}

View File

@ -1,144 +1,146 @@
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts" />
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
import { deployCoreAsync, initAsync } from "./deploy";
import { FieldPorts } from "./field_ports";
import { FieldImages } from "./field_images";
import { FieldSpeed } from "./field_speed";
import { FieldBrickButtons } from "./field_brickbuttons";
import { FieldTurnRatio } from "./field_turnratio";
pxt.editor.initExtensionsAsync = function(opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
pxt.debug('loading pxt-ev3 target extensions...')
updateBlocklyShape();
const res: pxt.editor.ExtensionResult = {
fieldEditors: [{
selector: "ports",
editor: FieldPorts
}, {
selector: "images",
editor: FieldImages
}, {
selector: "speed",
editor: FieldSpeed
}, {
selector: "brickbuttons",
editor: FieldBrickButtons
}, {
selector: "turnratio",
editor: FieldTurnRatio
}],
deployCoreAsync
};
initAsync().catch(e => {
// probably no HID - we'll try this again upon deployment
})
return Promise.resolve<pxt.editor.ExtensionResult>(res);
}
/**
* Update the shape of Blockly blocks with square corners
*/
function updateBlocklyShape() {
/**
* Rounded corner radius.
* @const
*/
(Blockly.BlockSvg as any).CORNER_RADIUS = 0 * (Blockly.BlockSvg as any).GRID_UNIT;
/**
* Inner space between edge of statement input and notch.
* @const
*/
(Blockly.BlockSvg as any).STATEMENT_INPUT_INNER_SPACE = 3 * (Blockly.BlockSvg as any).GRID_UNIT;
/**
* SVG path for drawing next/previous notch from left to right.
* @const
*/
(Blockly.BlockSvg as any).NOTCH_PATH_LEFT = (
'l 8,8 ' +
'h 16 ' +
'l 8,-8 '
);
/**
* SVG path for drawing next/previous notch from right to left.
* @const
*/
(Blockly.BlockSvg as any).NOTCH_PATH_RIGHT = (
'l -8,8 ' +
'h -16 ' +
'l -8,-8 '
);
/**
* SVG start point for drawing the top-left corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_LEFT_CORNER_START =
'm 0,' + 0;
/**
* SVG path for drawing the rounded top-left corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_LEFT_CORNER =
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0 ';
/**
* SVG path for drawing the rounded top-right corner.
* @const
*/
(Blockly.BlockSvg as any).TOP_RIGHT_CORNER =
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS;
/**
* SVG path for drawing the rounded bottom-right corner.
* @const
*/
(Blockly.BlockSvg as any).BOTTOM_RIGHT_CORNER =
'l 0,' + (Blockly.BlockSvg as any).CORNER_RADIUS;
/**
* SVG path for drawing the rounded bottom-left corner.
* @const
*/
(Blockly.BlockSvg as any).BOTTOM_LEFT_CORNER =
'l -' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0';
/**
* SVG path for drawing the top-left corner of a statement input.
* @const
*/
(Blockly.BlockSvg as any).INNER_TOP_LEFT_CORNER =
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',-' + 0;
/**
* SVG path for drawing the bottom-left corner of a statement input.
* Includes the rounded inside corner.
* @const
*/
(Blockly.BlockSvg as any).INNER_BOTTOM_LEFT_CORNER =
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS * 2 +
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',' + 0;
/**
* Corner radius of the flyout background.
* @type {number}
* @const
*/
(Blockly as any).Flyout.prototype.CORNER_RADIUS = 0;
/**
* Margin around the edges of the blocks in the flyout.
* @type {number}
* @const
*/
(Blockly as any).Flyout.prototype.MARGIN = 8;
}
// When require()d from node, bind the global pxt namespace
namespace pxt {
export const dummyExport = 1;
}
eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")
namespace pxt.editor {
import UF2 = pxtc.UF2;
// this comes from aux/pxt.lms
const rbfTemplate = `
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
74617274696e672e2e2e0084006080XX00448581644886488405018130813e80427965210084000a
`
function hf2Async() {
return pxt.HF2.mkPacketIOAsync()
.then(h => {
let w = new Ev3Wrapper(h)
return w.reconnectAsync(true)
.then(() => w)
})
}
let noHID = false
let initPromise: Promise<Ev3Wrapper>
function initAsync() {
if (initPromise)
return initPromise
let canHID = false
if (U.isNodeJS) {
canHID = true
} else {
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload)
canHID = true
}
if (noHID)
canHID = false
if (canHID) {
initPromise = hf2Async()
.catch(err => {
initPromise = null
noHID = true
return Promise.reject(err)
})
} else {
noHID = true
initPromise = Promise.reject(new Error("no HID"))
}
return initPromise
}
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let w: Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
filename = filename.replace(/^lego-/, "")
let fspath = "../prjs/BrkProg_SAVE/"
let elfPath = fspath + filename + ".elf"
let rbfPath = fspath + filename + ".rbf"
let rbfHex = rbfTemplate
.replace(/\s+/g, "")
.replace("XX", U.toHex(U.stringToUint8Array(elfPath)))
let rbfBIN = U.fromHex(rbfHex)
HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()
f.filename = "Projects/" + filename + ext
if (data)
UF2.writeBytes(f, 0, data)
return f
}
let elfUF2 = mkFile(".elf")
for (let b of origElfUF2) {
UF2.writeBytes(elfUF2, b.targetAddr, b.data)
}
let r = UF2.concatFiles([elfUF2, mkFile(".rbf", rbfBIN)])
let data = UF2.serializeFile(r)
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
let saveUF2Async = () => {
if (isCli || !pxt.commands.saveOnlyAsync) {
return Promise.resolve()
} else {
return pxt.commands.saveOnlyAsync(resp)
}
}
if (noHID) return saveUF2Async()
return initAsync()
.then(w_ => {
w = w_
if (w.isStreaming)
U.userError("please stop the program first")
return w.stopAsync()
})
.then(() => w.rmAsync(elfPath))
.then(() => w.flashAsync(elfPath, UF2.readBytes(origElfUF2, 0, origElfUF2.length * 256)))
.then(() => w.flashAsync(rbfPath, rbfBIN))
.then(() => w.runAsync(rbfPath))
.then(() => {
if (isCli)
return w.disconnectAsync()
else
return Promise.resolve()
//return Promise.delay(1000).then(() => w.dmesgAsync())
}).catch(e => {
// if we failed to initalize, retry
if (noHID)
return saveUF2Async()
else
return Promise.reject(e)
})
}
initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
pxt.debug('loading pxt-ev3 target extensions...')
const res: pxt.editor.ExtensionResult = {
deployCoreAsync,
};
initAsync().catch(e => {
// probably no HID - we'll try this again upon deployment
})
return Promise.resolve<pxt.editor.ExtensionResult>(res);
}
}
// namespace pxt {
// export const dummyExport = 1;
// }
// eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")

View File

@ -0,0 +1,159 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldPortsOptions extends Blockly.FieldCustomDropdownOptions {
columns?: string;
width?: string;
}
export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.FieldCustom {
public isFieldCustom_ = true;
// Width in pixels
private width_: number;
// Columns in grid
private columns_: number;
private savedPrimary_: string;
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
super(options.data);
this.columns_ = parseInt(options.columns) || 4;
this.width_ = parseInt(options.width) || 150;
}
/**
* Create a dropdown menu under the text.
* @private
*/
public showEditor_() {
// If there is an existing drop-down we own, this is a request to hide the drop-down.
if (Blockly.DropDownDiv.hideIfOwner(this)) {
return;
}
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
Blockly.DropDownDiv.hideWithoutAnimation();
Blockly.DropDownDiv.clearContent();
// Populate the drop-down with the icons for this field.
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
let contentDiv = document.createElement('div');
// Accessibility properties
contentDiv.setAttribute('role', 'menu');
contentDiv.setAttribute('aria-haspopup', 'true');
const buttonsSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg") as SVGGElement;
pxsim.svg.hydrate(buttonsSVG, {
viewBox: "0 0 256.68237 256.68237",
width: this.width_,
height: this.width_
});
contentDiv.appendChild(buttonsSVG);
const gWrapper = pxsim.svg.child(buttonsSVG, 'g', { 'transform': 'translate(-4.695057,58.29823)' });
const gInnerWrapper = pxsim.svg.child(gWrapper, 'g', { 'transform': 'translate(3.9780427e-6,-32.677281)' });
const back = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#6a6a6a;stroke-width:3.91719985',
d: 'M 106.30882,198.38022 C 84.431262,177.26258 50.453467,142.52878 50.453467,142.52878 v -7.12931 H 37.087971 a 32.381533,32.381533 0 1 1 0,-64.763062 H 50.457376 V 63.503186 L 105.71731,7.0563355 h 55.25604 c 25.02699,25.5048885 55.25994,55.2599395 55.25994,55.2599395 v 8.320133 h 12.77398 a 32.381533,32.381533 0 0 1 0,64.763062 h -12.77398 v 7.13323 c -29.43384,30.27603 -54.66454,55.85144 -54.66454,55.85144 z'
})
const buttonLeft = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#a8a9a8;stroke-width:3.91719985',
d: 'm 36.492567,78.357208 h 40.69971 V 126.48393 H 36.492567 A 24.063359,24.063359 0 0 1 12.429199,102.42057 v 0 A 24.063359,24.063359 0 0 1 36.492567,78.357208 Z'
})
const buttonRight = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#a8a9a8;stroke-width:3.91719985',
d: 'M 229.00727,126.48784 H 188.30756 V 78.361126 h 40.69971 a 24.063359,24.063359 0 0 1 24.06335,24.063354 v 0 a 24.063359,24.063359 0 0 1 -24.06335,24.06336 z'
})
const buttonEnter = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#3c3c3c;stroke-width:3.91719985',
d: 'm 109.27806,78.357208 h 46.9398 a 1.782326,1.782326 0 0 1 1.78233,1.782326 V 124.7016 a 1.782326,1.782326 0 0 1 -1.78233,1.78233 h -46.9398 a 1.782326,1.782326 0 0 1 -1.78233,-1.78233 V 80.139534 a 1.782326,1.782326 0 0 1 1.78233,-1.782326 z'
})
const buttonTop = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#a8a9a8;stroke-width:3.91719985',
d: 'm 108.09114,15.967966 49.90905,-0.59542 37.43276,38.619675 -15.44943,15.449437 V 97.367379 H 165.7249 V 81.306861 A 11.978797,11.978797 0 0 0 153.84012,69.422075 c -11.59883,-0.184102 -43.37516,0 -43.37516,0 A 9.6676495,9.6676495 0 0 0 100.36251,79.520618 V 97.347793 H 86.103905 V 69.422075 L 70.654464,53.97264 Z'
})
const buttonBottom = pxsim.svg.child(gInnerWrapper, 'path', {
style: 'fill:#a8a9a8;stroke-width:3.91719985',
d: 'M 157.78865,189.01028 108.18908,189.38233 70.654464,150.794 86.323259,135.4895 v -28.08625 h 14.101921 v 16.11144 a 12.006218,12.006218 0 0 0 11.85346,11.9788 c 11.59882,0.1841 43.13227,0 43.13227,0 a 10.18472,10.18472 0 0 0 10.38059,-10.38058 v -17.70966 h 14.39179 v 28.08632 l 15.3045,15.3045 z'
})
const buttons = [buttonEnter, buttonLeft, buttonRight, buttonTop, buttonBottom];
const options = this.getOptions();
for (let i = 0, option: any; option = options[i]; i++) {
let content = (options[i] as any)[0]; // Human-readable text or image.
const value = (options[i] as any)[1]; // Language-neutral value.
const button = buttons[i];
button.setAttribute('id', ':' + i); // For aria-activedescendant
button.setAttribute('role', 'menuitem');
button.setAttribute('cursor', 'pointer');
const title = pxsim.svg.child(button, 'title');
title.textContent = content;
Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_);
// These are applied manually instead of using the :hover pseudoclass
// because Android has a bad long press "helper" menu and green highlight
// that we must prevent with ontouchstart preventDefault
Blockly.bindEvent_(button, 'mousedown', button, function (e) {
this.setAttribute('stroke', '#ffffff');
e.preventDefault();
});
Blockly.bindEvent_(button, 'mouseover', button, function () {
this.setAttribute('stroke', '#ffffff');
});
Blockly.bindEvent_(button, 'mouseout', button, function () {
this.setAttribute('stroke', 'transparent');
});
button.setAttribute('data-value', value);
}
contentDiv.style.width = this.width_ + 'px';
dropdownDiv.appendChild(contentDiv);
Blockly.DropDownDiv.setColour('#ffffff', '#dddddd');
// Calculate positioning based on the field position.
var scale = this.sourceBlock_.workspace.scale;
var bBox = { width: this.size_.width, height: this.size_.height };
bBox.width *= scale;
bBox.height *= scale;
var position = this.fieldGroup_.getBoundingClientRect();
var primaryX = position.left + bBox.width / 2;
var primaryY = position.top + bBox.height;
var secondaryX = primaryX;
var secondaryY = position.top;
// Set bounds to workspace; show the drop-down.
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
this.onHide_.bind(this));
}
/**
* Callback for when a button is clicked inside the drop-down.
* Should be bound to the FieldIconMenu.
* @param {Event} e DOM event for the click/touch
* @private
*/
private buttonClick_ = function (e: any) {
let value = e.target.getAttribute('data-value');
this.setValue(value);
Blockly.DropDownDiv.hide();
};
/**
* Callback for when the drop-down is hidden.
*/
private onHide_ = function () {
Blockly.DropDownDiv.content_.removeAttribute('role');
Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
};
}

114
editor/field_images.ts Normal file
View File

@ -0,0 +1,114 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtblocks.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldImagesOptions extends pxtblockly.FieldImageDropdownOptions {
}
export class FieldImages extends pxtblockly.FieldImageDropdown implements Blockly.FieldCustom {
public isFieldCustom_ = true;
constructor(text: string, options: FieldImagesOptions, validator?: Function) {
super(text, options, validator);
}
/**
* Create a dropdown menu under the text.
* @private
*/
public showEditor_() {
// If there is an existing drop-down we own, this is a request to hide the drop-down.
if (Blockly.DropDownDiv.hideIfOwner(this)) {
return;
}
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
Blockly.DropDownDiv.hideWithoutAnimation();
Blockly.DropDownDiv.clearContent();
// Populate the drop-down with the icons for this field.
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
let contentDiv = document.createElement('div');
// Accessibility properties
contentDiv.setAttribute('role', 'menu');
contentDiv.setAttribute('aria-haspopup', 'true');
const options = this.getOptions();
for (let i = 0, option: any; option = options[i]; i++) {
let content = (options[i] as any)[0]; // Human-readable text or image.
const value = (options[i] as any)[1]; // Language-neutral value.
// Icons with the type property placeholder take up space but don't have any functionality
// Use for special-case layouts
if (content.type == 'placeholder') {
let placeholder = document.createElement('span');
placeholder.setAttribute('class', 'blocklyDropDownPlaceholder');
placeholder.style.width = content.width + 'px';
placeholder.style.height = content.height + 'px';
contentDiv.appendChild(placeholder);
continue;
}
let button = document.createElement('button');
button.setAttribute('id', ':' + i); // For aria-activedescendant
button.setAttribute('role', 'menuitem');
button.setAttribute('class', 'blocklyDropDownButton');
button.title = content.alt;
if ((this as any).columns_) {
button.style.width = (((this as any).width_ / (this as any).columns_) - 8) + 'px';
//button.style.height = ((this.width_ / this.columns_) - 8) + 'px';
} else {
button.style.width = content.width + 'px';
button.style.height = content.height + 'px';
}
let backgroundColor = this.sourceBlock_.getColour();
if (value == this.getValue()) {
// This icon is selected, show it in a different colour
backgroundColor = this.sourceBlock_.getColourTertiary();
button.setAttribute('aria-selected', 'true');
}
button.style.backgroundColor = backgroundColor;
button.style.borderColor = this.sourceBlock_.getColourTertiary();
Blockly.bindEvent_(button, 'click', this, (this as any).buttonClick_);
Blockly.bindEvent_(button, 'mouseup', this, (this as any).buttonClick_);
// These are applied manually instead of using the :hover pseudoclass
// because Android has a bad long press "helper" menu and green highlight
// that we must prevent with ontouchstart preventDefault
Blockly.bindEvent_(button, 'mousedown', button, function (e) {
this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
e.preventDefault();
});
Blockly.bindEvent_(button, 'mouseover', button, function () {
this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
contentDiv.setAttribute('aria-activedescendant', this.id);
});
Blockly.bindEvent_(button, 'mouseout', button, function () {
this.setAttribute('class', 'blocklyDropDownButton');
contentDiv.removeAttribute('aria-activedescendant');
});
let buttonImg = document.createElement('img');
buttonImg.src = content.src;
//buttonImg.alt = icon.alt;
// Upon click/touch, we will be able to get the clicked element as e.target
// Store a data attribute on all possible click targets so we can match it to the icon.
button.setAttribute('data-value', value);
buttonImg.setAttribute('data-value', value);
button.appendChild(buttonImg);
contentDiv.appendChild(button);
}
contentDiv.style.width = (this as any).width_ + 'px';
dropdownDiv.appendChild(contentDiv);
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary());
// Calculate positioning based on the field position.
var scale = this.sourceBlock_.workspace.scale;
var bBox = { width: this.size_.width, height: this.size_.height };
bBox.width *= scale;
bBox.height *= scale;
var position = this.fieldGroup_.getBoundingClientRect();
var primaryX = position.left + bBox.width / 2;
var primaryY = position.top + bBox.height;
var secondaryX = primaryX;
var secondaryY = position.top;
// Set bounds to workspace; show the drop-down.
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
(this as any).onHide_.bind(this));
}
}

151
editor/field_ports.ts Normal file
View File

@ -0,0 +1,151 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldPortsOptions extends Blockly.FieldCustomDropdownOptions {
columns?: string;
width?: string;
}
export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCustom {
public isFieldCustom_ = true;
// Width in pixels
private width_: number;
// Columns in grid
private columns_: number;
private savedPrimary_: string;
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
super(options.data);
this.columns_ = parseInt(options.columns) || 4;
this.width_ = parseInt(options.width) || 300;
}
trimOptions_() {
}
/**
* Create a dropdown menu under the text.
* @private
*/
public showEditor_() {
// If there is an existing drop-down we own, this is a request to hide the drop-down.
if (Blockly.DropDownDiv.hideIfOwner(this)) {
return;
}
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
Blockly.DropDownDiv.hideWithoutAnimation();
Blockly.DropDownDiv.clearContent();
// Populate the drop-down with the icons for this field.
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
let contentDiv = document.createElement('div');
// Accessibility properties
contentDiv.setAttribute('role', 'menu');
contentDiv.setAttribute('aria-haspopup', 'true');
let options = this.getOptions();
options = options.sort();
for (let i = 0, option: any; option = options[i]; i++) {
let content = (options[i] as any)[0]; // Human-readable text or image.
const value = (options[i] as any)[1]; // Language-neutral value.
// Icons with the type property placeholder take up space but don't have any functionality
// Use for special-case layouts
if (content.type == 'placeholder') {
let placeholder = document.createElement('span');
placeholder.setAttribute('class', 'blocklyDropDownPlaceholder');
placeholder.style.width = content.width + 'px';
placeholder.style.height = content.height + 'px';
contentDiv.appendChild(placeholder);
continue;
}
let button = document.createElement('button');
button.setAttribute('id', ':' + i); // For aria-activedescendant
button.setAttribute('role', 'menuitem');
button.setAttribute('class', 'blocklyDropDownButton');
button.title = content.alt;
if (this.columns_) {
button.style.width = ((this.width_ / this.columns_) - 8) + 'px';
button.style.height = ((this.width_ / this.columns_) - 8) + 'px';
} else {
button.style.width = content.width + 'px';
button.style.height = content.height + 'px';
}
let backgroundColor = this.sourceBlock_.getColour();
if (value == this.getValue()) {
// This icon is selected, show it in a different colour
backgroundColor = this.sourceBlock_.getColourTertiary();
button.setAttribute('aria-selected', 'true');
}
button.style.backgroundColor = backgroundColor;
button.style.borderColor = this.sourceBlock_.getColourTertiary();
Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_);
// These are applied manually instead of using the :hover pseudoclass
// because Android has a bad long press "helper" menu and green highlight
// that we must prevent with ontouchstart preventDefault
Blockly.bindEvent_(button, 'mousedown', button, function (e) {
this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
e.preventDefault();
});
Blockly.bindEvent_(button, 'mouseover', button, function () {
this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
contentDiv.setAttribute('aria-activedescendant', this.id);
});
Blockly.bindEvent_(button, 'mouseout', button, function () {
this.setAttribute('class', 'blocklyDropDownButton');
contentDiv.removeAttribute('aria-activedescendant');
});
let buttonImg = document.createElement('img');
buttonImg.src = content.src;
//buttonImg.alt = icon.alt;
// Upon click/touch, we will be able to get the clicked element as e.target
// Store a data attribute on all possible click targets so we can match it to the icon.
button.setAttribute('data-value', value);
buttonImg.setAttribute('data-value', value);
button.appendChild(buttonImg);
contentDiv.appendChild(button);
}
contentDiv.style.width = this.width_ + 'px';
dropdownDiv.appendChild(contentDiv);
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary());
// Calculate positioning based on the field position.
var scale = this.sourceBlock_.workspace.scale;
var bBox = { width: this.size_.width, height: this.size_.height };
bBox.width *= scale;
bBox.height *= scale;
var position = this.fieldGroup_.getBoundingClientRect();
var primaryX = position.left + bBox.width / 2;
var primaryY = position.top + bBox.height;
var secondaryX = primaryX;
var secondaryY = position.top;
// Set bounds to workspace; show the drop-down.
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
this.onHide_.bind(this));
}
/**
* Callback for when a button is clicked inside the drop-down.
* Should be bound to the FieldIconMenu.
* @param {Event} e DOM event for the click/touch
* @private
*/
private buttonClick_ = function (e: any) {
let value = e.target.getAttribute('data-value');
this.setValue(value);
Blockly.DropDownDiv.hide();
};
/**
* Callback for when the drop-down is hidden.
*/
private onHide_ = function () {
Blockly.DropDownDiv.content_.removeAttribute('role');
Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
};
}

96
editor/field_speed.ts Normal file
View File

@ -0,0 +1,96 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldSpeedOptions extends Blockly.FieldCustomOptions {
min?: string;
max?: string;
label?: string;
}
export class FieldSpeed extends Blockly.FieldSlider implements Blockly.FieldCustom {
public isFieldCustom_ = true;
private params: any;
private speedSVG: SVGElement;
private circleBar: SVGCircleElement;
private reporter: SVGTextElement;
/**
* Class for a color wheel field.
* @param {number|string} value The initial content of the field.
* @param {Function=} opt_validator An optional function that is called
* to validate any constraints on what the user entered. Takes the new
* text as an argument and returns either the accepted text, a replacement
* text, or null to abort the change.
* @extends {Blockly.FieldNumber}
* @constructor
*/
constructor(value_: any, params: FieldSpeedOptions, opt_validator?: Function) {
super(String(value_), '-100', '100', null, '10', 'Speed', opt_validator);
this.params = params;
if (this.params['min']) this.min_ = parseFloat(this.params.min);
if (this.params['max']) this.max_ = parseFloat(this.params.max);
if (this.params['label']) this.labelText_ = this.params.label;
(this as any).sliderColor_ = '#a8aaa8';
}
createLabelDom_(labelText: string) {
var labelContainer = document.createElement('div');
this.speedSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg") as SVGGElement;
pxsim.svg.hydrate(this.speedSVG, {
viewBox: "0 0 200 100"
});
labelContainer.appendChild(this.speedSVG);
const outerCircle = pxsim.svg.child(this.speedSVG, "circle", {
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 0.1s linear;`,
'stroke': '#a8aaa8', 'stroke-width': '1rem'
}) as SVGCircleElement;
this.circleBar = pxsim.svg.child(this.speedSVG, "circle", {
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 0.1s linear;`,
'stroke': '#f12a21', 'stroke-width': '1rem'
}) as SVGCircleElement;
this.reporter = pxsim.svg.child(this.speedSVG, "text", {
'x': 100, 'y': 80,
'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px',
'class': 'sim-text inverted number'
}) as SVGTextElement;
// labelContainer.setAttribute('class', 'blocklyFieldSliderLabel');
var readout = document.createElement('span');
readout.setAttribute('class', 'blocklyFieldSliderReadout');
// var label = document.createElement('span');
// label.setAttribute('class', 'blocklyFieldSliderLabelText');
// label.innerHTML = labelText;
// labelContainer.appendChild(label);
// labelContainer.appendChild(readout);
return [labelContainer, readout];
};
setReadout_(readout: Element, value: string) {
this.updateSpeed(parseFloat(value));
// Update reporter
this.reporter.textContent = `${value}%`;
}
private updateSpeed(speed: number) {
let sign = this.sign(speed);
speed = (Math.abs(speed) / 100 * 50) + 50;
if (sign == -1) speed = 50 - speed;
let c = Math.PI * (90 * 2);
let pct = ((100 - speed) / 100) * c;
this.circleBar.setAttribute('stroke-dashoffset', `${pct}`);
}
// A re-implementation of Math.sign (since IE11 doesn't support it)
private sign(num: number) {
return num ? num < 0 ? -1 : 1 : 0;
}
}

108
editor/field_turnratio.ts Normal file
View File

@ -0,0 +1,108 @@
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
export interface FieldTurnRatioOptions extends Blockly.FieldCustomOptions {
}
export class FieldTurnRatio extends Blockly.FieldSlider implements Blockly.FieldCustom {
public isFieldCustom_ = true;
private params: any;
private path_: SVGPathElement;
private reporter_: SVGTextElement;
/**
* Class for a color wheel field.
* @param {number|string} value The initial content of the field.
* @param {Function=} opt_validator An optional function that is called
* to validate any constraints on what the user entered. Takes the new
* text as an argument and returns either the accepted text, a replacement
* text, or null to abort the change.
* @extends {Blockly.FieldNumber}
* @constructor
*/
constructor(value_: any, params: FieldTurnRatioOptions, opt_validator?: Function) {
super(String(value_), '-100', '100', null, '10', 'TurnRatio', opt_validator);
this.params = params;
(this as any).sliderColor_ = '#a8aaa8';
}
static HALF = 80;
static HANDLE_RADIUS = 30;
static RADIUS = FieldTurnRatio.HALF - FieldTurnRatio.HANDLE_RADIUS - 1;
createLabelDom_(labelText: string) {
let labelContainer = document.createElement('div');
let svg = Blockly.utils.createSvgElement('svg', {
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:html': 'http://www.w3.org/1999/xhtml',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'version': '1.1',
'height': (FieldTurnRatio.HALF + FieldTurnRatio.HANDLE_RADIUS + 10) + 'px',
'width': (FieldTurnRatio.HALF * 2) + 'px'
}, labelContainer);
let defs = Blockly.utils.createSvgElement('defs', {}, svg);
let marker = Blockly.utils.createSvgElement('marker', {
'id': 'head',
'orient': "auto",
'markerWidth': '2',
'markerHeight': '4',
'refX': '0.1', 'refY': '1.5'
}, defs);
let markerPath = Blockly.utils.createSvgElement('path', {
'd': 'M0,0 V3 L1.5,1.5 Z',
'fill': '#f12a21'
}, marker);
this.reporter_ = pxsim.svg.child(svg, "text", {
'x': FieldTurnRatio.HALF, 'y': 96,
'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px',
'class': 'sim-text inverted number'
}) as SVGTextElement;
this.path_ = Blockly.utils.createSvgElement('path', {
'x1': FieldTurnRatio.HALF,
'y1': FieldTurnRatio.HALF,
'marker-end': 'url(#head)',
'style': 'fill: none; stroke: #f12a21; stroke-width: 10'
}, svg);
this.updateGraph_();
let readout = document.createElement('span');
readout.setAttribute('class', 'blocklyFieldSliderReadout');
return [labelContainer, readout];
};
updateGraph_() {
if (!this.path_) {
return;
}
let v = goog.math.clamp(parseFloat(this.getText()), -100, 100);
if (isNaN(v)) {
v = 0;
}
const x = goog.math.clamp(parseFloat(this.getText()), -100, 100) / 100;
const theta = x * Math.PI / 2;
const cx = FieldTurnRatio.HALF;
const cy = FieldTurnRatio.HALF - 14;
const gamma = Math.PI - 2 * theta;
const r = FieldTurnRatio.RADIUS;
const alpha = 0.2 + Math.abs(x) * 0.5;
const x1 = 0;
const y1 = r * alpha;
const y2 = r * Math.sin(Math.PI / 2 - theta);
const x2 = r * Math.cos(Math.PI / 2 - theta);
const y3 = y2 - r * alpha * Math.cos(2 * theta);
const x3 = x2 - r * alpha * Math.sin(2 * theta);
const d = `M ${cx} ${cy} C ${cx} ${cy - y1} ${cx + x3} ${cy - y3} ${cx + x2} ${cy - y2}`;
this.path_.setAttribute('d', d);
this.reporter_.textContent = `${v}`;
}
setReadout_(readout: Element, value: string) {
this.updateGraph_();
}
}

View File

@ -1,12 +1,14 @@
{
"compilerOptions": {
"target": "es5",
"noImplicitAny": true,
"noImplicitAny": false,
"noImplicitReturns": true,
"declaration": true,
"out": "../built/editor.js",
"module": "commonjs",
"outDir": "../built/editor",
"rootDir": ".",
"newLine": "LF",
"sourceMap": false
"sourceMap": false,
"allowSyntheticDefaultImports": true,
"declaration": true
}
}

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