<div dir="ltr"><div><div><div><div><div><div><div>Hello,<br><br>I am building a USB gadget with a HexWax ExpandIO-USB chip, here: <a href="http://hexwax.com/Products/expandIO-USB/" target="_blank">http://hexwax.com/Products/expandIO-USB/</a><br>



<br></div>The device is working fine (lsusb shows it) and so I thought 
that in the name of continued training and doing things the hard way, 
that I would use Haskell to talk to it!<br>I have only ever done USB with &#39;C&#39; in the past and I am now stuck fighting the type checker.<br>
<br></div>Here is my full code so far, it works in so far as it finds 
the device, opens and closes a connection and prints out some stuff. I 
then wanted to send four NUL bytes which elicits the same as a response 
according to the documentation but I cannot get it to compile. Apologies
 for it in advance, it&#39;s the journey you know, not the arrival, anyway, 
here it is...<br>
</div><br><span style="font-family:courier new,monospace">module Main where<br><br>import Data.ByteString.Char8 as BS hiding (putStrLn)<br>import Data.Word (Word16)<br>import Data.Vector as V (filterM, null, (!)) --as V hiding ((++))                                         <br>



import System.USB<br>import System.Environment<br><br><br>-- hexwax expandIO-USB default code: &quot;0b40:0132&quot;                                                          <br>main :: IO ()<br>main = do<br>  findHexWax (0xb40,0x132) &gt;&gt;= \hw -&gt;<br>



    case hw of<br>      Just dev -&gt; hexwaxGo dev<br>      Nothing  -&gt; putStrLn &quot;HexWax device not found&quot;<br><br><br>findHexWax :: (Word16,Word16) -&gt; IO (Maybe Device)<br>findHexWax (cVendor, cProd) = do<br>



  usbCtx  &lt;- newCtx<br>  usbDevs &lt;- getDevices usbCtx<br>  setDebug usbCtx PrintWarnings<br>  boards &lt;- V.filterM (isTarget (cVendor, cProd)) usbDevs<br>  case V.null boards of<br>    True  -&gt; return Nothing<br>



    False -&gt; return $ Just $ boards!0<br>  where<br>    isTarget :: (Word16, Word16) -&gt; Device -&gt; IO Bool<br>    isTarget (cVendor, cProd) dev = do<br>      info &lt;- getDeviceDesc dev<br>      let vid = deviceVendorId info<br>



      let vpr = deviceProductId info<br>      return $ ((vid, vpr) == (cVendor, cProd))<br><br><br>hexwaxGo :: Device -&gt; IO ()<br>hexwaxGo dev = withDeviceHandle dev (testBoard dev)<br><br><br><br>testBoard :: Device -&gt; DeviceHandle -&gt; IO ()<br>



testBoard dev handle = do<br>  putStrLn $ &quot;Inspecting device: \&quot;&quot; ++ (show dev) ++ &quot;\&quot;\n&quot;<br>  -- write 0x00 0x00 0x00 0x00, get back same...                                                          <br>



  let payload  = pack &quot;\x00\x00\x00\x00&quot;<br>  let endPoint = EndpointAddress 0 Out<br>  action &lt;- writeInterrupt handle endPoint<br>  (size, status) &lt;- action payload 1000<br>  return ()</span><br><br></div>



And the error message:<br><br>Prelude&gt; :r<br>[1 of 1] Compiling Main             ( usb1.hs, interpreted )<br><br><font><span style="font-family:courier new,monospace">usb1.hs:60:13:<br>    Couldn&#39;t match expected type `IO t0&#39; with actual type `WriteAction&#39;<br>



    In the return type of a call of `writeInterrupt&#39;<br>    Probable cause: `writeInterrupt&#39; is applied to too few arguments<br>    In a stmt of a &#39;do&#39; block: action &lt;- writeInterrupt handle endPoint<br>



    In the expression:<br>      do { putStrLn $ &quot;Inspecting device: \&quot;&quot; ++ (show dev) ++ &quot;\&quot;&quot;;<br>           let payload = pack &quot;\NUL\NUL\NUL\NUL&quot;;<br>           let endPoint = EndpointAddress 0 Out;<br>



           action &lt;- writeInterrupt handle endPoint;<br>           .... }<br>Failed, modules loaded: none.<br></span></font><br><br><br></div>I
 have spent a few hours trying this and that, my Haskell is improving 
but not much good if I can&#39;t compile my program now is it!<br>
<br>So, can anybody point out the error of my ways here please as I just can&#39;t see it!<br><br></div>Thanks,<br>Sean Charles.<br><br></div>PS:
 Code style comments, alternative ways of making it more concise (but 
still readable and understandable mind you) are also welcome.</div>