seemingly finished the rewrite from libsharperang to libpaperang, added buttons to choose model type in UI tester

This commit is contained in:
Maff 2019-09-28 23:51:46 +01:00
parent b1f08472da
commit 0a2df42a5a
9 changed files with 100 additions and 33 deletions

View File

@ -4,13 +4,20 @@ using System.Linq;
namespace libpaperang.Helpers { namespace libpaperang.Helpers {
public class CRC { public class CRC {
public uint iv { get => ~iv; private set => iv=~value; } private uint _iv;
public uint iv { get => ~_iv; private set => _iv=~value; }
public uint mv = 0x35769521; public uint mv = 0x35769521;
private uint poly = 0xedb88320; private uint poly = 0xedb88320;
private uint[] crctable; private uint[] crctable;
public bool IsInitialised=false; public bool IsInitialised=false;
public CRC() => iv = 0; public CRC(bool autoinit = true) {
public CRC(uint iv) => this.iv = iv; iv = 0;
if(autoinit) Initialise();
}
public CRC(uint iv, bool autoinit = true) {
this.iv = iv;
if (autoinit) Initialise();
}
public void Initialise() { public void Initialise() {
crctable=Enumerable.Range(0, 256).Select(i => { crctable=Enumerable.Range(0, 256).Select(i => {
uint e=(uint)i; uint e=(uint)i;
@ -33,7 +40,7 @@ namespace libpaperang.Helpers {
public uint GetChecksumUint<T>(IEnumerable<T> data) { public uint GetChecksumUint<T>(IEnumerable<T> data) {
if (!IsInitialised) throw new CrcNotAvailableException(); if (!IsInitialised) throw new CrcNotAvailableException();
try { try {
return ~data.Aggregate(iv, return ~data.Aggregate(_iv,
(cti, cb) => crctable[(cti&0xFF)^Convert.ToByte(cb)]^(cti>>8)); (cti, cb) => crctable[(cti&0xFF)^Convert.ToByte(cb)]^(cti>>8));
} catch (FormatException e) { } catch (FormatException e) {
throw new FormatException("Could not read input as a byte stream", e); throw new FormatException("Could not read input as a byte stream", e);

View File

@ -2,7 +2,7 @@
using System.Linq; using System.Linq;
namespace libpaperang.Helpers { namespace libpaperang.Helpers {
class Transforms { public class Transforms {
public BaseTypes.Packet Frame; public BaseTypes.Packet Frame;
public BaseTypes.Opcodes Op; public BaseTypes.Opcodes Op;
public short OpLen; public short OpLen;
@ -30,20 +30,20 @@ namespace libpaperang.Helpers {
return BitConverter.GetBytes(SwapWordEndianness( return BitConverter.GetBytes(SwapWordEndianness(
0x00010000 | ((((( 0x00010000 | (((((
Data & 0xffu) << 16) | Data & 0xffu) << 16) |
Data) & 0xffff00u) >> 8))).Skip(2).ToArray(); Data) & 0xffff00u) >> 8)));
default: throw new InvalidOperationException(); default: throw new InvalidOperationException();
} }
} }
public byte[] Packet(byte[] oper, byte[] data, CRC checksum) { public byte[] Packet(byte[] oper, byte[] data, CRC checksum) {
byte[] packet = new byte[data.Length+6+OpLen]; byte[] packet = new byte[1+oper.Length+data.Length+5];
packet[0] = Frame.Start; packet[0] = Frame.Start;
packet[packet.Length-1] = Frame.End; packet[packet.Length-1] = Frame.End;
Buffer.BlockCopy(oper, Buffer.BlockCopy(oper,
0, packet, 1, OpLen); 0, packet, 1, oper.Length);
Buffer.BlockCopy(data, Buffer.BlockCopy(data,
0, packet, OpLen+1, packet.Length); 0, packet, oper.Length+1, data.Length);
Buffer.BlockCopy(checksum.GetChecksumBytes(data), Buffer.BlockCopy(checksum.GetChecksumBytes(data),
0, packet, packet.Length - (OpLen+1), 4); 0, packet, packet.Length - 5, 4);
return packet; return packet;
} }
public byte[] Packet(BaseTypes.Operations oper, byte[] data, CRC checksum) => public byte[] Packet(BaseTypes.Operations oper, byte[] data, CRC checksum) =>
@ -54,7 +54,7 @@ namespace libpaperang.Helpers {
return p; return p;
} }
public uint SwapWordEndianness(uint value) => ( public uint SwapWordEndianness(uint value) => (
(value & 0x000000ffu) << 2) | (value & 0x000000ffu) << 24)|
((value & 0x0000ff00u) << 8) | ((value & 0x0000ff00u) << 8) |
((value & 0x00ff0000u) >> 8) | ((value & 0x00ff0000u) >> 8) |
((value & 0xff000000u) >> 24); ((value & 0xff000000u) >> 24);

View File

@ -50,7 +50,7 @@ namespace libpaperang {
public dynamic Instance; public dynamic Instance;
} }
} }
interface IPrinter { public interface IPrinter {
short LineWidth { get; } short LineWidth { get; }
BaseTypes.Connection ConnectionMethod { get; } BaseTypes.Connection ConnectionMethod { get; }
BaseTypes.Model PrinterVariant { get; } BaseTypes.Model PrinterVariant { get; }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using LibUsbDotNet; using LibUsbDotNet;
using LibUsbDotNet.Main; using LibUsbDotNet.Main;
@ -85,7 +86,11 @@ namespace libpaperang.Interfaces {
return readbuf; return readbuf;
} }
public bool WriteBytes(byte[] packet) => Printer.tx.Write(packet, 500, out int _) == ErrorCode.None; public bool WriteBytes(byte[] packet) => Printer.tx.Write(packet, 500, out int _) == ErrorCode.None;
public bool WriteBytes(byte[] packet, int delay) => throw new NotImplementedException(); public bool WriteBytes(byte[] packet, int delay) {
bool _=WriteBytes(packet);
Thread.Sleep(delay);
return _;
}
public USB(BaseTypes.Model model) => iModel=model; public USB(BaseTypes.Model model) => iModel=model;
} }
} }

View File

@ -1,9 +1,11 @@
using libpaperang; using libpaperang;
using libpaperang.Helpers; using libpaperang.Helpers;
using libpaperang.Interfaces; using libpaperang.Interfaces;
using System.Linq;
using System.Collections.Generic;
namespace libpaperang.Main { namespace libpaperang.Main {
class Paperang { public class Paperang {
public IPrinter Printer; public IPrinter Printer;
public Transforms Transform; public Transforms Transform;
public CRC Crc; public CRC Crc;
@ -28,6 +30,39 @@ namespace libpaperang.Main {
throw new PrinterConnectionNotSupportedException(); throw new PrinterConnectionNotSupportedException();
} }
} }
public void Initialise() {
Printer.OpenPrinter(Printer.AvailablePrinters.First());
Printer.Initialise();
Handshake();
}
public void Handshake() {
_ = Printer.WriteBytes(
Transform.Packet(
BaseTypes.Operations.CrcTransmit,
Crc.GetCrcIvBytes(),
new CRC(MagicValue)));
NoOp();
Feed(0);
NoOp();
}
public void Feed(uint ms) => Printer.WriteBytes(
Transform.Packet(BaseTypes.Operations.LineFeed,
Transform.Arg(BaseTypes.Operations.LineFeed, ms),
Crc));
public void NoOp() => Printer.WriteBytes(
Transform.Packet(BaseTypes.Operations.NoOp, new byte[] { 0, 0 }, Crc));
public void PrintBytes(byte[] data, bool autofeed = true) {
List<byte[]> segments = data
.Select((b,i) => new {Index=i,Value=b })
.GroupBy(b=>b.Index/1008)
.Select(b=>b.Select(bb=>bb.Value).ToArray())
.ToList();
segments.ForEach(b => Printer.WriteBytes(
Transform.Packet(
Transform.Arg(BaseTypes.Operations.Print, (uint)b.Length),
b,
Crc),
200-(b.Length/Printer.LineWidth)));
}
} }
} }

View File

@ -4,10 +4,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 16.0.29215.179 VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharperang", "sharperang\sharperang.csproj", "{677A8867-809E-4476-A9AE-7BEB5CE02F96}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharperang", "sharperang\sharperang.csproj", "{677A8867-809E-4476-A9AE-7BEB5CE02F96}"
ProjectSection(ProjectDependencies) = postProject
{A429CCEB-9331-4CD9-B3C0-A8F736732DEA} = {A429CCEB-9331-4CD9-B3C0-A8F736732DEA}
EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libsharperang", "libsharperang\libsharperang.csproj", "{93203F87-29D0-4CDE-B2EE-156488E30186}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libsharperang", "libsharperang\libsharperang.csproj", "{93203F87-29D0-4CDE-B2EE-156488E30186}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libpaperang", "libpaperang\libpaperang.csproj", "{A429CCEB-9331-4CD9-B3C0-A8F736732DEA}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libpaperang", "libpaperang\libpaperang.csproj", "{A429CCEB-9331-4CD9-B3C0-A8F736732DEA}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -16,9 +16,10 @@
<Grid Margin="10,10,10,10"> <Grid Margin="10,10,10,10">
<Button x:Name="btClearLog" Content="Clear Log" HorizontalAlignment="Left" MinWidth="75" Margin="0,2,0,152.2" Click="BtClearLog_Click"/> <Button x:Name="btClearLog" Content="Clear Log" HorizontalAlignment="Left" MinWidth="75" Margin="0,2,0,152.2" Click="BtClearLog_Click"/>
<Button x:Name="btInitUSB" Content="Initialise USB" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,23,0,0" IsDefault="True" Height="21" Click="BtInitUSB_Click"/> <Button x:Name="btInitUSB" Content="Initialise USB" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,23,0,0" IsDefault="True" Height="21" Click="BtInitUSB_Click"/>
<Button x:Name="btTyP1" Content="Model P1" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="100,2,0,0" Height="21" Click="BtSetP1_Click"/>
<Button x:Name="btTyP2" Content="Model P2" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="100,23,0,0" Height="21" Click="BtSetP2_Click"/>
<Button x:Name="btTestLine" Content="Single-line test" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,44,0,0" Height="21" Click="BtTestLine_Click"/> <Button x:Name="btTestLine" Content="Single-line test" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,44,0,0" Height="21" Click="BtTestLine_Click"/>
<Button x:Name="btLoadImage" Content="Load test image" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,65,0,0" Height="21" Click="BtLoadImage_Click"/> <Button x:Name="btLoadImage" Content="Load test image" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="75" Margin="0,65,0,0" Height="21" Click="BtLoadImage_Click"/>
<Image x:Name="imPreview" HorizontalAlignment="Left" Height="154" Margin="363,10,0,0" VerticalAlignment="Top" Width="369"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
<TextBox x:Name="tbLog" HorizontalAlignment="Left" Margin="10,232,0,10" TextWrapping="Wrap" Width="774" Grid.ColumnSpan="3" AllowDrop="False" IsReadOnly="True" IsUndoEnabled="False" VerticalScrollBarVisibility="Visible" ScrollViewer.CanContentScroll="True" Text="{Binding Path=LogBuffer}"/> <TextBox x:Name="tbLog" HorizontalAlignment="Left" Margin="10,232,0,10" TextWrapping="Wrap" Width="774" Grid.ColumnSpan="3" AllowDrop="False" IsReadOnly="True" IsUndoEnabled="False" VerticalScrollBarVisibility="Visible" ScrollViewer.CanContentScroll="True" Text="{Binding Path=LogBuffer}"/>

View File

@ -1,4 +1,7 @@
using libsharperang; //using libsharperang;
using libpaperang;
using libpaperang.Interfaces;
using libpaperang.Main;
using System; using System;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
@ -10,7 +13,10 @@ using System.IO;
namespace sharperang { namespace sharperang {
public partial class MainWindow : Window { public partial class MainWindow : Window {
private LogBridge logger; private LogBridge logger;
private USBPrinter printer=new USBPrinter(48); private BaseTypes.Connection mmjcx=BaseTypes.Connection.USB;
private BaseTypes.Model mmjmd=BaseTypes.Model.T1;
private Paperang mmj;
//private USBPrinter printer=new USBPrinter(48);
private Bitmap bimg; private Bitmap bimg;
public MainWindow() { public MainWindow() {
@ -21,10 +27,19 @@ namespace sharperang {
} }
private void BtClearLog_Click(object sender, RoutedEventArgs e) => private void BtClearLog_Click(object sender, RoutedEventArgs e) =>
logger.ClearBuffer(); logger.ClearBuffer();
private void BtSetP1_Click(object sender, RoutedEventArgs e) => mmjmd = BaseTypes.Model.P1;
private void BtSetP2_Click(object sender, RoutedEventArgs e) => mmjmd = BaseTypes.Model.P2;
private void BtInitUSB_Click(object sender, RoutedEventArgs e) { private void BtInitUSB_Click(object sender, RoutedEventArgs e) {
mmj = new Paperang(mmjcx, mmjmd);
logger.Verbose("# printers found: " + mmj.Printer.AvailablePrinters.Count);
if(!mmj.Printer.PrinterAvailable) {
logger.Err("Couldn't initialise printer as none is connected");
return;
}
logger.Info("USB Initialising"); logger.Info("USB Initialising");
printer.Initialise(); mmj.Initialise();
//printer = new LibSharperang(logger); //printer = new LibSharperang(logger);
/*
logger.Debug("IsPrinterPresent => "+printer.IsPrinterPresent()); logger.Debug("IsPrinterPresent => "+printer.IsPrinterPresent());
logger.Debug("FoundPrinterGuids => "+printer.FoundPrinterGuids()); logger.Debug("FoundPrinterGuids => "+printer.FoundPrinterGuids());
printer?.IDs?.ForEach(p => logger.Debug("FoundPrinterGuidAddrs "+p.ToString()+" => "+printer?.FoundPrinterGuidAddrs(p))); printer?.IDs?.ForEach(p => logger.Debug("FoundPrinterGuidAddrs "+p.ToString()+" => "+printer?.FoundPrinterGuidAddrs(p)));
@ -32,9 +47,11 @@ namespace sharperang {
logger.Debug("Claim => " + printer?.Claim()); logger.Debug("Claim => " + printer?.Claim());
logger.Debug("Init => "+BitConverter.ToString(printer.builder.BuildTransmitCrc()).Replace('-', ' ')); logger.Debug("Init => "+BitConverter.ToString(printer.builder.BuildTransmitCrc()).Replace('-', ' '));
printer.InitPrinter(); printer.InitPrinter();
*/
logger.Debug("PrinterInitialised? " + mmj.Printer.PrinterInitialised);
logger.Debug("Printer initialised and ready"); logger.Debug("Printer initialised and ready");
} }
private void BtTestLine_Click(object sender, RoutedEventArgs e) => printer.Feed(200); private void BtTestLine_Click(object sender, RoutedEventArgs e) => mmj.Feed(200);
private void BtLoadImage_Click(object sender, RoutedEventArgs e) { private void BtLoadImage_Click(object sender, RoutedEventArgs e) {
logger.Debug("Loading image for print"); logger.Debug("Loading image for print");
OpenFileDialog r = new OpenFileDialog { OpenFileDialog r = new OpenFileDialog {
@ -52,34 +69,34 @@ namespace sharperang {
r.Dispose(); r.Dispose();
logger.Debug("Disposed of dialog"); logger.Debug("Disposed of dialog");
bimg=new Bitmap(_, bimg=new Bitmap(_,
(printer.ImageWidth*8), (int)((double)(printer.ImageWidth*8)*(double)((double)_.Height/(double)_.Width))); (mmj.Printer.LineWidth*8), (int)((double)(mmj.Printer.LineWidth*8)*(double)((double)_.Height/(double)_.Width)));
logger.Debug("Loaded image as Bitmap"); logger.Debug("Loaded image as Bitmap");
_.Dispose(); _.Dispose();
logger.Debug("Disposed of Image"); logger.Debug("Disposed of Image");
bimg=CopyToBpp(bimg); bimg=CopyToBpp(bimg);
logger.Debug("Converted Bitmap to Bitmap with 1-bit colour depth"); logger.Debug("Converted Bitmap to Bitmap with 1-bit colour depth");
//BitArray img = new BitArray(bimg.Height*96*8); //BitArray img = new BitArray(bimg.Height*96*8);
byte[] iimg = new byte[bimg.Height*printer.ImageWidth]; byte[] iimg = new byte[bimg.Height*mmj.Printer.LineWidth];
byte[] img; byte[] img;
using (MemoryStream s = new MemoryStream()) { using (MemoryStream s = new MemoryStream()) {
bimg.Save(s, ImageFormat.Bmp); bimg.Save(s, ImageFormat.Bmp);
img=s.ToArray(); img=s.ToArray();
} }
logger.Debug("Got bitmap's bytes"); logger.Debug("Got bitmap's bytes");
int startoffset=img.Length-(bimg.Height*printer.ImageWidth); int startoffset=img.Length-(bimg.Height*mmj.Printer.LineWidth);
logger.Debug("Processing bytes with offset " + startoffset); logger.Debug("Processing bytes with offset " + startoffset);
for(int h=0;h<bimg.Height;h++) { for(int h=0;h<bimg.Height;h++) {
for (int w=0;w<printer.ImageWidth;w++) { for (int w=0;w< mmj.Printer.LineWidth; w++) {
iimg[(printer.ImageWidth*(bimg.Height-1-h))+(printer.ImageWidth-1-w)]=(byte)~ iimg[(mmj.Printer.LineWidth * (bimg.Height-1-h))+(mmj.Printer.LineWidth - 1-w)]=(byte)~
(img[startoffset+(printer.ImageWidth*h)+(printer.ImageWidth-1-w)]); (img[startoffset+(mmj.Printer.LineWidth * h)+(mmj.Printer.LineWidth - 1-w)]);
} }
} }
logger.Debug("Have print data of length " + iimg.Length); logger.Debug("Have print data of length " + iimg.Length);
bimg.Dispose(); bimg.Dispose();
logger.Debug("Disposed of Bitmap"); logger.Debug("Disposed of Bitmap");
printer.PrintBytes(iimg, false); mmj.PrintBytes(iimg, false);
logger.Debug("Feeding for 200ms"); logger.Debug("Feeding for 200ms");
printer.Feed(200); mmj.Feed(200);
} }
static uint BitSwap1(uint x) => ((x & 0x55555555u) << 1) | ((x & (~0x55555555u)) >> 1); static uint BitSwap1(uint x) => ((x & 0x55555555u) << 1) | ((x & (~0x55555555u)) >> 1);
static uint BitSwap2(uint x) => ((x & 0x33333333u) << 2) | ((x & (~0x33333333u)) >> 2); static uint BitSwap2(uint x) => ((x & 0x33333333u) << 2) | ((x & (~0x33333333u)) >> 2);

View File

@ -189,10 +189,9 @@
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\libsharperang\libsharperang.csproj"> <ProjectReference Include="..\libpaperang\libpaperang.csproj">
<Project>{93203f87-29d0-4cde-b2ee-156488e30186}</Project> <Project>{a429cceb-9331-4cd9-b3c0-a8f736732dea}</Project>
<Name>libsharperang</Name> <Name>libpaperang</Name>
<EmbedInteropTypes>False</EmbedInteropTypes>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>