| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- unit USBasp_Threads;
- {
- This file is part of
- Nephelae USBasp HID UART.
- USB HID Read / Write threads.
- Copyright (C) 2022 - 2025 Dimitrios Chr. Ioannidis.
- Nephelae - https://www.nephelae.eu
- https://www.nephelae.eu/
- Licensed under the MIT License (MIT).
- See licence file in root directory.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
- ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
- SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- }
- {$mode ObjFPC}{$H+}
- interface
- uses
- Classes, SysUtils, syncobjs, hidapi,
- SPSCRingBuffer;
- type
- { TThreadHID_Base }
- TThreadHID_Base = class(TThread)
- protected
- FThreadEvent: TEvent;
- FThreadUnpluggedEvent: TEvent;
- FBuffer: TSPSCRingBuffer;
- FHIDDevice: PHidDevice;
- public
- constructor Create(const AHIDDevice: PHidDevice;
- const ABuffer: TSPSCRingBuffer; const AThreadEvent: TEvent;
- const AUnpluggedEvent: TEvent); reintroduce;
- end;
- { TThread_HID_Status_Rx }
- TThread_HID_Status_Rx = class(TThreadHID_Base)
- protected
- procedure Execute; override;
- end;
- { TThread_HID_Status_Tx }
- TThread_HID_Status_Tx = class(TThreadHID_Base)
- protected
- procedure Execute; override;
- end;
- { TThread_HID_UART_Rx }
- TThread_HID_UART_Rx = class(TThreadHID_Base)
- procedure Execute; override;
- end;
- { TThread_HID_UART_Tx }
- TThread_HID_UART_Tx = class(TThreadHID_Base)
- protected
- procedure Execute; override;
- end;
- implementation
- { TThreadHID_Base }
- constructor TThreadHID_Base.Create(const AHIDDevice: PHidDevice;
- const ABuffer: TSPSCRingBuffer; const AThreadEvent: TEvent;
- const AUnpluggedEvent: TEvent);
- begin
- inherited Create(False);
- FThreadEvent := AThreadEvent;
- FThreadUnpluggedEvent := AUnpluggedEvent;
- FBuffer := ABuffer;
- FHIDDevice := AHIDDevice;
- end;
- { TThread_HID_Status_Rx }
- procedure TThread_HID_Status_Rx.Execute;
- var
- USBAspHidPacket: array[0..7] of byte = (0, 0, 0, 0, 0, 0, 0, 0);
- DataCount: SizeInt = 0;
- begin
- repeat
- DataCount := FHIDDevice^.Read(USBAspHidPacket, 8);
- if DataCount > 0 then
- begin
- FBuffer.Write(USBAspHidPacket, DataCount);
- FThreadEvent.SetEvent;
- end;
- until Terminated;
- end;
- { TThread_HID_Status_Tx }
- procedure TThread_HID_Status_Tx.Execute;
- var
- USBAspHidPacket: array[0..8] of byte = (0, 0, 0, 0, 0, 0, 0, 0, 0);
- DataCount: byte = 0;
- begin
- repeat
- if FBuffer.Empty then
- FThreadEvent.ResetEvent;
- FThreadEvent.WaitFor(INFINITE);
- FillChar(USBAspHidPacket, 8, 0);
- DataCount := FBuffer.Peek(USBAspHidPacket[1], 8);
- if DataCount > 0 then
- begin
- FHIDDevice^.Write(USBAspHidPacket, 8 + 1);
- FBuffer.AdvanceReadIdx(DataCount);
- end;
- until Terminated;
- end;
- { TThread_HID_UART_Rx }
- procedure TThread_HID_UART_Rx.Execute;
- var
- USBAspHidPacket: array[0..7] of byte = (0, 0, 0, 0, 0, 0, 0, 0);
- SerialDataCount, DataCount: byte;
- begin
- repeat
- DataCount := FHIDDevice^.Read(USBAspHidPacket, 8);
- if (DataCount > 0) and (USBAspHidPacket[7] > 0) then
- begin
- if (USBAspHidPacket[7] > 7) then
- SerialDataCount := 8
- else
- SerialDataCount := USBAspHidPacket[7];
- if FBuffer.Write(USBAspHidPacket, SerialDataCount) <> SerialDataCount then
- raise TExceptionClass.Create('Buffer OverRun');
- FThreadEvent.SetEvent;
- end;
- until Terminated;
- end;
- { TThread_HID_UART_Tx }
- procedure TThread_HID_UART_Tx.Execute;
- var
- USBAspHidPacket: array[0..8] of byte = (0, 0, 0, 0, 0, 0, 0, 0, 0);
- SerialCountOrDataByte, DataCount: byte;
- begin
- repeat
- if FBuffer.Empty then
- FThreadEvent.ResetEvent;
- FThreadEvent.WaitFor(INFINITE);
- DataCount := FBuffer.Peek(USBAspHidPacket[1], 8);
- SerialCountOrDataByte := DataCount;
- if (SerialCountOrDataByte = 8) and (USBAspHidPacket[8] = 7) then
- SerialCountOrDataByte := 7
- else
- if SerialCountOrDataByte < 8 then
- USBAspHidPacket[8] := SerialCountOrDataByte;
- if DataCount > 0 then
- begin
- SerialCountOrDataByte :=
- FHIDDevice^.Write(USBAspHidPacket, 8 + 1);
- FBuffer.AdvanceReadIdx(DataCount);
- end;
- until Terminated;
- end;
- end.
|