123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150(* File: mindstorm__EV3.ml
Copyright (C) 2015-
Christophe Troestler <Christophe.Troestler@umons.ac.be>
WWW: http://math.umons.ac.be/an/software/
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3 or
later as published by the Free Software Foundation, with the special
exception on linking described in the file LICENSE.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
LICENSE for more details. *)(* References: LEGO MINDSTORMS EV3 "Communication Developer Kit" and
"Firmware Developer Kit". *)#ifndefMODULE_ERR#defineMODULE_ERR(err)STRINGIFY(Mindstorm.EV3:err)#defineMODULE(fn)STRINGIFY(Mindstorm.EV3.fn)#endif#ifdefLWTmoduleConn=Mindstorm_lwt_connect#elsemoduleConn=Mindstorm_connect#endif#include"mindstorm_macros.ml"#include"mindstorm_common.ml"(** Handling errors
***********************************************************************)typeerror=|Unknown_handle|Handle_not_ready|Corrupt_file|No_handles_available|No_permission|Illegal_path|File_exists|End_of_file|Size_error|Unknown_error|Illegal_filename|Illegal_connectionexceptionErroroferrorleterror=lete=Array.make256(FailureMODULE_ERR(undocumentederror))ine.(0x00)<-Failure"Should not happen, contact the Mindstorm developer!";e.(0x01)<-ErrorUnknown_handle;e.(0x02)<-ErrorHandle_not_ready;e.(0x03)<-ErrorCorrupt_file;e.(0x04)<-ErrorNo_handles_available;e.(0x05)<-ErrorNo_permission;e.(0x06)<-ErrorIllegal_path;e.(0x07)<-ErrorFile_exists;e.(0x08)<-ErrorEnd_of_file;e.(0x09)<-ErrorSize_error;e.(0x0A)<-ErrorUnknown_error;e.(0x0B)<-ErrorIllegal_filename;e.(0x0C)<-ErrorIllegal_connection;eletcheck_status_as_exnstatus=ifstatus<>'\x00'thenraise(error.(Char.codestatus))typebluetooth=Conn.bluetoothtypeusb=Conn.usbtype'aconn={c:'aConn.t;mutablemsg_counter:int;}letcloseconn=Conn.closeconn.cletcheck_status_EV3pkg=check_status_as_exn(Bytes.getpkg4)letconnect_bluetoothaddr=letc=Conn.connect_bluetooth~check_status:false~check_status_fn:check_status_EV3addrin{c=c;msg_counter=0}(** Sending commands
***********************************************************************)moduleCmd=struct(* let system_reply = '\x01' *)(* let system_no_reply = '\x81' *)(* let direct_reply = '\x00' *)letdirect_no_reply='\x80'(* [msg] is supposed to have space for the first 6 "control" bytes.*)letsendconncmd_typemsg=letlen=Bytes.lengthmsg-2inassert(len>0);copy_uint16lenmsg0;conn.msg_counter<-conn.msg_counter+1;copy_uint16conn.msg_countermsg2;Bytes.setmsg4cmd_type;Bytes.setmsg5'\x00';Bytes.setmsg6'\x00';Conn.sendconn.cmsgend(* let primpar_short = 0x00 *)(* let primpar_long = 0x80*)(* let primpar_const = 0x00 *)letprimpar_value=0x3F(*let primpar_1_byte = 1 *)(* let primpar_2_bytes = 2 *)(* let primpar_4_bytes = 3 *)(* let primpar_string = 4 (\* zero terminated string *\) *)(* (v land primpar_value) lor primpar_short lorprimpar_const*)let_set_lc0sofsv=Bytes.setsofs(Char.unsafe_chr(vlandprimpar_value))(* 2bytes, v ∈ {-127,...,127} *)letset_data8sofsv=Bytes.setsofs'\x81';(* PRIMPAR_LONG | PRIMPAR_CONST | PRIMPAR_1_BYTE *)Bytes.sets(ofs+1)(Char.unsafe_chr(vland0xFF))(*3 bytes, v ∈ {-32767,...,32767} *)letset_data16sofsv=Bytes.setsofs'\x82';(* PRIMPAR_LONG | PRIMPAR_CONST| PRIMPAR_2_BYTES *)copy_uint16vs(ofs+1)moduleSound=structlettoneconn~vol~freq~ms=letm=Bytes.create17inBytes.setm7'\x94';Bytes.setm8'\x01';set_data8m9vol;set_data16m11freq;set_data16m14ms;Cmd.sendconnCmd.direct_no_replymend;;