54
54
55
55
type
56
56
TArrayOfByte = Array of Byte;
57
+ PMicroBitPeripheral = ^TMicroBitPeripheral;
58
+ TMicroBitPeripheral = record
59
+ AddressString:String;
60
+ ButtonCounter:Integer;
61
+ ButtonChordStarted:Boolean;
62
+ end ;
57
63
58
64
var
65
+ MicroBitPeripherals:Array of TMicroBitPeripheral;
59
66
ScanRxCount:Integer;
60
67
BluetoothUartDeviceDescription:String;
61
68
ScanCycleCounter:LongWord;
69
76
UART0:PSerialDevice = Nil ;
70
77
KeyboardLoopHandle:TThreadHandle = INVALID_HANDLE_VALUE;
71
78
ReadByteCounter:Integer;
72
- ButtonCounter:Integer;
73
- ButtonChordStarted:Boolean;
74
79
75
80
function ReadByte :Byte; forward ;
76
81
@@ -255,20 +260,6 @@ procedure HciCommand(OGF:byte; OCF:Word; Params:array of byte);
255
260
HciCommand((OGF shl 10 ) or OCF,Params);
256
261
end ;
257
262
258
- procedure SetLEScanResponseData (Data:array of byte);
259
- var
260
- Params:array of byte;
261
- Len:byte;
262
- i:integer;
263
- begin
264
- Len:=Min(Length(Data),31 );
265
- SetLength(Params,Len + 1 );
266
- Params[0 ]:=Len;
267
- for i:=0 to Len - 1 do
268
- Params[i + 1 ]:=Data[i];
269
- HciCommand(OGF_LE_CONTROL,$09 ,Params);
270
- end ;
271
-
272
263
function EventReadFirstByte :Byte;
273
264
var
274
265
c:LongWord;
@@ -564,7 +555,7 @@ function KeyboardLoop(Parameter:Pointer):PtrInt;
564
555
' Q' : SystemRestart(0 );
565
556
' R' :
566
557
begin
567
- RestoreBootFile(' bluetooth-dev-bluetoothtest ' ,' config.txt' );
558
+ RestoreBootFile(' microbitdemo ' ,' config.txt' );
568
559
SystemRestart(0 );
569
560
end ;
570
561
end ;
@@ -599,6 +590,29 @@ function AsWord(Hi,Lo:Integer):Word;
599
590
Result:=(Hi shl 8 ) or Lo;
600
591
end ;
601
592
593
+ function FindOrMakeMicroBitPeripheral (NewAddressString:String):PMicroBitPeripheral;
594
+ var
595
+ I:Integer;
596
+ begin
597
+ Result:=Nil ;
598
+ for I:= 0 to High(MicroBitPeripherals) do
599
+ if MicroBitPeripherals[I].AddressString = NewAddressString then
600
+ Result:=@MicroBitPeripherals[I];
601
+ if Result = nil then
602
+ begin
603
+ SetLength(MicroBitPeripherals,Length(MicroBitPeripherals) + 1 );
604
+ Result:=@MicroBitPeripherals[High(MicroBitPeripherals)];
605
+ with Result^ do
606
+ begin
607
+ AddressString:=NewAddressString;
608
+ ButtonCounter:=0 ;
609
+ ButtonChordStarted:=False;
610
+ end ;
611
+ Log(' ' );
612
+ Log(Format(' detected new micro:bit peripheral %s' ,[NewAddressString]));
613
+ end ;
614
+ end ;
615
+
602
616
procedure ParseEvent ;
603
617
var
604
618
I:Integer;
@@ -613,6 +627,10 @@ procedure ParseEvent;
613
627
LeEventType:Byte;
614
628
NewButtonCounter:Integer;
615
629
ButtonMessage:String;
630
+ CounterByte:Byte;
631
+ MicroEventIndex:Integer;
632
+ MicroEvent:Byte;
633
+ MicroBitPeripheral:PMicroBitPeripheral;
616
634
function GetByte :Byte;
617
635
begin
618
636
Result:=Event[GetByteIndex];
@@ -675,8 +693,9 @@ function GetByte:Byte;
675
693
MfrHi:=GetByte;
676
694
SignatureLo:=GetByte;
677
695
SignatureHi:=GetByte;
678
- if (MainType = $ff) and (AsWord(MfrHi,MfrLo) = Word(ManufacturerTesting)) and (SignatureLo = $ 55 ) and (SignatureHi = $97 ) then
696
+ if (MainType = $ff) and (AsWord(MfrHi,MfrLo) = Word(ManufacturerTesting)) and (AsWord (SignatureHi,Signaturelo) = $9755 ) then
679
697
begin
698
+ MicroBitPeripheral:=FindOrMakeMicroBitPeripheral(AddressString);
680
699
GetByteIndex:=20 ;
681
700
NewButtonCounter:=(GetByte - Ord(' 0' ))*10 ;
682
701
NewButtonCounter:=NewButtonCounter + (GetByte - Ord(' 0' ));
@@ -685,28 +704,77 @@ function GetByte:Byte;
685
704
begin
686
705
S:=S + Char(GetByte);
687
706
end ;
688
- if NewButtonCounter <> ButtonCounter then
707
+ if NewButtonCounter <> MicroBitPeripheral^. ButtonCounter then
689
708
begin
690
- ButtonCounter:=NewButtonCounter;
691
- if not ButtonChordStarted then
709
+ MicroBitPeripheral^. ButtonCounter:=NewButtonCounter;
710
+ if not MicroBitPeripheral^. ButtonChordStarted then
692
711
begin
693
712
LoggingOutput(' ' );
694
- ButtonChordStarted:=True;
713
+ MicroBitPeripheral^. ButtonChordStarted:=True;
695
714
end ;
696
715
case S[1 ] of
697
716
' 0' :
698
717
begin
699
718
ButtonMessage:=' Released ' ;
700
- ButtonChordStarted:=False;
719
+ MicroBitPeripheral^. ButtonChordStarted:=False;
701
720
end ;
702
721
' 1' : ButtonMessage:=' A down ' ;
703
722
' 2' : ButtonMessage:=' B down ' ;
704
723
' 3' : ButtonMessage:=' A and B down' ;
705
724
else ButtonMessage:=' ????????????' ;
706
725
end ;
707
- LoggingOutput(Format(' micro:bit addr %s %s - %02.2d events, history: %s' ,[AddressString,ButtonMessage,ButtonCounter,S]));
726
+ LoggingOutput(Format(' micro:bit addr %s %s - %02.2d events, history: %s' ,[AddressString,ButtonMessage,MicroBitPeripheral^. ButtonCounter,S]));
708
727
end ;
709
- end ;
728
+ end
729
+ else if (MainType = $ff) and (AsWord(MfrHi,MfrLo) = Word(ManufacturerTesting)) and (AsWord(SignatureHi,SignatureLo) = $9855 ) then
730
+ begin
731
+ MicroBitPeripheral:=FindOrMakeMicroBitPeripheral(AddressString);
732
+ GetByteIndex:=20 ;
733
+ CounterByte:=GetByte;
734
+ NewbuttonCounter:=CounterByte and $7f ;
735
+ S:=' ' ;
736
+ while GetByteIndex <= High(Event) do
737
+ S:=S + Char(Ord(' 0' ) + (GetByte shr 6 ));
738
+ while (MicroBitPeripheral^.ButtonCounter mod 128 ) <> NewButtonCounter do
739
+ begin
740
+ Inc(MicroBitPeripheral^.ButtonCounter);
741
+ MicroEventIndex:=NewButtonCounter - (MicroBitPeripheral^.ButtonCounter mod 128 );
742
+ // Log(Format('counter %d new %d index %d %s',[MicroBitPeripheral^.ButtonCounter,NewButtonCounter,MicroEventIndex,S]));
743
+ if MicroEventIndex < 0 then
744
+ Inc(MicroEventIndex,128 );
745
+ if MicroEventIndex >= 21 then
746
+ begin
747
+ Log(Format(' unable to reconstruct event %d index %d from %d %s' ,[MicroBitPeripheral^.ButtonCounter,MicroEventIndex,NewButtonCounter,S]));
748
+ if (CounterByte and $80 ) = 0 then
749
+ begin
750
+ MicroBitPeripheral^.ButtonCounter:=NewButtonCounter;
751
+ Log(' the micro:bit seems to have restarted' );
752
+ end ;
753
+ end
754
+ else
755
+ begin
756
+ GetByteIndex:=21 + MicroEventIndex;
757
+ if not MicroBitPeripheral^.ButtonChordStarted then
758
+ begin
759
+ LoggingOutput(' ' );
760
+ MicroBitPeripheral^.ButtonChordStarted:=True;
761
+ end ;
762
+ MicroEvent:=GetByte shr 6 ;
763
+ case MicroEvent of
764
+ 0 :
765
+ begin
766
+ ButtonMessage:=' Released ' ;
767
+ MicroBitPeripheral^.ButtonChordStarted:=False;
768
+ end ;
769
+ 1 : ButtonMessage:=' A down ' ;
770
+ 2 : ButtonMessage:=' B down ' ;
771
+ 3 : ButtonMessage:=' A and B down' ;
772
+ else ButtonMessage:=' ????????????' ;
773
+ end ;
774
+ LoggingOutput(Format(' micro:bit addr %s event number %03.3d %s - history: %s' ,[AddressString,MicroBitPeripheral^.ButtonCounter,ButtonMessage,S]));
775
+ end ;
776
+ end ;
777
+ end ;
710
778
end ;
711
779
712
780
begin
@@ -734,8 +802,7 @@ function GetByte:Byte;
734
802
Log(' Init complete' );
735
803
ScanCycleCounter:=0 ;
736
804
ReadByteCounter:=0 ;
737
- ButtonCounter:=0 ;
738
- ButtonChordStarted:=False;
805
+ SetLength(MicroBitPeripherals,0 );
739
806
while True do
740
807
begin
741
808
ReadBackLog:=0 ;
0 commit comments