Skip to content

Commit

Permalink
Connect to micro:bit automatically when sending scripts.
Browse files Browse the repository at this point in the history
  • Loading branch information
EiichiroIto committed Apr 16, 2021
1 parent 494955c commit 8e64b4a
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 26 deletions.
4 changes: 2 additions & 2 deletions Plugins/win/MicrowitchPlugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ EXPORT int primMicrobitDevice(void);
EXPORT int primEnumerateComPorts(void);
EXPORT int setInterpreter(struct VirtualMachine* anInterpreter);

char nameStr[2048];

EXPORT int primMicrobitDevice(void) {
char nameStr[1000];
int i;
int ret;
int count;
Expand All @@ -52,7 +53,6 @@ EXPORT int primMicrobitDevice(void) {
}

EXPORT int primEnumerateComPorts(void) {
char nameStr[1000];
int i;
int ret;
int resultOop;
Expand Down
Binary file modified Plugins/win/MicrowitchPlugin.dll
Binary file not shown.
51 changes: 38 additions & 13 deletions Plugins/win/winMicrowitchOps.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,52 +69,77 @@ EnumerateComPorts(char *dst, int max)
int i;
char *ptr = dst;
int org_max = max;
TCHAR tmpbuf[256];
TCHAR tmpbuf[512];

SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT, NULL, NULL, (DIGCF_PRESENT|DIGCF_DEVICEINTERFACE));
for (i=0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) {
HKEY key = SetupDiOpenDevRegKey(hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
if ( key ) {
DWORD type;
DWORD size = sizeof(tmpbuf);
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, &type, (PBYTE)tmpbuf, size, &size)) {
continue;
}
if (_tcscmp(tmpbuf, _T("USB\\VID_0D28&PID_0204&REV_1000&MI_01"))) {
continue;
}
DWORD size, size2;
type = 0;
size = max;
RegQueryValueEx(key, _T("PortName"), NULL, &type , (LPBYTE) tmpbuf, &size);
size = WideCharToMultiByte(CP_ACP, 0, tmpbuf, wcslen(tmpbuf), ptr, max, NULL, NULL);
ptr[size++] = '\r';
#ifdef MAIN
ptr[size++] = '\n';
#else
ptr[size++] = '\r';
#endif /* MAIN */
size2 = sizeof(tmpbuf);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, &type, (PBYTE)tmpbuf, size2, &size2)) {
size2 = WideCharToMultiByte(CP_ACP, 0, tmpbuf, wcslen(tmpbuf), &ptr[size], max, NULL, NULL);
size += size2;
#ifdef MAIN
ptr[size++] = '\n';
#else
ptr[size++] = '\r';
#endif /* MAIN */
}
ptr[size] = 0;
ptr += size;
max -= size;
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return org_max - max;
}

#ifdef MAIN
#include <stdio.h>
char buffer[1024];

void
dump(const char *buf, int size)
{
int i, j;

for (i = 0; i < (size + 15) / 16; i ++) {
for (j = 0; j < 16; j ++) {
int pos = i * 16 + j;
if (pos < size) {
printf("%02X ", (unsigned int) buf[pos]);
}
}
printf("\n");
}
}

void
main(int argc, char *argv[])
{
int ret;
char buffer[1024];

memset(buffer, 0, sizeof buffer);
ret = MicrobitDevice(buffer, sizeof buffer);
printf("ret=%d,buf=%s\n", ret, buffer);
printf("Microbit Drive:\n%d bytes\n'%s'\n", ret, buffer);

memset(buffer, 0, sizeof buffer);
ret = EnumerateComPorts(buffer, sizeof buffer);
printf("size=%d\n", ret);
printf("ComPorts=<%s>\n", buffer);
printf("ComPorts:\n%d bytes\n%s\n", ret, buffer);
printf("Dumps:\n");
dump(buffer, ret);
}

#endif /* MAIN */
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ If the file selection dialog is displayed in the third step, micro:bit may not b
1. Wait "status: ready" for a few seconds.
1. When you click on the script you have created, it will be transferred to the micro:bit and executed.

## Trasnferring a script
## Transferring a script
Just clicking on the script you have created will not save the script
in the micro:bit, so the script in the micro:bit will be lost when you
power off or reboot.
Expand Down
6 changes: 6 additions & 0 deletions locale/ja.po
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -862,3 +862,9 @@ msgstr "スピーカーオフ"
msgid "no micro:bit found"
msgstr "micro:bit が見つかりません"

msgid "unable to find the appropriate firmware"
msgstr "適切なファームウェアが見つかりません"

msgid "initializing micro:bit done, please re-send scripts"
msgstr "micro:bit を初期化しました。もう一度送信してください"

6 changes: 6 additions & 0 deletions locale/ja_HIRA.po
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -862,3 +862,9 @@ msgstr "スピーカーオフ"
msgid "no micro:bit found"
msgstr "micro:bit がみつかりません"

msgid "unable to find the appropriate firmware"
msgstr "てきせつなファームウェアがみつかりません"

msgid "initializing micro:bit done, please re-send scripts"
msgstr "micro:bit をしょきかしました。もういちどそうしんしてください"

2 changes: 1 addition & 1 deletion microwitch.changes

Large diffs are not rendered by default.

Binary file modified microwitch.image
Binary file not shown.
Binary file added tools/checkmicrobit.exe
Binary file not shown.
1 change: 1 addition & 0 deletions v07/connect automatically.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'From MIT Squeak 0.9.4 (June 1, 2003) [No updates present.] on 15 April 2021 at 9:25:30 pm'!Object subclass: #MicroPythonBoard instanceVariableNames: 'port portName currentState response count requests returnValue interrupt useRaw ' classVariableNames: 'PasteModeString PromptString UseAllPorts ' poolDictionaries: '' category: 'MicroPython-Board'!!MicroPythonBoard methodsFor: 'private'!hardwareIdFrom: aString | index vid pid | index := aString findString: 'VID_'. vid := index > 0 ifTrue: [aString copyFrom: index + 4 to: index + 7]. index := aString findString: 'PID_'. pid := index > 0 ifTrue: [aString copyFrom: index + 4 to: index + 7]. ^ Array with: vid with: pid! !!MicroPythonBoard methodsFor: 'serial port'!winPortNames | str list info | str := MicrowitchPlugin enumerateComPorts. str ifNil: [^ #()]. list := OrderedCollection new. str lines pairsDo: [:portname :each | info := self hardwareIdFrom: each. (self class useAllPorts or: [info first = '0D28' and: [info second = '0204']]) ifTrue: [list add: portname]]. ^ list asArray! !!MicroPythonBoard class methodsFor: 'accessing' stamp: 'EiichiroIto 4/13/2021 17:20'!useAllPorts ^ UseAllPorts! !!MicroPythonBoard class methodsFor: 'accessing' stamp: 'EiichiroIto 4/13/2021 17:21'!useAllPorts: aBoolean UseAllPorts := aBoolean! !!MicroPythonBoard class methodsFor: 'class initialization' stamp: 'EiichiroIto 4/13/2021 17:20'!initialize UseAllPorts := false! !!MicrobitCode class methodsFor: 'accessing'!firmwareFor: aSymbol ^ Firmware at: aSymbol ifAbsent: []! !!ScratchFrameMorph methodsFor: 'startup'!processSettingsFile "Process settings from the Scratch.ini file." | lang settings k | self class setVisibleDrives: nil. lang := nil. ScratchFileChooserDialog clearFolderCache. "clear homeDir and last folder cache" settings := self readSettingsFile. settings associationsDo: [:assoc | k := assoc key. k = 'allports' ifTrue: [MicroPythonBoard useAllPorts: assoc value asNumberNoError > 0]. k = 'language' ifTrue: [lang := assoc value]. k = 'home' ifTrue: [ScratchFileChooserDialog setHomeDir: assoc value]. k = 'visibledrives' ifTrue: [self class setVisibleDrives: assoc value]]. lang ifNil: [lang := ScratchTranslator guessLanguage]. self setLanguage: lang! !!ScratchFrameMorph methodsFor: 'microwitch'!connectMicrobit | list menu selection path ver id firmware | list := mpboard portNames sort. list isEmpty ifTrue: [^ DialogBoxMorph inform: 'no micro:bit found' localized]. list size = 1 ifTrue: [selection := list first] ifFalse: [menu := CustomMenu new. list do: [:each | menu add: each action: each]. selection := menu startUp. selection ifNil: [^ self]]. self connectPort: selection ifConnectedDo: [^ self]. path := MicrowitchPlugin microbitDevice. path ifNil: [^ DialogBoxMorph inform: 'no micro:bit found' localized]. id := self getMicrobitIDFrom: path , FileDirectory pathNameDelimiter asString , 'DETAILS.TXT'. ver := self microbitVersionForID: id. path := path , FileDirectory pathNameDelimiter asString , 'firmware.hex'. firmware := MicrobitCode firmwareFor: ver. firmware ifNil: [^ DialogBoxMorph inform: 'unable to find the appropriate firmware' localized]. self writeString: firmware as: path. DialogBoxMorph inform: 'initializing micro:bit done, please re-send scripts' localized! !!ScratchFrameMorph methodsFor: 'microwitch'!connectPort: aString ifConnectedDo: aBlock | timeout | mpboard closePort. mpboard openPort: aString. mpboard stop. timeout := Time millisecondClockValue + 1000. [Time millisecondClockValue > timeout] whileFalse: [mpboard step. mpboard isReady ifTrue: aBlock. (Delay forMilliseconds: 10) wait]. mpboard closePort! !!ScratchFrameMorph methodsFor: 'microwitch'!microbitMenu: aMenuTitleMorph | menu | menu := CustomMenu new. menu add: 'Send to micro:bit' action: #sendMicroPythonScript. mpboard isConnecting ifTrue: [menu add: 'Disconnect from micro:bit' action: #disconnectMicrobit] ifFalse: [menu add: 'Connect to micro:bit' action: #connectMicrobit]. menu addLine. menu add: 'initialize micro:bit' action: #uploadFirmware. menu add: 'show python code' action: #showPythonProgram. Sensor shiftPressed ifTrue: [menu addLine. menu add: 'inspect' action: #inspect. menu add: 'update firmware' action: #updateFirmware]. menu addLine. menu add: 'About micro:witch' action: #aboutScratch. menu localize. menu invokeOn: self at: aMenuTitleMorph bottomLeft + (0 @ 10)! !!ScratchFrameMorph methodsFor: 'microwitch'!sendMicroPythonScript | script code | self currentHatBlocks isEmpty ifTrue: [^ self]. self hasDuplicateHatBlocks ifTrue: [^ DialogBoxMorph inform: 'has duplicate hat blocks.' localized]. mpboard isConnecting ifFalse: [self connectMicrobit]. mpboard isConnecting ifFalse: [^ self]. self stopAll. code := MicrobitCode new newlineCR. script := code pythonScriptFrom: self currentHatBlocks stageMorph: workPane. self uploadExternalModules: code externalModules. mpboard write: script fileNamed: 'main.py'. mpboard reboot! !!ScratchFrameMorph methodsFor: 'microwitch'!uploadFirmware | path ver id firmware | self stopAll. self closeMediaEditorsAndDialogs ifFalse: [^ self]. ver := nil. path := MicrowitchPlugin microbitDevice. path ifNil: [path := self firmwarePathByUser. path ifNil: [^ self]. ver := self selectVersionByUser. ver ifNil: [^ self]] ifNotNil: [id := self getMicrobitIDFrom: path , FileDirectory pathNameDelimiter asString , 'DETAILS.TXT'. ver := self microbitVersionForID: id. path := path , FileDirectory pathNameDelimiter asString , 'firmware.hex']. firmware := MicrobitCode firmwareFor: ver. firmware ifNil: [^ DialogBoxMorph inform: 'unable to find the appropriate firmware' localized]. (DialogBoxMorph ask: 'initialize micro:bit?' localized) ifFalse: [^ self]. self writeString: firmware as: path! !!MicroPythonBoard class reorganize!('private' defaultBaudRate defaultTimeout reset)('accessing' pasteModeString promptString useAllPorts useAllPorts:)('class initialization' initialize)!MicroPythonBoard initialize.!
Expand Down
1 change: 1 addition & 0 deletions v07/filein.st
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@
'change default translation dir.cs'
'support for microbit v2.cs'
'fix some bugs.cs'
'connect automatically.cs'
) do: [:each | (FileStream fileNamed: 'v07/', each) fileIn].
13 changes: 4 additions & 9 deletions v07/readme.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
build scratch image
To build scratch image

ScratchSourceCode1.4 is needed.

fileIn files in following order.
DoIt filein.st in this folder.

1. Microwitch-Plugins.st
2. Microwitch-Objects.st
3. Microwitch-Translator.st
4. microwitch06-startup.cs
To build scratch plugin

build scratch plugin

see build.sh at Plugins directory.
execute build.sh in the Plugins directory.

0 comments on commit 8e64b4a

Please sign in to comment.