5454
5555type
5656 TArrayOfByte = Array of Byte;
57+ PMicroBitPeripheral = ^TMicroBitPeripheral;
58+ TMicroBitPeripheral = record
59+ AddressString:String;
60+ ButtonCounter:Integer;
61+ ButtonChordStarted:Boolean;
62+ end ;
5763
5864var
65+ MicroBitPeripherals:Array of TMicroBitPeripheral;
5966 ScanRxCount:Integer;
6067 BluetoothUartDeviceDescription:String;
6168 ScanCycleCounter:LongWord;
6976 UART0:PSerialDevice = Nil ;
7077 KeyboardLoopHandle:TThreadHandle = INVALID_HANDLE_VALUE;
7178 ReadByteCounter:Integer;
72- ButtonCounter:Integer;
73- ButtonChordStarted:Boolean;
7479
7580function ReadByte :Byte; forward ;
7681
@@ -255,20 +260,6 @@ procedure HciCommand(OGF:byte; OCF:Word; Params:array of byte);
255260 HciCommand((OGF shl 10 ) or OCF,Params);
256261end ;
257262
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-
272263function EventReadFirstByte :Byte;
273264var
274265 c:LongWord;
@@ -564,7 +555,7 @@ function KeyboardLoop(Parameter:Pointer):PtrInt;
564555 ' Q' : SystemRestart(0 );
565556 ' R' :
566557 begin
567- RestoreBootFile(' bluetooth-dev-bluetoothtest ' ,' config.txt' );
558+ RestoreBootFile(' microbitdemo ' ,' config.txt' );
568559 SystemRestart(0 );
569560 end ;
570561 end ;
@@ -599,6 +590,29 @@ function AsWord(Hi,Lo:Integer):Word;
599590 Result:=(Hi shl 8 ) or Lo;
600591end ;
601592
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+
602616procedure ParseEvent ;
603617var
604618 I:Integer;
@@ -613,6 +627,10 @@ procedure ParseEvent;
613627 LeEventType:Byte;
614628 NewButtonCounter:Integer;
615629 ButtonMessage:String;
630+ CounterByte:Byte;
631+ MicroEventIndex:Integer;
632+ MicroEvent:Byte;
633+ MicroBitPeripheral:PMicroBitPeripheral;
616634function GetByte :Byte;
617635begin
618636 Result:=Event[GetByteIndex];
@@ -675,8 +693,9 @@ function GetByte:Byte;
675693 MfrHi:=GetByte;
676694 SignatureLo:=GetByte;
677695 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
679697 begin
698+ MicroBitPeripheral:=FindOrMakeMicroBitPeripheral(AddressString);
680699 GetByteIndex:=20 ;
681700 NewButtonCounter:=(GetByte - Ord(' 0' ))*10 ;
682701 NewButtonCounter:=NewButtonCounter + (GetByte - Ord(' 0' ));
@@ -685,28 +704,77 @@ function GetByte:Byte;
685704 begin
686705 S:=S + Char(GetByte);
687706 end ;
688- if NewButtonCounter <> ButtonCounter then
707+ if NewButtonCounter <> MicroBitPeripheral^. ButtonCounter then
689708 begin
690- ButtonCounter:=NewButtonCounter;
691- if not ButtonChordStarted then
709+ MicroBitPeripheral^. ButtonCounter:=NewButtonCounter;
710+ if not MicroBitPeripheral^. ButtonChordStarted then
692711 begin
693712 LoggingOutput(' ' );
694- ButtonChordStarted:=True;
713+ MicroBitPeripheral^. ButtonChordStarted:=True;
695714 end ;
696715 case S[1 ] of
697716 ' 0' :
698717 begin
699718 ButtonMessage:=' Released ' ;
700- ButtonChordStarted:=False;
719+ MicroBitPeripheral^. ButtonChordStarted:=False;
701720 end ;
702721 ' 1' : ButtonMessage:=' A down ' ;
703722 ' 2' : ButtonMessage:=' B down ' ;
704723 ' 3' : ButtonMessage:=' A and B down' ;
705724 else ButtonMessage:=' ????????????' ;
706725 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]));
708727 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 ;
710778end ;
711779
712780begin
@@ -734,8 +802,7 @@ function GetByte:Byte;
734802 Log(' Init complete' );
735803 ScanCycleCounter:=0 ;
736804 ReadByteCounter:=0 ;
737- ButtonCounter:=0 ;
738- ButtonChordStarted:=False;
805+ SetLength(MicroBitPeripherals,0 );
739806 while True do
740807 begin
741808 ReadBackLog:=0 ;
0 commit comments