Compare commits
428 Commits
Author | SHA1 | Date | |
---|---|---|---|
51a14596cd | |||
8518c446cd | |||
2f69df0d9d | |||
1789d0ce21 | |||
d0809510c4 | |||
6b9c0eaf65 | |||
52bdf94233 | |||
fd50ed8f7c | |||
ba0eb93b0f | |||
9a4ed45797 | |||
820fdf3a3c | |||
348d5ffc26 | |||
95e47a0b25 | |||
c3312ed5d1 | |||
b7cdc7d0fe | |||
dde5a35cd9 | |||
be398d84ee | |||
4445acce7a | |||
d6d8b0655b | |||
216aa1ddaf | |||
783a561941 | |||
c916664ae7 | |||
4b836ede1b | |||
52fdaeec99 | |||
2aaa45e10d | |||
7993363e89 | |||
4d671f6cb0 | |||
cc020d5a81 | |||
5c39862a44 | |||
e0e5c95989 | |||
800b4ad224 | |||
40c3b4b0cf | |||
64bdc35e6f | |||
2b5f702bb6 | |||
1c81ecd23f | |||
4d223374b5 | |||
dd9cf9014f | |||
eb11d7926c | |||
609740dc48 | |||
955a2c9757 | |||
02838e6c30 | |||
b0c54e84e6 | |||
b6644b7a23 | |||
3c4c38eb59 | |||
29aba7b10b | |||
7427142243 | |||
436500babb | |||
82be4e344b | |||
81bfca4ed6 | |||
c35dbdd38f | |||
1bc93013e6 | |||
58148eb1c3 | |||
a7c62b45b2 | |||
bd765d49ee | |||
383ca5467d | |||
e240e3b394 | |||
7affbf8cb6 | |||
4dff282633 | |||
5d470fdcef | |||
f30eac41e9 | |||
d7f46c0fb5 | |||
58384017f2 | |||
01f7fe633c | |||
a9a9a89811 | |||
7e2251d8ac | |||
1903a6e347 | |||
2fb75a2d83 | |||
0da175a8cd | |||
f01370e4fd | |||
751df2fe8c | |||
8be4bb11d8 | |||
342e714ae2 | |||
fb31b81f7e | |||
8204995749 | |||
85c14bb05a | |||
c398a5a133 | |||
a1b059171b | |||
afaedaa0b2 | |||
0aa41e9a64 | |||
88df2e14cb | |||
180f32f25c | |||
995527675a | |||
84eb849bc7 | |||
5e0e35b4bd | |||
300a2c1476 | |||
703bd01931 | |||
75a65eeab2 | |||
38a9f153f7 | |||
3c5dae8c7b | |||
85345969d3 | |||
ac1e5d2846 | |||
11b4bbc07e | |||
7f5b8aed99 | |||
c989e2fdab | |||
d3dcb5de85 | |||
9cca35d49f | |||
7123bfecd3 | |||
c8ac770983 | |||
aa031036ee | |||
a7d002d949 | |||
93fd8c8c78 | |||
1765ca2d35 | |||
1ab7ae6cfa | |||
3acf4e9ac5 | |||
ef5fa9ae82 | |||
e1f7a5b8cf | |||
2c73bfc813 | |||
d78d9c8686 | |||
2157af3e63 | |||
eac3e183c3 | |||
785ddff706 | |||
e07d6e3a31 | |||
763ad3f763 | |||
919a03951c | |||
9e427898ae | |||
60bf3a17d3 | |||
0529759a80 | |||
b07f157181 | |||
2f5f7d4133 | |||
e6e1dce59f | |||
43a9d03231 | |||
c0f6cd3651 | |||
f1445c6e89 | |||
04275ee35c | |||
f8d0594eca | |||
5be3b31e00 | |||
84c1079e50 | |||
6320379d02 | |||
b166f6034e | |||
d07f672b28 | |||
363e076f36 | |||
8bf6f265f7 | |||
217958aec3 | |||
367b1b0d1a | |||
6836852122 | |||
944098b9f9 | |||
539cf3d73e | |||
4b3e7cfb7d | |||
b144744509 | |||
e591bed6ad | |||
6a4e64eac0 | |||
f7dd14ff7b | |||
bfd34cedd6 | |||
8e1c075911 | |||
a02f364a4c | |||
48fee2c215 | |||
5780d1982c | |||
6fb08f0f7b | |||
13f8659b98 | |||
edc9d17a8c | |||
c7a3f5bbd0 | |||
41d5052583 | |||
07ddec343a | |||
5a9a5e997a | |||
55b6549999 | |||
fcdc350e40 | |||
9dedbeae1b | |||
124d8a0fd8 | |||
81fcbb6916 | |||
d436bd1227 | |||
cb648019bb | |||
11a88a9d94 | |||
92178f3371 | |||
3c86ae286f | |||
1b6d84a9b8 | |||
2d81be3b24 | |||
14f57f54bf | |||
e7c697c24d | |||
7ac63f038c | |||
557926d631 | |||
da62d51615 | |||
3918857fcc | |||
f1dcebdd88 | |||
1d35c78737 | |||
d17326ad7a | |||
4948a88833 | |||
b73b924ec4 | |||
641d292c33 | |||
223275fd65 | |||
6e42e816d3 | |||
5678cf5df9 | |||
67ec4accb9 | |||
fa867c3a34 | |||
7865876e64 | |||
113b42656c | |||
7557380722 | |||
3e2a1ec9e1 | |||
09db613620 | |||
bacb4673c9 | |||
e649a167cd | |||
997e8efb20 | |||
1f380ce959 | |||
8cbf601131 | |||
bdbb2a8c2f | |||
5e90cb4434 | |||
1bf1eb16f0 | |||
fbc6fc30a7 | |||
fee2329ca7 | |||
5656031e2d | |||
e87e1767b5 | |||
2d7a108e79 | |||
193f66fd2d | |||
5768fcaf35 | |||
2c22ea925f | |||
4e4aa266d5 | |||
05bdbd7b40 | |||
085ab0844b | |||
4ad229cb37 | |||
170ee33848 | |||
162e437527 | |||
ab13cb9047 | |||
80454f55c7 | |||
30e576345b | |||
dfc4c83718 | |||
e25d273765 | |||
903e98ca22 | |||
8a64085288 | |||
22ab1cba8d | |||
064d6f9411 | |||
330aff8082 | |||
0886a5d4e1 | |||
aa636aef96 | |||
1865ced312 | |||
b940befe85 | |||
c6bae5e17b | |||
83e4898eab | |||
7bdb9683c9 | |||
3c675892aa | |||
3d29c5e323 | |||
15d59269d4 | |||
73b5e7dc3f | |||
a92edcffee | |||
305a650125 | |||
34a5aeb7d2 | |||
32f524ddd8 | |||
b690c1634b | |||
8089841892 | |||
3d8c697586 | |||
e365e3d1be | |||
4ed41adb6a | |||
39b7f99741 | |||
ad17191ae2 | |||
4a8633f506 | |||
3690f409b0 | |||
97663d2b83 | |||
4d2b7ced71 | |||
5676103052 | |||
cb8c14fbb1 | |||
815d438d86 | |||
da8de1e31e | |||
b028916025 | |||
b9be74bad8 | |||
7e502b1749 | |||
f22edac84d | |||
ef2807a84e | |||
580b40876c | |||
b57ae5d588 | |||
71479d0caa | |||
7e39cdde9d | |||
85ca6b3698 | |||
2c89848fda | |||
ed1c187514 | |||
52816e6de7 | |||
60ac3a9d00 | |||
d2c7a5ace0 | |||
79fcd1c01e | |||
2d48725c63 | |||
802c3db0ba | |||
4a7e8c5fa8 | |||
0ebffd8549 | |||
988a2b638b | |||
fb743dea74 | |||
e400637ba1 | |||
b2768b1099 | |||
3a5885b28e | |||
b602b52f7d | |||
90afb60cc4 | |||
c936c16c33 | |||
ead69e3c6e | |||
d100026d5c | |||
41c2899feb | |||
9437873427 | |||
dab281a9cb | |||
f27fb4d93c | |||
11fb82eba9 | |||
170e6b700b | |||
387ad763f8 | |||
0e61f162bb | |||
400f01a6be | |||
afcbe69c44 | |||
9165fe09fc | |||
08f36fbb94 | |||
afca2aa4d1 | |||
3c6c766412 | |||
329a1e15ea | |||
16a025f3a0 | |||
26b975b5f2 | |||
79b9bce904 | |||
d3d9fa6ca0 | |||
8f5c930f76 | |||
a082807455 | |||
3469f51b7b | |||
e8e31e6aa7 | |||
2df90152fe | |||
e25590539e | |||
a7795302fc | |||
480d89ba8e | |||
9487d324fd | |||
bfc95e075e | |||
7d4ba9b2b2 | |||
71b83040e6 | |||
1976534da0 | |||
ebbbe6e86c | |||
c4a9b4a381 | |||
c7d36a5e82 | |||
c8c45be057 | |||
a8a7267851 | |||
9cdb4081fd | |||
dcb398d3d5 | |||
f6e350cf9f | |||
c085094394 | |||
7c2ea7c406 | |||
84b98a2788 | |||
4e99cd3ef1 | |||
57647318c4 | |||
2720698864 | |||
dfe2fe3cff | |||
18fefa2a44 | |||
c0bab4877a | |||
d2a1d10ada | |||
bcb68d937d | |||
05a8395028 | |||
3a1601a419 | |||
712c2178d2 | |||
12cdad72c8 | |||
95076f8f24 | |||
6391620373 | |||
86212e2153 | |||
98e430f3c1 | |||
5c7e856e7b | |||
a47988913e | |||
ea72dba6c7 | |||
215e846a54 | |||
21b34cb459 | |||
282134f5dc | |||
6b44352839 | |||
9a883d5672 | |||
59ce4338d3 | |||
90560050b8 | |||
2c72173bfe | |||
1a5992408b | |||
0e1a3b7e6b | |||
ea6bfa03bd | |||
20d584db2b | |||
0e4e0d8899 | |||
a18a690417 | |||
c9d57c5e8d | |||
7e9d42a571 | |||
1b51320edb | |||
4f44238237 | |||
c8ffa0ded7 | |||
6b07d5f716 | |||
8784e23b60 | |||
4b8409fbc0 | |||
3237978cba | |||
33c8902050 | |||
fa6c81cf80 | |||
46175fc7db | |||
e6ef86101f | |||
c4d3d7634e | |||
b0380fbef8 | |||
c85c68ab68 | |||
334d5aca9a | |||
1330a0fb82 | |||
005447ce44 | |||
60d5271de2 | |||
e3ab6ace55 | |||
5f4488dea7 | |||
07dc3bdae1 | |||
5d5d78ced0 | |||
fe46461c4c | |||
ccda971fd1 | |||
8fa6cf41ca | |||
aa3c6d5fc0 | |||
6a719e7718 | |||
b18b8333d0 | |||
84d80131d4 | |||
4977358718 | |||
15b2ef6c92 | |||
e0288ed741 | |||
df1caf9741 | |||
a755420d06 | |||
a139727fea | |||
48e081e584 | |||
124ad5c915 | |||
75a571fda7 | |||
bb842056d4 | |||
41b023f83f | |||
1ff058460f | |||
cb0895f166 | |||
1340fd0162 | |||
a3f56f4c9a | |||
c0e2252157 | |||
92ad67315b | |||
8b3064f4e0 | |||
138709285a | |||
65dd4617f1 | |||
bdc8c1c62c | |||
ebcde71950 | |||
d42117a2a5 | |||
b0145cf378 | |||
868ee826ab | |||
ce489bba56 | |||
b0944ba431 | |||
8736d32f09 | |||
f8c481555c | |||
15f50966aa | |||
88e21db35e | |||
4e9d3aa413 | |||
1efad776e6 | |||
5e7af872b5 | |||
17683033b1 | |||
31f3d108c5 | |||
b45bf7512c | |||
2dec405a9b | |||
29009aa5e5 | |||
86011827dc | |||
c20cfab069 |
1
.gitignore
vendored
@ -31,3 +31,4 @@ videos/**
|
||||
lib/
|
||||
.vscode/
|
||||
bin
|
||||
scripts/out.*
|
||||
|
@ -1,15 +1,17 @@
|
||||
# LEGO Mindstorms EV3 target for PXT
|
||||
|
||||
[](https://ci2.dot.net/job/Private/job/pxt_project_pink/job/master/job/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/
|
||||
|
||||
Issue tracker: https://src.education.lego.com/groups/ev3-makecode
|
||||
|
||||
## Local Dev setup
|
||||
|
||||
These instructions assume familiarity with dev tools and languages.
|
||||
|
||||
* install Node.js 6+
|
||||
* install [yotta](http://docs.yottabuild.org/#installing)
|
||||
* install Docker; make sure `docker` command is in your `PATH`
|
||||
* (optional) install [Visual Studio Code](https://code.visualstudio.com/)
|
||||
|
||||
In a common folder,
|
||||
|
@ -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
|
||||
|
@ -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.
|
10
brick/ins
@ -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
|
@ -1,2 +0,0 @@
|
||||
obj-m += $(MOD).o
|
||||
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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_ */
|
||||
|
||||
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
7
brick/mk
@ -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/
|
||||
|
@ -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
|
@ -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()
|
@ -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
|
@ -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()
|
@ -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
|
@ -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)
|
10
brick/send
@ -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'
|
||||
|
@ -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
|
@ -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?
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -1,9 +1,8 @@
|
||||
/// <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")
|
||||
require("./editor/deploy")
|
||||
|
||||
declare namespace pxt.editor {
|
||||
function deployCoreAsync(resp: pxtc.CompileResult, disconnect?: boolean): Promise<void>;
|
||||
|
@ -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";
|
||||
|
@ -8,6 +8,7 @@
|
||||
"module": "commonjs",
|
||||
"rootDir": ".",
|
||||
"newLine": "LF",
|
||||
"sourceMap": false
|
||||
"sourceMap": false,
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
}]
|
||||
```
|
12
docs/examples/happy-unhappy.md
Normal 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)
|
||||
})
|
||||
```
|
47
docs/maker.md
Normal 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"
|
||||
}
|
||||
]
|
||||
```
|
11
docs/maker/intruder-detector.md
Normal 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
@ -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)
|
||||
})
|
||||
```
|
9
docs/maker/security-gadget.md
Normal 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))
|
||||
})
|
||||
```
|
12
docs/maker/sound-machine.md
Normal 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)
|
||||
})
|
||||
```
|
15
docs/maker/sound-of-color.md
Normal 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))
|
||||
})
|
||||
```
|
@ -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
After Width: | Height: | Size: 69 KiB |
90
docs/static/fonts/icons/iconfont.css
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@font-face {
|
||||
font-family: "iconfont";
|
||||
src: url("iconfont.eot?73552ec404b3a3d3769a3f04fa58c2c4?#iefix") format("embedded-opentype"),
|
||||
url("iconfont.woff2?73552ec404b3a3d3769a3f04fa58c2c4") format("woff2"),
|
||||
url("iconfont.woff?73552ec404b3a3d3769a3f04fa58c2c4") 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-advancedcollapsed:before {
|
||||
content: "\f112";
|
||||
}
|
||||
.icon-advancedexpanded:before {
|
||||
content: "\f113";
|
||||
}
|
||||
.icon-cancel:before {
|
||||
content: "\f114";
|
||||
}
|
||||
.icon-check:before {
|
||||
content: "\f115";
|
||||
}
|
||||
.icon-download:before {
|
||||
content: "\f116";
|
||||
}
|
||||
.icon-save:before {
|
||||
content: "\f117";
|
||||
}
|
||||
.icon-blocks:before {
|
||||
content: "\f118";
|
||||
}
|
BIN
docs/static/fonts/icons/iconfont.eot
vendored
Normal file
84
docs/static/fonts/icons/iconfont.svg
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
horiz-adv-x="40" d=" M23.1 30.6V2.8H16.5V30.6H7.7V36.7H32.3V30.6H23.1z" />
|
||||
<glyph glyph-name="variables"
|
||||
unicode=""
|
||||
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="advancedcollapsed"
|
||||
unicode=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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=""
|
||||
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
BIN
docs/static/fonts/icons/iconfont.woff
vendored
Normal file
BIN
docs/static/fonts/icons/iconfont.woff2
vendored
Normal file
BIN
docs/static/hero.png
vendored
Normal file
After Width: | Height: | Size: 40 KiB |
74
docs/static/lego-logo.svg
vendored
Normal 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
After Width: | Height: | Size: 8.1 KiB |
BIN
docs/static/maker/intruder-detector.png
vendored
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
docs/static/maker/puppet.png
vendored
Normal file
After Width: | Height: | Size: 377 KiB |
BIN
docs/static/maker/security-gadget.png
vendored
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
docs/static/maker/sound-machine.png
vendored
Normal file
After Width: | Height: | Size: 141 KiB |
BIN
docs/static/maker/sound-of-color.png
vendored
Normal file
After Width: | Height: | Size: 159 KiB |
133
editor/deploy.ts
Normal file
@ -0,0 +1,133 @@
|
||||
/// <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) {
|
||||
canHID = true
|
||||
} 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)
|
||||
})
|
||||
}
|
@ -1,128 +1,120 @@
|
||||
/// <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";
|
||||
|
||||
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
|
||||
}],
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
// 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)
|
||||
initPromise = hf2Async()
|
||||
.catch(err => {
|
||||
initPromise = null
|
||||
noHID = true
|
||||
return Promise.reject(err)
|
||||
})
|
||||
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()
|
||||
/*
|
||||
.then(w => w.streamFileAsync("/tmp/serial.txt", buf => {
|
||||
let str = Util.fromUTF8(Util.uint8ArrayToString(buf))
|
||||
|
||||
}))
|
||||
*/
|
||||
return Promise.resolve<pxt.editor.ExtensionResult>(res);
|
||||
}
|
||||
}
|
||||
// namespace pxt {
|
||||
// export const dummyExport = 1;
|
||||
// }
|
||||
// eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")
|
||||
|
114
editor/field_images.ts
Normal 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));
|
||||
}
|
||||
}
|
147
editor/field_ports.ts
Normal file
@ -0,0 +1,147 @@
|
||||
/// <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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.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');
|
||||
};
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -252,6 +252,13 @@ namespace pxt.editor {
|
||||
return loop()
|
||||
}
|
||||
|
||||
|
||||
downloadFileAsync(path: string, cb: (d: Uint8Array) => void) {
|
||||
return this.lock.enqueue("file", () =>
|
||||
this.streamFileOnceAsync(path, cb))
|
||||
}
|
||||
|
||||
|
||||
private initAsync() {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
BIN
legoresources/Block icns/Blockcolor-icns.pdf
Normal file
193
legoresources/Block icns/icn_block_Large_motor.svg
Normal file
@ -0,0 +1,193 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1344 8191 55 41">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
clip-path: url(#clip-path);
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
clip-path: url(#clip-path-2);
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #919191;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
clip-path: url(#clip-path-3);
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
fill: #f2f2f2;
|
||||
}
|
||||
|
||||
.cls-8 {
|
||||
clip-path: url(#clip-path-4);
|
||||
}
|
||||
|
||||
.cls-9 {
|
||||
fill: #6a6a6a;
|
||||
}
|
||||
|
||||
.cls-10 {
|
||||
fill: #9a9a9a;
|
||||
}
|
||||
|
||||
.cls-11 {
|
||||
fill: #d02e26;
|
||||
}
|
||||
|
||||
.cls-12 {
|
||||
fill: #242424;
|
||||
}
|
||||
|
||||
.cls-13 {
|
||||
filter: url(#rød);
|
||||
}
|
||||
|
||||
.cls-14 {
|
||||
filter: url(#Path_4);
|
||||
}
|
||||
|
||||
.cls-15 {
|
||||
filter: url(#Path_1-2);
|
||||
}
|
||||
|
||||
.cls-16 {
|
||||
filter: url(#Path_2);
|
||||
}
|
||||
|
||||
.cls-17 {
|
||||
filter: url(#Path_1);
|
||||
}
|
||||
|
||||
.cls-18 {
|
||||
filter: url(#Path_34);
|
||||
}
|
||||
</style>
|
||||
<clipPath id="clip-path">
|
||||
<rect id="Rectangle_119" data-name="Rectangle 119" class="cls-1" width="55" height="41" transform="translate(-10.923 65.26)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip-path-2">
|
||||
<path id="Union_6" data-name="Union 6" class="cls-2" d="M0,88.889A11.109,11.109,0,0,1,9.191,77.947L8.954,77.7,8.947,54.41c0-.273.093-.261.255-.438l7.1-6.846V40.6l-.488-.5v-.516H11.39a2.6,2.6,0,0,1-2.6-2.6V20.163a2.6,2.6,0,0,1,2.6-2.6h4.421V12.236a3.765,3.765,0,0,1,3.766-3.765h4.241c0-.059-.005-.117-.005-.176V3.941a3,3,0,0,1,1.882-2.785V.4a.4.4,0,0,1,.4-.4H43.183a.394.394,0,0,1,.394.4v1a3,3,0,0,1,1.412,2.546V8.294c0,.059,0,.118-.005.176h2.359a3.765,3.765,0,0,1,3.765,3.765V31.528c-6.749,9.152-11.8,15.533-11.8,15.533h-.387s-4.616-.035-8.906-.062l.022,7.681h4.479a2.6,2.6,0,0,1,2.6,2.6V74.093a2.6,2.6,0,0,1-2.6,2.6H30.1l.022,7.664c0,.545-.1.545-.3.74l-6.78,6.569-.139.124a.989.989,0,0,1-1.036-.154A11.108,11.108,0,0,1,0,88.889Z"/>
|
||||
</clipPath>
|
||||
<filter id="Path_34" x="1375.234" y="8125.181" width="24.177" height="13.354" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<filter id="Path_1" x="1360.37" y="8169.796" width="24.177" height="49.327" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur-2"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur-2"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<filter id="Path_2" x="1367.722" y="8164.375" width="16.687" height="17.582" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur-3"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur-3"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<filter id="Path_1-2" x="1367.234" y="8132.71" width="38.296" height="41.59" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur-4"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur-4"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<clipPath id="clip-path-3">
|
||||
<path id="Path_9" data-name="Path 9" class="cls-2" d="M3.765,0H31.531A3.765,3.765,0,0,1,35.3,3.765V23.057C28.547,32.209,23.5,38.59,23.5,38.59h-.387s-12.667-.1-15.533-.1a1.484,1.484,0,0,1-1.548-.641L0,31.62V3.765A3.765,3.765,0,0,1,3.765,0Z"/>
|
||||
</clipPath>
|
||||
<filter id="Path_4" x="1370.999" y="8136.004" width="30.766" height="34.531" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur-5"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur-5"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<clipPath id="clip-path-4">
|
||||
<path id="Path_10" data-name="Path 10" class="cls-2" d="M3.765,0H24a3.765,3.765,0,0,1,3.765,3.765v14.48c-5.628,7.331-10.127,13.286-10.127,13.286H3.765A3.765,3.765,0,0,1,0,27.766v-24A3.765,3.765,0,0,1,3.765,0Z"/>
|
||||
</clipPath>
|
||||
<filter id="rød" x="1351.423" y="8202.021" width="25.213" height="25.214" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur-6"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur-6"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="icn_block_Large_motor" transform="translate(666.315 8209.204)">
|
||||
<g id="Symbol_13_1" data-name="Symbol 13 – 1" transform="translate(688.608 -83.464)">
|
||||
<g id="Mask_Group_12" data-name="Mask Group 12" class="cls-3">
|
||||
<g id="Mask_Group_6" data-name="Mask Group 6" class="cls-4" transform="translate(-2)">
|
||||
<g id="Large_motor" data-name="Large motor" transform="translate(-1.056 0)">
|
||||
<g id="Group_23" data-name="Group 23">
|
||||
<path id="Subtraction_1" data-name="Subtraction 1" class="cls-5" d="M-2806.659-5548.724h-3.653a3.558,3.558,0,0,1-3.554-3.554v-14.908a3.558,3.558,0,0,1,3.554-3.555h3.653a3.558,3.558,0,0,1,3.554,3.555v14.908A3.558,3.558,0,0,1-2806.659-5548.724Zm.1-5.923a2.47,2.47,0,0,0-2.468,2.467,2.471,2.471,0,0,0,2.468,2.469,2.471,2.471,0,0,0,2.468-2.469A2.47,2.47,0,0,0-2806.56-5554.647Zm.062-.99h.01a2.859,2.859,0,0,1,1.425.37c.112.054.238.116.378.176a.67.67,0,0,0,.267.063c.364,0,.427-.425.428-.429v-1.145s-.111-.449-.454-.449a.556.556,0,0,0-.241.063l-.211.1a2.988,2.988,0,0,1-1.591.4h-.023a4.281,4.281,0,0,1-1.831-.5.642.642,0,0,0-.262-.059c-.167,0-.392.077-.517.444,0,0-.011.628,0,1.145.007.32.3.388.537.388a1.414,1.414,0,0,0,.239-.021A4.678,4.678,0,0,1-2806.5-5555.637Zm-1.218-3.3h.006c.048,0,.469.012.469.422v.844s.136.2.639.2c.039,0,.079,0,.123,0a2.375,2.375,0,0,0,.914-.2v-.844a.437.437,0,0,1,.429-.422c.145,0,.287,0,.394,0,.22,0,.391,0,.42,0,.005,0,.168-.134.19-.861.021-.7-.165-.883-.186-.9h-.818c-.022,0-.524-.049-.532-.5-.006-.386,0-1.306,0-1.684v-.022a.326.326,0,0,1,.048-.21.1.1,0,0,1,.076-.033.219.219,0,0,1,.093.025l.79.379a.668.668,0,0,0,.256.062.255.255,0,0,0,.189-.07.4.4,0,0,0,.084-.292c-.008-.485,0-1.013,0-1.163v-.008a.214.214,0,0,0-.215-.179.654.654,0,0,0-.315.111,2.7,2.7,0,0,1-1.524.458c-.075.006-.151.009-.224.009a3.3,3.3,0,0,1-1.72-.468,1.044,1.044,0,0,0-.545-.253.225.225,0,0,0-.167.065.4.4,0,0,0-.087.255v1.171a.423.423,0,0,0,.451.4.709.709,0,0,0,.349-.1c.357-.2.564-.326.633-.366l.022-.013a.216.216,0,0,1,.088-.021c.067,0,.147.042.147.238v1.706a.578.578,0,0,1-.138.378.427.427,0,0,1-.319.121h-.018c-.136,0-.288,0-.449,0-.219,0-.384,0-.445,0,0,0-.2.165-.2.9,0,.717.184.855.192.861Zm1.156-10.815a2.471,2.471,0,0,0-2.468,2.469,2.47,2.47,0,0,0,2.468,2.467,2.47,2.47,0,0,0,2.468-2.467A2.471,2.471,0,0,0-2806.56-5569.753Z" transform="translate(2841.282 5625.42)"/>
|
||||
</g>
|
||||
<path id="Path_36" data-name="Path 36" class="cls-2" d="M.395,0H17.488a.4.4,0,0,1,.395.395V3.841a.4.4,0,0,1-.395.395H.395A.4.4,0,0,1,0,3.841V.395A.4.4,0,0,1,.395,0Z" transform="translate(26.751 0)"/>
|
||||
<g class="cls-18" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<path id="Path_34-2" data-name="Path 34" class="cls-2" d="M.395,0H20.782a.4.4,0,0,1,.395.395V9.958a.4.4,0,0,1-.395.395H.395A.4.4,0,0,1,0,9.958V.395A.4.4,0,0,1,.395,0Z" transform="translate(1376.73 8126.68)"/>
|
||||
</g>
|
||||
<g class="cls-17" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<path id="Path_1-3" data-name="Path 1" class="cls-5" d="M-.121,4,8.6-4.416,20.69-3.98,20.8,34.388c0,.545-.1.545-.3.74l-6.78,6.57-.138.124c-.38.26-1.293-.075-1.293-.62L-.368,27.722-.375,4.438C-.375,4.165-.283,4.176-.121,4Z" transform="translate(1362.25 8175.71)"/>
|
||||
</g>
|
||||
<g class="cls-16" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<path id="Path_2-2" data-name="Path 2" class="cls-2" d="M1484.037,521.285v11.229s.012.55.2.729,2.289,2.36,2.289,2.36a1.019,1.019,0,0,0,.753.262c.493-.016,7.567,0,7.567,0l2.883-3.057v-5.183l-6.94-.369Z" transform="translate(-114.81 7644.59)"/>
|
||||
</g>
|
||||
<g id="Group_4" data-name="Group 4" transform="translate(9.843 17.559)">
|
||||
<path id="Path_44" data-name="Path 44" class="cls-2" d="M3.554,0H7.207a3.554,3.554,0,0,1,3.554,3.554V18.462a3.554,3.554,0,0,1-3.554,3.554H3.554A3.554,3.554,0,0,1,0,18.462V3.554A3.554,3.554,0,0,1,3.554,0Z" transform="translate(0 0)"/>
|
||||
<ellipse id="Ellipse_3" data-name="Ellipse 3" class="cls-1" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(0.691 0.987)"/>
|
||||
<ellipse id="Ellipse_4" data-name="Ellipse 4" class="cls-1" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(0.691 16.092)"/>
|
||||
<path id="Path_5" data-name="Path 5" class="cls-1" d="M5607.868,939.1a2.7,2.7,0,0,1-1.524.459,3.338,3.338,0,0,1-1.945-.459c-.818-.606-.8.067-.8.067v1.172c0,.293.36.55.8.3s.654-.378.654-.378.235-.12.235.218v1.705s.013.512-.475.5-.9,0-.9,0-.191.161-.191.9.191.86.191.86h.9s.475-.016.475.422v.844s.147.234.761.2a2.341,2.341,0,0,0,.914-.2v-.844a.436.436,0,0,1,.43-.422c.41-.006.818,0,.818,0s.164-.124.187-.86-.187-.9-.187-.9h-.818s-.524-.034-.533-.5,0-1.705,0-1.705-.03-.335.216-.218l.791.378s.541.265.53-.3,0-1.172,0-1.172S5608.345,938.813,5607.868,939.1Z" transform="translate(-5602.81 -932.641)"/>
|
||||
<path id="Path_6" data-name="Path 6" class="cls-1" d="M5601.894,1015.1a.54.54,0,0,1,.778-.386,4.241,4.241,0,0,0,1.854.5,3.287,3.287,0,0,0,1.8-.5c.54-.263.695.386.695.386v1.145a.462.462,0,0,1-.695.365,3.768,3.768,0,0,0-1.8-.545,4.6,4.6,0,0,0-1.854.545s-.767.155-.778-.365S5601.894,1015.1,5601.894,1015.1Z" transform="translate(-5601.296 -1000.958)"/>
|
||||
</g>
|
||||
<g class="cls-15" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<path id="Path_1-4" data-name="Path 1" class="cls-2" d="M3.765,0H31.531A3.765,3.765,0,0,1,35.3,3.765V23.057C28.547,32.209,23.5,38.59,23.5,38.59h-.387s-12.667-.1-15.533-.1a1.484,1.484,0,0,1-1.548-.641L0,31.62V3.765A3.765,3.765,0,0,1,3.765,0Z" transform="translate(1368.73 8134.21)"/>
|
||||
</g>
|
||||
<g id="hvid" transform="translate(16.868 8.471)">
|
||||
<g id="Mask_Group_1" data-name="Mask Group 1" class="cls-6">
|
||||
<path id="hvid-2" data-name="hvid" class="cls-7" d="M1498.578,448.445l4.657,4.8,15.484,20.229v9.67l8.5-10.5V452.321l-.646-5.006Z" transform="translate(-1491.247 -448.708)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g class="cls-14" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<path id="Path_4-2" data-name="Path 4" class="cls-2" d="M3.765,0H24a3.765,3.765,0,0,1,3.765,3.765v14.48c-5.628,7.331-10.127,13.286-10.127,13.286H3.765A3.765,3.765,0,0,1,0,27.766v-24A3.765,3.765,0,0,1,3.765,0Z" transform="translate(1372.5 8137.51)"/>
|
||||
</g>
|
||||
<g id="Group_3" data-name="Group 3" transform="translate(20.633 11.963)">
|
||||
<g id="Mask_Group_2" data-name="Mask Group 2" class="cls-8" transform="translate(0 0)">
|
||||
<path id="Union_1" data-name="Union 1" class="cls-9" d="M9.412,18.589V.706a.706.706,0,1,1,1.412,0V18.589a.706.706,0,1,1-1.412,0Zm-2.353,0V.706a.706.706,0,1,1,1.412,0V18.589a.706.706,0,1,1-1.412,0Zm-2.353,0V.706a.706.706,0,1,1,1.412,0V18.589a.706.706,0,1,1-1.412,0Zm-2.353,0V.706a.706.706,0,1,1,1.412,0V18.589a.706.706,0,1,1-1.412,0ZM0,18.589V.706a.706.706,0,1,1,1.412,0V18.589a.706.706,0,1,1-1.412,0Z" transform="translate(10.353 -3.492)"/>
|
||||
</g>
|
||||
</g>
|
||||
<ellipse id="Ellipse_1" data-name="Ellipse 1" class="cls-10" cx="1.461" cy="1.461" rx="1.461" ry="1.461" transform="translate(18.925 10.528)"/>
|
||||
<ellipse id="Ellipse_2" data-name="Ellipse 2" class="cls-10" cx="1.461" cy="1.461" rx="1.461" ry="1.461" transform="translate(37.584 43.404)"/>
|
||||
<g class="cls-13" transform="matrix(1, 0, 0, 1, -1351.87, -8125.74)">
|
||||
<ellipse id="rød-2" data-name="rød" class="cls-11" cx="11.107" cy="11.107" rx="11.107" ry="11.107" transform="translate(1352.92 8203.52)"/>
|
||||
</g>
|
||||
<g id="Group_2" data-name="Group 2" transform="matrix(0.966, 0.259, -0.259, 0.966, 5.162, 76.726)">
|
||||
<ellipse id="Ellipse_4-2" data-name="Ellipse 4" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(7.503 0)"/>
|
||||
<ellipse id="Ellipse_7" data-name="Ellipse 7" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(15.006 7.503)"/>
|
||||
<ellipse id="Ellipse_5" data-name="Ellipse 5" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(7.503 15.006)"/>
|
||||
<ellipse id="Ellipse_6" data-name="Ellipse 6" cx="2.468" cy="2.468" rx="2.468" ry="2.468" transform="translate(0 7.503)"/>
|
||||
<path id="Path_4-3" data-name="Path 4" class="cls-12" d="M1.564,1.019s.014.512-.475.5-.9,0-.9,0S0,1.68,0,2.421s.191.86.191.86h.9s.475-.016.475.422,0,.844,0,.844.147.234.761.2a2.339,2.339,0,0,0,.914-.2V3.7a.436.436,0,0,1,.43-.422c.41-.006.818,0,.818,0s.164-.124.187-.86-.187-.9-.187-.9H3.669s-.524-.034-.532-.5A8.122,8.122,0,0,1,3.179.2,1.884,1.884,0,0,0,1.646.138C1.595.533,1.564,1.019,1.564,1.019Z" transform="translate(7.602 12.277) rotate(-90)"/>
|
||||
<path id="Path_5-2" data-name="Path 5" d="M.3.1,1.312,0,2.369.1a.3.3,0,0,1,.3.3V1.779a.3.3,0,0,1-.3.3L1.36,1.939.3,2.075a.3.3,0,0,1-.3-.3V.4A.3.3,0,0,1,.3.1Z" transform="translate(8.618 5.261)"/>
|
||||
<path id="Path_7" data-name="Path 7" d="M.3.1,1.312,0,2.369.1a.3.3,0,0,1,.3.3V1.779a.3.3,0,0,1-.3.3L1.36,1.939.3,2.075a.3.3,0,0,1-.3-.3V.4A.3.3,0,0,1,.3.1Z" transform="translate(5.26 11.285) rotate(-90)"/>
|
||||
<path id="Path_6-2" data-name="Path 6" d="M.3.1,1.312,0,2.369.1a.3.3,0,0,1,.3.3V1.779a.3.3,0,0,1-.3.3L1.36,1.939.3,2.075a.3.3,0,0,1-.3-.3V.4A.3.3,0,0,1,.3.1Z" transform="translate(11.284 14.642) rotate(180)"/>
|
||||
<path id="Path_8" data-name="Path 8" d="M.3.1,1.312,0,2.369.1a.3.3,0,0,1,.3.3V1.779a.3.3,0,0,1-.3.3L1.36,1.939.3,2.075a.3.3,0,0,1-.3-.3V.4A.3.3,0,0,1,.3.1Z" transform="translate(14.641 8.619) rotate(90)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
35
legoresources/Block icns/icn_block_buttons_green.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1321.124 9006.084 42.65 31.79">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #6a6a6a;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #3c3c3c;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.948" x2="0.5" y2="0.059" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#6a6a6a"/>
|
||||
<stop offset="0.522" stop-color="#8ce300"/>
|
||||
<stop offset="1" stop-color="#6a6a6a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_buttons_green" transform="translate(666.315 8209.204)">
|
||||
<path id="Union_4" data-name="Union 4" class="cls-1" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(654.809 796.881)"/>
|
||||
<path id="light" class="cls-2" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(654.809 796.881)"/>
|
||||
<path id="Rectangle_23" data-name="Rectangle 23" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(656.092 808.729)"/>
|
||||
<path id="Rectangle_24" data-name="Rectangle 24" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(696.077 816.725) rotate(180)"/>
|
||||
<path id="Path_42" data-name="Path 42" class="cls-4" d="M.3,0H8.1a.3.3,0,0,1,.3.3V7.7a.3.3,0,0,1-.3.3H.3A.3.3,0,0,1,0,7.7V.3A.3.3,0,0,1,.3,0Z" transform="translate(671.889 808.729)"/>
|
||||
<path id="Path_15" data-name="Path 15" class="cls-3" d="M-102.228-1598.9l8.293-.1,6.22,6.417-2.567,2.567v4.64h-2.369v-2.666a1.99,1.99,0,0,0-1.975-1.974c-1.927-.031-7.207,0-7.207,0a1.606,1.606,0,0,0-1.678,1.678v2.962h-2.369v-4.64l-2.567-2.567Z" transform="translate(774.216 2397.264)"/>
|
||||
<path id="Path_16" data-name="Path 16" class="cls-3" d="M6.264.062,14.505,0l6.236,6.412L18.135,8.954v4.667H15.79V10.945a2,2,0,0,0-1.969-1.99c-1.927-.031-7.166,0-7.166,0A1.689,1.689,0,0,0,4.93,10.679v2.942H2.543V8.954L0,6.412Z" transform="translate(686.509 827.175) rotate(180)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
35
legoresources/Block icns/icn_block_buttons_red.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1321.124 8957.084 42.65 31.79">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #6a6a6a;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #3c3c3c;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.948" x2="0.5" y2="0.059" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#6a6a6a"/>
|
||||
<stop offset="0.522" stop-color="#e5352c"/>
|
||||
<stop offset="1" stop-color="#6a6a6a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_buttons_red" transform="translate(666.315 8209.204)">
|
||||
<path id="Union_4" data-name="Union 4" class="cls-1" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(654.809 747.881)"/>
|
||||
<path id="light" class="cls-2" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(654.809 747.881)"/>
|
||||
<path id="Rectangle_23" data-name="Rectangle 23" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(656.092 759.729)"/>
|
||||
<path id="Rectangle_24" data-name="Rectangle 24" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(696.077 767.725) rotate(180)"/>
|
||||
<path id="Path_42" data-name="Path 42" class="cls-4" d="M.3,0H8.1a.3.3,0,0,1,.3.3V7.7a.3.3,0,0,1-.3.3H.3A.3.3,0,0,1,0,7.7V.3A.3.3,0,0,1,.3,0Z" transform="translate(671.889 759.729)"/>
|
||||
<path id="Path_15" data-name="Path 15" class="cls-3" d="M-102.228-1598.9l8.293-.1,6.22,6.417-2.567,2.567v4.64h-2.369v-2.666a1.99,1.99,0,0,0-1.975-1.974c-1.927-.031-7.207,0-7.207,0a1.606,1.606,0,0,0-1.678,1.678v2.962h-2.369v-4.64l-2.567-2.567Z" transform="translate(774.216 2348.264)"/>
|
||||
<path id="Path_16" data-name="Path 16" class="cls-3" d="M6.264.062,14.505,0l6.236,6.412L18.135,8.954v4.667H15.79V10.945a2,2,0,0,0-1.969-1.99c-1.927-.031-7.166,0-7.166,0A1.689,1.689,0,0,0,4.93,10.679v2.942H2.543V8.954L0,6.412Z" transform="translate(686.509 778.175) rotate(180)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
35
legoresources/Block icns/icn_block_buttons_yellow.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1393.124 8957.084 42.65 31.79">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #6a6a6a;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #3c3c3c;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.948" x2="0.5" y2="0.059" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#6a6a6a"/>
|
||||
<stop offset="0.522" stop-color="#ffeb00"/>
|
||||
<stop offset="1" stop-color="#838383"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_buttons_yellow" transform="translate(666.315 8209.204)">
|
||||
<path id="Union_4" data-name="Union 4" class="cls-1" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(726.809 747.881)"/>
|
||||
<path id="light" class="cls-2" d="M16.882,31.79c-3.635-3.509-9.28-9.28-9.28-9.28V21.325H5.38a5.381,5.381,0,0,1,0-10.761H7.6V9.379L16.783,0h9.182c4.158,4.237,9.182,9.182,9.182,9.182v1.382h2.122a5.381,5.381,0,1,1,0,10.761H35.147V22.51c-4.891,5.031-9.083,9.28-9.083,9.28Z" transform="translate(726.809 747.881)"/>
|
||||
<path id="Rectangle_23" data-name="Rectangle 23" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(728.092 759.729)"/>
|
||||
<path id="Rectangle_24" data-name="Rectangle 24" class="cls-3" d="M4,0h6.763a0,0,0,0,1,0,0V8a0,0,0,0,1,0,0H4A4,4,0,0,1,0,4V4A4,4,0,0,1,4,0Z" transform="translate(768.077 767.725) rotate(180)"/>
|
||||
<path id="Path_42" data-name="Path 42" class="cls-4" d="M.3,0H8.1a.3.3,0,0,1,.3.3V7.7a.3.3,0,0,1-.3.3H.3A.3.3,0,0,1,0,7.7V.3A.3.3,0,0,1,.3,0Z" transform="translate(743.889 759.729)"/>
|
||||
<path id="Path_15" data-name="Path 15" class="cls-3" d="M-102.228-1598.9l8.293-.1,6.22,6.417-2.567,2.567v4.64h-2.369v-2.666a1.99,1.99,0,0,0-1.975-1.974c-1.927-.031-7.207,0-7.207,0a1.606,1.606,0,0,0-1.678,1.678v2.962h-2.369v-4.64l-2.567-2.567Z" transform="translate(846.216 2348.264)"/>
|
||||
<path id="Path_16" data-name="Path 16" class="cls-3" d="M6.264.062,14.505,0l6.236,6.412L18.135,8.954v4.667H15.79V10.945a2,2,0,0,0-1.969-1.99c-1.927-.031-7.166,0-7.166,0A1.689,1.689,0,0,0,4.93,10.679v2.942H2.543V8.954L0,6.412Z" transform="translate(758.509 778.175) rotate(180)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
65
legoresources/Block icns/icn_block_color_sensor.svg
Normal file
@ -0,0 +1,65 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1327.274 8333.921 23.497 21.72">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
clip-path: url(#clip-path);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #b72b1c;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #f2f2f2;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
filter: url(#Path_1);
|
||||
}
|
||||
</style>
|
||||
<clipPath id="clip-path">
|
||||
<path id="Union_5" data-name="Union 5" class="cls-1" d="M2.543,21.72c-.7,0-1.26-.4-1.26-.9V17.968H.494A.494.494,0,0,1,0,17.475V4.64a.494.494,0,0,1,.494-.494h.79V.9c0-.5.564-.9,1.26-.9H20.954c.7,0,1.26.4,1.26.9v3.25H23a.494.494,0,0,1,.494.494V17.475a.494.494,0,0,1-.494.494h-.79v2.855c0,.5-.564.9-1.26.9Z"/>
|
||||
</clipPath>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.901" x2="0.5" y2="1.068" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#a8a9a8"/>
|
||||
<stop offset="1" stop-color="#545554"/>
|
||||
</linearGradient>
|
||||
<filter id="Path_1" x="1319.557" y="8327.921" width="38.93" height="39.72" filterUnits="userSpaceOnUse">
|
||||
<feOffset dy="3" input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="3" result="blur"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="icn_block_color_sensor" transform="translate(666.315 8209.204)">
|
||||
<g id="Mask_Group_5" data-name="Mask Group 5" class="cls-2" transform="translate(660.959 124.718)">
|
||||
<g id="Group_4" data-name="Group 4" transform="translate(0)">
|
||||
<g id="Group_2" data-name="Group 2">
|
||||
<path id="Path_28" data-name="Path 28" class="cls-1" d="M.494,0H23A.494.494,0,0,1,23.5.494V13.328a.494.494,0,0,1-.494.494H.494A.494.494,0,0,1,0,13.328V.494A.494.494,0,0,1,.494,0Z" transform="translate(0 4.147)"/>
|
||||
<g class="cls-6" transform="matrix(1, 0, 0, 1, -1327.27, -8333.92)">
|
||||
<path id="Path_1-2" data-name="Path 1" class="cls-3" d="M1.26,0H19.67c.7,0,1.26.4,1.26.9V20.823c0,.5-.564.9-1.26.9H1.26c-.7,0-1.26-.4-1.26-.9V.9C0,.4.564,0,1.26,0Z" transform="translate(1328.56 8333.92)"/>
|
||||
</g>
|
||||
<rect id="Rectangle_2" data-name="Rectangle 2" width="0.494" height="3.949" transform="translate(22.51 6.121)"/>
|
||||
<rect id="Rectangle_5" data-name="Rectangle 5" width="0.494" height="3.949" transform="translate(0.592 6.121)"/>
|
||||
<rect id="Rectangle_3" data-name="Rectangle 3" width="0.494" height="3.949" transform="translate(22.51 11.748)"/>
|
||||
<rect id="Rectangle_4" data-name="Rectangle 4" width="0.494" height="3.949" transform="translate(0.592 11.748)"/>
|
||||
</g>
|
||||
<path id="Union_1" data-name="Union 1" class="cls-4" d="M1.678,11.551a4.557,4.557,0,0,1,.1-.973,6.22,6.22,0,1,1,8.874,0,4.542,4.542,0,1,1-8.979.973Z" transform="translate(5.529 2.666)"/>
|
||||
<path id="Union_2" data-name="Union 2" d="M1.738,10.614A3.5,3.5,0,0,1,1.98,9.332,5.233,5.233,0,1,1,8.5,9.317a3.507,3.507,0,1,1-6.765,1.3Z" transform="translate(6.516 3.602)"/>
|
||||
<g id="Group_3" data-name="Group 3" transform="translate(9.379 6.615)">
|
||||
<ellipse id="Ellipse_5" data-name="Ellipse 5" class="cls-5" cx="2.369" cy="2.369" rx="2.369" ry="2.369"/>
|
||||
<ellipse id="Ellipse_6" data-name="Ellipse 6" class="cls-5" cx="1.283" cy="1.283" rx="1.283" ry="1.283" transform="translate(1.086 6.22)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
26
legoresources/Block icns/icn_block_display.svg
Normal file
@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1299.627 9145.076 41.445 32.779">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #3c3c3c;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #a0b5a6;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.924" x2="0.5" y2="0.948" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#a8a9a8"/>
|
||||
<stop offset="1" stop-color="gray"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_display" transform="translate(666.315 8209.204)">
|
||||
<path id="Path_91" data-name="Path 91" class="cls-1" d="M.816,0H40.629a.816.816,0,0,1,.816.816V31.963a.816.816,0,0,1-.816.816H.816A.816.816,0,0,1,0,31.963V.816A.816.816,0,0,1,.816,0Z" transform="translate(633.313 935.874)"/>
|
||||
<path id="Path_92" data-name="Path 92" class="cls-2" d="M1.57,0H32.4a1.57,1.57,0,0,1,1.57,1.57V18.9a1.57,1.57,0,0,1-1.57,1.57H1.57A1.57,1.57,0,0,1,0,18.9V1.57A1.57,1.57,0,0,1,1.57,0Z" transform="translate(637.08 940.207)"/>
|
||||
<path id="Path_93" data-name="Path 93" class="cls-3" d="M1.13,0H27.316a1.13,1.13,0,0,1,1.13,1.13v16.7a1.13,1.13,0,0,1-1.13,1.13H1.13A1.13,1.13,0,0,1,0,17.834V1.13A1.13,1.13,0,0,1,1.13,0Z" transform="translate(639.906 941.023)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
101
legoresources/Block icns/icn_block_gyro.svg
Normal file
@ -0,0 +1,101 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1306.936 8729.215 61.393 44.083">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #d5277e;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
clip-path: url(#clip-path);
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
clip-path: url(#clip-path-2);
|
||||
}
|
||||
|
||||
.cls-11, .cls-5 {
|
||||
fill: #9a9a9a;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
fill: #f2f2f2;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
opacity: 0.6;
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-8 {
|
||||
fill: url(#linear-gradient-2);
|
||||
}
|
||||
|
||||
.cls-9 {
|
||||
fill: #b72b1c;
|
||||
}
|
||||
|
||||
.cls-10, .cls-11 {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.cls-12 {
|
||||
filter: url(#Path_12);
|
||||
}
|
||||
</style>
|
||||
<clipPath id="clip-path">
|
||||
<path id="Path_88" data-name="Path 88" class="cls-1" d="M1162.538,3051.215l1.79,38.862h-31.593l-5.221,5.221h-11.692l-5.221-5.221h-7.666l1.729-38.862Z" transform="translate(-1124.637 -3056.569)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip-path-2">
|
||||
<path id="Union_7" data-name="Union 7" class="cls-2" d="M6.318,39.688a6.076,6.076,0,0,1-1.291-.3H2.271A1.283,1.283,0,0,1,.987,38.108V35.147H.494A.494.494,0,0,1,0,34.653V4.542a.494.494,0,0,1,.494-.494H.987V1.284A1.283,1.283,0,0,1,2.271,0h8.237V.395h2.226V0h8.3a1.284,1.284,0,0,1,1.284,1.284V4.048H22.9a.494.494,0,0,1,.494.494V34.653a.494.494,0,0,1-.494.493h-.592v2.962a1.284,1.284,0,0,1-1.284,1.283h-2.7c-.111.2-1.244.3-1.451.3Z"/>
|
||||
</clipPath>
|
||||
<filter id="Path_12" x="1328.499" y="8733.444" width="23.575" height="33.349" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.375" result="blur"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#fff" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#404040"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-2" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#fff"/>
|
||||
<stop offset="1" stop-color="gray"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_gyro" transform="translate(666.315 8209.204)">
|
||||
<g id="Mask_Group_11" data-name="Mask Group 11" class="cls-3" transform="translate(662.322 525.366)">
|
||||
<g id="Group_16" data-name="Group 16">
|
||||
<g id="Mask_Group_7" data-name="Mask Group 7" class="cls-4" transform="translate(0 0)">
|
||||
<g id="Group_9" data-name="Group 9" transform="translate(0 0)">
|
||||
<path id="Path_29" data-name="Path 29" class="cls-2" d="M.494,0H22.9A.494.494,0,0,1,23.4.494V30.605a.494.494,0,0,1-.494.494H.494A.494.494,0,0,1,0,30.605V.494A.494.494,0,0,1,.494,0Z" transform="translate(0 4.048)"/>
|
||||
<rect id="Rectangle_11" data-name="Rectangle 11" class="cls-5" width="3.752" height="10.268" transform="translate(9.774 0.395)"/>
|
||||
<g class="cls-12" transform="matrix(1, 0, 0, 1, -1328.64, -8734.57)">
|
||||
<path id="Path_12-2" data-name="Path 12" class="cls-2" d="M1.283,0H9.52V10.424l2.226-.163V0h8.3a1.283,1.283,0,0,1,1.283,1.283V29.815A1.283,1.283,0,0,1,20.041,31.1H1.283A1.283,1.283,0,0,1,0,29.815V1.283A1.283,1.283,0,0,1,1.283,0Z" transform="translate(1329.62 8734.57)"/>
|
||||
</g>
|
||||
<g id="hvid" transform="translate(0.987 19.252)">
|
||||
<g id="hvid-2" data-name="hvid" transform="translate(0)">
|
||||
<path id="Path_57" data-name="Path 57" class="cls-6" d="M.79,0H20.535a.79.79,0,0,1,.79.79V18.857a1.283,1.283,0,0,1-1.283,1.283H1.283A1.283,1.283,0,0,1,0,18.857V.79A.79.79,0,0,1,.79,0Z" transform="translate(0)"/>
|
||||
<path id="Path_59" data-name="Path 59" class="cls-7" d="M0,0H21.325V1.975a1.283,1.283,0,0,1-1.283,1.283H1.283A1.283,1.283,0,0,1,0,1.975Z" transform="translate(0 16.882)"/>
|
||||
</g>
|
||||
<g id="Path_1" data-name="Path 1" class="cls-8" transform="translate(15.935 18.955)">
|
||||
<path class="cls-10" d="M -0.03972615301609039 1.355897426605225 L -10.6034460067749 1.355897426605225 C -10.8238697052002 1.355897426605225 -11.76168155670166 1.143560767173767 -12.02564239501953 0.9932262897491455 L -11.25642585754395 0.3544974625110626 C -11.06739616394043 0.1967574656009674 -10.78548622131348 0.1249974593520164 -10.6034460067749 0.1249974593520164 L -0.03972615301609039 0.1249974593520164 C 0.08689384907484055 0.1249974593520164 0.1953838467597961 0.221777468919754 0.3209938406944275 0.3338374495506287 C 0.3559758961200714 0.3650458753108978 0.3912657201290131 0.3964739441871643 0.4275123476982117 0.4264010488986969 L 1.240363001823425 1.159494996070862 C 0.997438907623291 1.265054941177368 0.2347392439842224 1.355897426605225 -0.03972615301609039 1.355897426605225 Z"/>
|
||||
<path class="cls-11" d="M -0.03972615301609039 1.230897426605225 C 0.1518102586269379 1.230897426605225 0.6746260523796082 1.174463033676147 0.9910745024681091 1.102993011474609 L 0.3458296954631805 0.5210594534873962 C 0.3090922832489014 0.490643322467804 0.2732802927494049 0.4587787985801697 0.2377838492393494 0.4271174669265747 C 0.1312438398599625 0.3320774734020233 0.03924384713172913 0.249997466802597 -0.03972615301609039 0.249997466802597 L -10.6034460067749 0.249997466802597 C -10.76875591278076 0.249997466802597 -11.01853656768799 0.3187874555587769 -11.1765661239624 0.4506674706935883 L -11.78844928741455 0.9587525725364685 C -11.43126487731934 1.086030006408691 -10.7613353729248 1.230897426605225 -10.6034460067749 1.230897426605225 L -0.03972615301609039 1.230897426605225 M -0.03972615301609039 1.480897426605225 L -10.6034460067749 1.480897426605225 C -10.82154655456543 1.480897426605225 -12.20312595367432 1.196227431297302 -12.20312595367432 0.9781274795532227 L -11.33627605438232 0.258327454328537 C -11.12889575958252 0.08526746183633804 -10.82154655456543 -2.538394937801058e-06 -10.6034460067749 -2.538394937801058e-06 L -0.03972615301609039 -2.538394937801058e-06 C 0.1783738434314728 -2.538394937801058e-06 0.3312638401985168 0.1853174567222595 0.5091438293457031 0.3316974639892578 L 1.42017388343811 1.153337478637695 C 1.42017388343811 1.371437430381775 0.1783738434314728 1.480897426605225 -0.03972615301609039 1.480897426605225 Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="red_things" data-name="red things" transform="translate(2.962 5.529)">
|
||||
<ellipse id="red_dot" data-name="red dot" class="cls-9" cx="1.975" cy="1.975" rx="1.975" ry="1.975" transform="translate(6.713 3.85)"/>
|
||||
<path id="red_arrow_1" data-name="red arrow 1" class="cls-9" d="M3121.088-1937.325a6.718,6.718,0,0,1-.494-7.01c.151.093.443.226.592.3.42.239.482-.2.4-.494l-.79-2.468-2.468.691a.939.939,0,0,0-.3.1c-.129.082-.24.258,0,.395l.691.395a8.146,8.146,0,0,0,.691,9.28C3120.449-1936.882,3121.088-1937.325,3121.088-1937.325Z" transform="translate(-3117.592 1947)"/>
|
||||
<path id="red_arrow_2" data-name="red arrow 2" class="cls-9" d="M3118.12-1937.325a6.718,6.718,0,0,0,.493-7.01c-.151.093-.443.226-.592.3-.42.239-.482-.2-.395-.494l.79-2.468,2.468.691a.943.943,0,0,1,.3.1c.128.082.24.258,0,.395l-.691.395a8.147,8.147,0,0,1-.691,9.28C3118.758-1936.882,3118.12-1937.325,3118.12-1937.325Z" transform="translate(-3104.259 1947)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.3 KiB |
65
legoresources/Block icns/icn_block_medium_motor.svg
Normal file
@ -0,0 +1,65 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1323.372 8463.761 30.979 30.979">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #3c3c3c;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #b72b1c;
|
||||
stroke: #8b1104;
|
||||
stroke-width: 0.25px;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
filter: url(#Union_1);
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.919" x2="0.5" y2="1.077" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#a8a9a8"/>
|
||||
<stop offset="1" stop-color="#545554"/>
|
||||
</linearGradient>
|
||||
<filter id="Union_1" x="1323.372" y="8463.761" width="30.979" height="30.979" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="0.375" result="blur"/>
|
||||
<feFlood flood-opacity="0.322"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="icn_block_medium_motor" transform="translate(666.315 8209.204)">
|
||||
<g id="Group_4" data-name="Group 4" transform="translate(658.182 255.683)">
|
||||
<path id="Path_1" data-name="Path 1" class="cls-1" d="M2.383-.287H27.768A1.534,1.534,0,0,1,29.44,1V27.258c0,.654-.714,1.185-1.673,1.185H2.383c-.959,0-1.673-.531-1.673-1.185V1A1.534,1.534,0,0,1,2.383-.287Z" transform="translate(-0.711 0.287)"/>
|
||||
</g>
|
||||
<g id="Group_7" data-name="Group 7" transform="translate(686.912 255.683) rotate(90)">
|
||||
<g class="cls-7" transform="matrix(0, -1, 1, 0, -8464.89, 1353.23)">
|
||||
<path id="Union_1-2" data-name="Union 1" class="cls-2" d="M13.822,28.729a4.048,4.048,0,0,1-4.048-4.048V18.955H4.048A4.048,4.048,0,0,1,0,14.908V13.822A4.048,4.048,0,0,1,4.048,9.774H9.774V4.048A4.048,4.048,0,0,1,13.822,0h1.086a4.048,4.048,0,0,1,4.048,4.048V9.774h5.726a4.048,4.048,0,0,1,4.048,4.048v1.086a4.048,4.048,0,0,1-4.048,4.048H18.955v5.726a4.048,4.048,0,0,1-4.048,4.048Z" transform="translate(1353.23 8464.89) rotate(90)"/>
|
||||
</g>
|
||||
<ellipse id="Ellipse_1" data-name="Ellipse 1" class="cls-3" cx="3.159" cy="3.159" rx="3.159" ry="3.159" transform="translate(11.255 0.987)"/>
|
||||
<ellipse id="Ellipse_2" data-name="Ellipse 2" class="cls-3" cx="3.159" cy="3.159" rx="3.159" ry="3.159" transform="translate(11.255 21.424)"/>
|
||||
<ellipse id="Ellipse_1-2" data-name="Ellipse 1" class="cls-3" cx="3.159" cy="3.159" rx="3.159" ry="3.159" transform="translate(0.987 17.475) rotate(-90)"/>
|
||||
<ellipse id="Ellipse_2-2" data-name="Ellipse 2" class="cls-3" cx="3.159" cy="3.159" rx="3.159" ry="3.159" transform="translate(21.424 17.475) rotate(-90)"/>
|
||||
</g>
|
||||
<g id="Ellipse_4" data-name="Ellipse 4" class="cls-4" transform="translate(668.3 265.702)">
|
||||
<ellipse class="cls-5" cx="4.395" cy="4.395" rx="4.395" ry="4.395"/>
|
||||
<ellipse class="cls-6" cx="4.395" cy="4.395" rx="4.27" ry="4.27"/>
|
||||
</g>
|
||||
<path id="Hole" d="M5605.5,961.821s-.035.664-.5.67-.952,0-.952,0a1.541,1.541,0,0,0-.3,1.1c0,.824.232,1.045.232,1.045h1.06a.42.42,0,0,1,.454.454v1.085a2.528,2.528,0,0,0,1.149.187,4.2,4.2,0,0,0,1.091-.187v-1.085a.475.475,0,0,1,.478-.454,6.978,6.978,0,0,0,.94-.091s.257-.243.282-1.062-.23-1.07-.23-1.07h-1.1a.417.417,0,0,1-.5-.441,7.426,7.426,0,0,1,0-1.07,3.135,3.135,0,0,0-2.113,0C5605.488,961.354,5605.5,961.821,5605.5,961.821Z" transform="translate(-4933.915 -693.478)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
84
legoresources/Block icns/icn_block_touch_sensor.svg
Normal file
@ -0,0 +1,84 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1327.51 8602.067 23.497 21.72">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #a8a9a8;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
clip-path: url(#clip-path);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: url(#linear-gradient-2);
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #b72b1c;
|
||||
stroke: #8b1104;
|
||||
stroke-width: 0.25px;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.cls-8 {
|
||||
filter: url(#Path_1);
|
||||
}
|
||||
</style>
|
||||
<clipPath id="clip-path">
|
||||
<path id="Union_3" data-name="Union 3" class="cls-1" d="M2.567,21.72c-.7,0-1.283-.393-1.283-.889V17.968H.651A.651.651,0,0,1,0,17.317V4.8a.651.651,0,0,1,.651-.651h.633V.889C1.283.394,1.871,0,2.567,0H9.576V.889h4.147V0H20.93c.7,0,1.283.394,1.283.889V4.147h.633A.65.65,0,0,1,23.5,4.8v12.52a.651.651,0,0,1-.651.651h-.633v2.863c0,.5-.588.889-1.283.889Z"/>
|
||||
</clipPath>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.91" x2="0.5" y2="1.046" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#a8a9a8"/>
|
||||
<stop offset="1" stop-color="#545554"/>
|
||||
</linearGradient>
|
||||
<filter id="Path_1" x="1325.794" y="8599.067" width="26.93" height="27.72" filterUnits="userSpaceOnUse">
|
||||
<feOffset input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="1" result="blur"/>
|
||||
<feFlood flood-opacity="0.502"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<linearGradient id="linear-gradient-2" x1="0.949" y1="0.5" x2="0.056" y2="0.5" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#b72b1c"/>
|
||||
<stop offset="1" stop-color="#8b1104"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="icn_block_touch_sensor" transform="translate(666.315 8209.204)">
|
||||
<g id="Group_8" data-name="Group 8" transform="translate(661.196 392.864)">
|
||||
<g id="Mask_Group_3" data-name="Mask Group 3" class="cls-2">
|
||||
<g id="Group_2" data-name="Group 2" transform="translate(0 0)">
|
||||
<path id="Path_27" data-name="Path 27" class="cls-1" d="M.494,0H23A.494.494,0,0,1,23.5.494V13.328a.494.494,0,0,1-.494.494H.494A.494.494,0,0,1,0,13.328V.494A.494.494,0,0,1,.494,0Z" transform="translate(0 4.147)"/>
|
||||
<g class="cls-8" transform="matrix(1, 0, 0, 1, -1327.51, -8602.07)">
|
||||
<path id="Path_1-2" data-name="Path 1" class="cls-3" d="M1.283,0h7.01V.889H12.44V0h7.207c.7,0,1.283.393,1.283.889V20.831c0,.5-.588.889-1.283.889H1.283c-.7,0-1.283-.393-1.283-.889V.889C0,.393.588,0,1.283,0Z" transform="translate(1328.79 8602.07)"/>
|
||||
</g>
|
||||
<rect id="Rectangle_2" data-name="Rectangle 2" width="0.494" height="3.949" transform="translate(22.51 6.121)"/>
|
||||
<rect id="Rectangle_5" data-name="Rectangle 5" width="0.494" height="3.949" transform="translate(0.592 6.121)"/>
|
||||
<rect id="Rectangle_3" data-name="Rectangle 3" width="0.494" height="3.949" transform="translate(22.51 11.748)"/>
|
||||
<rect id="Rectangle_4" data-name="Rectangle 4" width="0.494" height="3.949" transform="translate(0.592 11.748)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group_5" data-name="Group 5" transform="translate(664.158 395.579)">
|
||||
<rect id="Rectangle_6" data-name="Rectangle 6" class="cls-4" width="6.22" height="4.048" transform="translate(0 6.861)"/>
|
||||
<rect id="Rectangle_9" data-name="Rectangle 9" class="cls-4" width="6.22" height="4.048" transform="translate(10.811) rotate(90)"/>
|
||||
<rect id="Rectangle_7" data-name="Rectangle 7" class="cls-4" width="6.22" height="4.048" transform="translate(17.573 10.909) rotate(180)"/>
|
||||
<rect id="Rectangle_8" data-name="Rectangle 8" class="cls-4" width="6.22" height="4.048" transform="translate(6.763 17.573) rotate(-90)"/>
|
||||
<g id="Ellipse_1" data-name="Ellipse 1" class="cls-5" transform="translate(4.838 4.887)">
|
||||
<ellipse class="cls-6" cx="3.949" cy="3.949" rx="3.949" ry="3.949"/>
|
||||
<ellipse class="cls-7" cx="3.949" cy="3.949" rx="3.824" ry="3.824"/>
|
||||
</g>
|
||||
<path id="Hole" d="M5605.323,961.71s-.032.6-.45.6-.854,0-.854,0a1.382,1.382,0,0,0-.266.989c0,.74.208.939.208.939h.953a.378.378,0,0,1,.409.408v.975a2.269,2.269,0,0,0,1.033.168,3.77,3.77,0,0,0,.98-.168v-.975a.426.426,0,0,1,.43-.408,6.239,6.239,0,0,0,.845-.082s.231-.219.253-.955-.207-.961-.207-.961h-.99a.375.375,0,0,1-.446-.4,6.76,6.76,0,0,1,0-.961,2.814,2.814,0,0,0-1.9,0C5605.313,961.289,5605.323,961.71,5605.323,961.71Z" transform="translate(-5597.534 -954.45)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
103
legoresources/Block icns/icn_block_ultra_sonic.svg
Normal file
@ -0,0 +1,103 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1324.724 8870.247 54.201 22.707">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #f2f2f2;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #292929;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke: rgba(242,242,242,0.5);
|
||||
stroke-width: 0.15px;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #931f1f;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #9d761f;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
clip-path: url(#clip-path);
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.cls-8 {
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
<clipPath id="clip-path">
|
||||
<ellipse id="guld" class="cls-1" cx="4.541" cy="4.541" rx="4.541" ry="4.541"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="icn_block_ultra_sonic" transform="translate(666.315 8209.204)">
|
||||
<rect id="Rectangle_1" data-name="Rectangle 1" class="cls-2" width="28.236" height="20.338" transform="translate(673.021 661.932)"/>
|
||||
<rect id="Rectangle_2" data-name="Rectangle 2" width="16.487" height="11.452" transform="translate(677.958 666.474)"/>
|
||||
<g id="eye1" transform="translate(658.41 661.044)">
|
||||
<g id="sort" class="cls-3" transform="translate(0 0)">
|
||||
<ellipse class="cls-7" cx="11.354" cy="11.354" rx="11.354" ry="11.354"/>
|
||||
<ellipse class="cls-8" cx="11.354" cy="11.354" rx="11.279" ry="11.279"/>
|
||||
</g>
|
||||
<ellipse id="rød" class="cls-4" cx="7.01" cy="7.01" rx="7.01" ry="7.01" transform="translate(4.344 4.344)"/>
|
||||
<ellipse id="guld-3" data-name="guld" class="cls-5" cx="5.232" cy="5.232" rx="5.232" ry="5.232" transform="translate(6.121 6.121)"/>
|
||||
<ellipse id="guld-4" data-name="guld" class="cls-1" cx="4.541" cy="4.541" rx="4.541" ry="4.541" transform="translate(6.812 6.812)"/>
|
||||
<g id="Group_5" data-name="Group 5" transform="translate(6.812 6.812)">
|
||||
<g id="Mask_Group_8" data-name="Mask Group 8" class="cls-6">
|
||||
<g id="Group_17" data-name="Group 17" transform="translate(-4.652 2.089) rotate(-30)">
|
||||
<rect id="Rectangle_84" data-name="Rectangle 84" class="cls-5" width="0.395" height="14.834" transform="translate(1.333 0)"/>
|
||||
<rect id="Rectangle_91" data-name="Rectangle 91" class="cls-5" width="0.395" height="14.649" transform="translate(0 13.081) rotate(-90)"/>
|
||||
<rect id="Rectangle_85" data-name="Rectangle 85" class="cls-5" width="0.395" height="14.834" transform="translate(3.209 0)"/>
|
||||
<rect id="Rectangle_97" data-name="Rectangle 97" class="cls-5" width="0.395" height="14.649" transform="translate(0 11.205) rotate(-90)"/>
|
||||
<rect id="Rectangle_86" data-name="Rectangle 86" class="cls-5" width="0.395" height="14.834" transform="translate(5.084 0)"/>
|
||||
<rect id="Rectangle_96" data-name="Rectangle 96" class="cls-5" width="0.395" height="14.649" transform="translate(0 9.33) rotate(-90)"/>
|
||||
<rect id="Rectangle_87" data-name="Rectangle 87" class="cls-5" width="0.395" height="14.834" transform="translate(6.96 0)"/>
|
||||
<rect id="Rectangle_95" data-name="Rectangle 95" class="cls-5" width="0.395" height="14.649" transform="translate(0 7.454) rotate(-90)"/>
|
||||
<rect id="Rectangle_88" data-name="Rectangle 88" class="cls-5" width="0.395" height="14.834" transform="translate(8.836 0)"/>
|
||||
<rect id="Rectangle_94" data-name="Rectangle 94" class="cls-5" width="0.395" height="14.649" transform="translate(0 5.578) rotate(-90)"/>
|
||||
<rect id="Rectangle_89" data-name="Rectangle 89" class="cls-5" width="0.395" height="14.834" transform="translate(10.712 0)"/>
|
||||
<rect id="Rectangle_93" data-name="Rectangle 93" class="cls-5" width="0.395" height="14.649" transform="translate(0 3.702) rotate(-90)"/>
|
||||
<rect id="Rectangle_90" data-name="Rectangle 90" class="cls-5" width="0.395" height="14.834" transform="translate(12.588 0)"/>
|
||||
<rect id="Rectangle_92" data-name="Rectangle 92" class="cls-5" width="0.395" height="14.649" transform="translate(0 1.826) rotate(-90)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="eye2" transform="translate(689.903 661.044)">
|
||||
<g id="sort-2" data-name="sort" class="cls-3" transform="translate(0 0)">
|
||||
<ellipse class="cls-7" cx="11.354" cy="11.354" rx="11.354" ry="11.354"/>
|
||||
<ellipse class="cls-8" cx="11.354" cy="11.354" rx="11.279" ry="11.279"/>
|
||||
</g>
|
||||
<ellipse id="rød-2" data-name="rød" class="cls-4" cx="7.01" cy="7.01" rx="7.01" ry="7.01" transform="translate(4.344 4.344)"/>
|
||||
<ellipse id="guld-5" data-name="guld" class="cls-5" cx="5.232" cy="5.232" rx="5.232" ry="5.232" transform="translate(6.121 6.121)"/>
|
||||
<ellipse id="guld-6" data-name="guld" class="cls-1" cx="4.541" cy="4.541" rx="4.541" ry="4.541" transform="translate(6.812 6.812)"/>
|
||||
<g id="Group_18" data-name="Group 18" transform="translate(6.812 6.812)">
|
||||
<g id="Mask_Group_8-2" data-name="Mask Group 8" class="cls-6">
|
||||
<g id="Group_17-2" data-name="Group 17" transform="translate(-4.652 2.089) rotate(-30)">
|
||||
<rect id="Rectangle_84-2" data-name="Rectangle 84" class="cls-5" width="0.395" height="14.834" transform="translate(1.333 0)"/>
|
||||
<rect id="Rectangle_91-2" data-name="Rectangle 91" class="cls-5" width="0.395" height="14.649" transform="translate(0 13.081) rotate(-90)"/>
|
||||
<rect id="Rectangle_85-2" data-name="Rectangle 85" class="cls-5" width="0.395" height="14.834" transform="translate(3.209 0)"/>
|
||||
<rect id="Rectangle_97-2" data-name="Rectangle 97" class="cls-5" width="0.395" height="14.649" transform="translate(0 11.205) rotate(-90)"/>
|
||||
<rect id="Rectangle_86-2" data-name="Rectangle 86" class="cls-5" width="0.395" height="14.834" transform="translate(5.084 0)"/>
|
||||
<rect id="Rectangle_96-2" data-name="Rectangle 96" class="cls-5" width="0.395" height="14.649" transform="translate(0 9.33) rotate(-90)"/>
|
||||
<rect id="Rectangle_87-2" data-name="Rectangle 87" class="cls-5" width="0.395" height="14.834" transform="translate(6.96 0)"/>
|
||||
<rect id="Rectangle_95-2" data-name="Rectangle 95" class="cls-5" width="0.395" height="14.649" transform="translate(0 7.454) rotate(-90)"/>
|
||||
<rect id="Rectangle_88-2" data-name="Rectangle 88" class="cls-5" width="0.395" height="14.834" transform="translate(8.836 0)"/>
|
||||
<rect id="Rectangle_94-2" data-name="Rectangle 94" class="cls-5" width="0.395" height="14.649" transform="translate(0 5.578) rotate(-90)"/>
|
||||
<rect id="Rectangle_89-2" data-name="Rectangle 89" class="cls-5" width="0.395" height="14.834" transform="translate(10.712 0)"/>
|
||||
<rect id="Rectangle_93-2" data-name="Rectangle 93" class="cls-5" width="0.395" height="14.649" transform="translate(0 3.702) rotate(-90)"/>
|
||||
<rect id="Rectangle_90-2" data-name="Rectangle 90" class="cls-5" width="0.395" height="14.834" transform="translate(12.588 0)"/>
|
||||
<rect id="Rectangle_92-2" data-name="Rectangle 92" class="cls-5" width="0.395" height="14.649" transform="translate(0 1.826) rotate(-90)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.0 KiB |
73
legoresources/Blocks_Implemented_In_Swift_Playgrounds.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Functions for measuring in Swift Playgrounds "EV3 Animal Rescue" (Miranda)
|
||||
|
||||
## Sensors
|
||||
|
||||
* Ultrasonic (cm, inches)
|
||||
* Gyro (angle, rate)
|
||||
* Reset Gyro
|
||||
* Touch (count, on/off)
|
||||
* Light (color, reflection, ambience)
|
||||
* IR (proximity, seek)
|
||||
|
||||
## Motor Sensors
|
||||
|
||||
* Motor (degrees, rotations, power)
|
||||
|
||||
#### Wait for
|
||||
|
||||
All sensor methods have a `waitFor` version that waits for the sensor value to be >= or <=. We don't use '=' equality because it is non-sensical for floating point data.
|
||||
|
||||
All sensors also have a `waitForIncrease`, `waitForDecrease` version.
|
||||
|
||||
------------------------
|
||||
|
||||
# Output Functions
|
||||
|
||||
* Move tank ( for seconds, for degrees, for rotations, indefinitely )
|
||||
* Stop Move (stops 2 motors)
|
||||
* Motor off
|
||||
* Motor on (for seconds, for degrees, for rotations, indefinitely)
|
||||
* Reset motor (resets all counters related to the motor)
|
||||
|
||||
|
||||
# Brick Functions
|
||||
|
||||
* Brick light on (color + mode: flashing, on, or pulsating)
|
||||
* Brick light off
|
||||
* Play sound (wait for completion, play once, play repeating)
|
||||
- Parameters:
|
||||
- file: Takes an input conforming to enum `SoundFile`. One of the following:
|
||||
- `.hello`
|
||||
- `.goodbye`
|
||||
- `.fanfare`
|
||||
- `.errorAlarm`
|
||||
- `.start`
|
||||
- `.stop`
|
||||
- `.object`
|
||||
- `.ouch`
|
||||
- `.blip`
|
||||
- `.arm`
|
||||
- `.snap`
|
||||
- `.laser`
|
||||
* Play sound frequency (for seconds, can either wait for completion or continue while playing)
|
||||
* Play sound note (in range `C4-D#9`) (for seconds, can either wait for completion or continue while playing)
|
||||
* Stopsound (stops all sounds playing)
|
||||
* Wait for seconds
|
||||
* Display text
|
||||
* Display text at `(x,y)` with color`(black, white)`, font`(bold, normal, large)` with option to clear screen
|
||||
* Display line from `(x1,y1)` to `(x2,y2)` with color `(black, white)` option to clear screen
|
||||
* Display rectangle at `(x,y)` with `(width, height)`, with fill or no fill, with color `(black, white)`, option to clear screen
|
||||
* Display image at `(x,y)`, option to clear screen.
|
||||
takes an input conforming to enum `ImageName`. One of the following:
|
||||
- `.neutral`
|
||||
- `.pinchRight`
|
||||
- `.awake`
|
||||
- `.hurt`
|
||||
- `.accept`
|
||||
- `.decline`
|
||||
- `.questionMark`
|
||||
- `.warning`
|
||||
- `.stop`
|
||||
- `.pirate`
|
||||
- `.boom`
|
||||
- `.ev3Icon`
|
After Width: | Height: | Size: 375 KiB |
BIN
legoresources/MC22122017/01b - MakeCode - basicdesign@2x.png
Normal file
After Width: | Height: | Size: 384 KiB |
After Width: | Height: | Size: 383 KiB |
After Width: | Height: | Size: 418 KiB |
BIN
legoresources/MC22122017/02a - MakeCode - portselector@2x.png
Normal file
After Width: | Height: | Size: 386 KiB |
BIN
legoresources/MC22122017/03a - MakeCode - all elements@2x.png
Normal file
After Width: | Height: | Size: 442 KiB |
BIN
legoresources/MC22122017/03b - MakeCode - motorsync@2x.png
Normal file
After Width: | Height: | Size: 404 KiB |
BIN
legoresources/MC22122017/04a - MakeCode - medmotor@2x.png
Normal file
After Width: | Height: | Size: 430 KiB |
BIN
legoresources/MC22122017/04b - MakeCode - medmotor@2x.png
Normal file
After Width: | Height: | Size: 428 KiB |
BIN
legoresources/MC22122017/05a - MakeCode - large motor@2x.png
Normal file
After Width: | Height: | Size: 426 KiB |
BIN
legoresources/MC22122017/05b - MakeCode - large motor@2x.png
Normal file
After Width: | Height: | Size: 425 KiB |
BIN
legoresources/MC22122017/06 - MakeCode - color - 1@2x.png
Normal file
After Width: | Height: | Size: 428 KiB |
BIN
legoresources/MC22122017/06 - MakeCode - color - 2@2x.png
Normal file
After Width: | Height: | Size: 422 KiB |
BIN
legoresources/MC22122017/06 - MakeCode - color - 3@2x.png
Normal file
After Width: | Height: | Size: 429 KiB |
BIN
legoresources/MC22122017/07a - MakeCode - Gyro@2x.png
Normal file
After Width: | Height: | Size: 423 KiB |
BIN
legoresources/MC22122017/07b - MakeCode - Gyro@2x.png
Normal file
After Width: | Height: | Size: 413 KiB |
BIN
legoresources/MC22122017/08 - MakeCode - UltraSound@2x.png
Normal file
After Width: | Height: | Size: 408 KiB |
BIN
legoresources/MC22122017/09a - MakeCode - display image@2x.png
Normal file
After Width: | Height: | Size: 478 KiB |