-- Raspberry Pi LPC1114 I/O Processor SPI Agent Firmware Transport Services -- using HID Remote I/O using libhidapi -- Copyright (C)2019, Philip Munts, President, Munts AM Corp. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are met: -- -- * Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. WITH Interfaces; WITH errno; WITH HID.hidapi; WITH Message64; WITH RemoteIO.Client; USE TYPE RemoteIO.Client.Device; PACKAGE BODY spi_agent.transport IS dev : RemoteIO.Client.Device := NULL; -- Initialize the SPI Agent Firmware transport library PROCEDURE open(servername : String; error : OUT Integer) IS BEGIN IF dev /= NULL THEN error := errno.EBUSY; RETURN; END IF; -- TODO: Interpret the servername parameter as a USB device serial number dev := RemoteIO.Client.Create(HID.hidapi.Create); error := errno.EOK; EXCEPTION WHEN OTHERS => error := errno.EIO; END open; -- Deinitialize the SPI Agent Firmware transport library PROCEDURE close(error : OUT Integer) IS BEGIN IF dev = NULL THEN error := errno.EINVAL; RETURN; END IF; -- TODO: Destroy the existing Remote I/O device object dev := NULL; error := errno.EOK; END close; -- Dispatch an SPI Agent Firmware command to the transport library PROCEDURE command (command : IN spi_agent.messages.SPIAGENT_COMMAND_MSG_t; response : OUT spi_agent.messages.SPIAGENT_RESPONSE_MSG_t; error : OUT Integer) IS cmd : Message64.Message; resp : Message64.Message; BEGIN IF dev = NULL THEN error := errno.EINVAL; RETURN; END IF; cmd := (OTHERS => 0); cmd(0) := Message64.Byte(RemoteIO.MessageTypes'Pos( RemoteIO.DEVICE_OPERATION_REQUEST)); -- Convert from SPIAGENT_COMMAND_MSG_t to byte stream cmd(3) := Message64.Byte(command.Command/16777216); cmd(4) := Message64.Byte(command.Command/65536 MOD 256); cmd(5) := Message64.Byte(command.Command/256 MOD 256); cmd(6) := Message64.Byte(command.Command MOD 256); cmd(7) := Message64.Byte(command.Pin/16777216); cmd(8) := Message64.Byte(command.Pin/65536 MOD 256); cmd(9) := Message64.Byte(command.Pin/256 MOD 256); cmd(10) := Message64.Byte(command.Pin MOD 256); cmd(11) := Message64.Byte(command.Data/16777216); cmd(12) := Message64.Byte(command.Data/65536 MOD 256); cmd(13) := Message64.Byte(command.Data/256 MOD 256); cmd(14) := Message64.Byte(command.Data MOD 256); -- Execute the command dev.Transaction(cmd, resp); -- Convert from byte stream to SPIAGENT_RESPONSE_MSG_t response.Command := Interfaces.Unsigned_32(resp(3))*16777216 OR Interfaces.Unsigned_32(resp(4))*65536 OR Interfaces.Unsigned_32(resp(5))*256 OR Interfaces.Unsigned_32(resp(6)); response.Pin := Interfaces.Unsigned_32(resp(7))*16777216 OR Interfaces.Unsigned_32(resp(8))*65536 OR Interfaces.Unsigned_32(resp(9))*256 OR Interfaces.Unsigned_32(resp(10)); response.Data := Interfaces.Unsigned_32(resp(11))*16777216 OR Interfaces.Unsigned_32(resp(12))*65536 OR Interfaces.Unsigned_32(resp(13))*256 OR Interfaces.Unsigned_32(resp(14)); response.Error := Interfaces.Unsigned_32(resp(15))*16777216 OR Interfaces.Unsigned_32(resp(16))*65536 OR Interfaces.Unsigned_32(resp(17))*256 OR Interfaces.Unsigned_32(resp(18)); error := errno.EOK; EXCEPTION WHEN OTHERS => error := errno.EIO; END command; END spi_agent.transport;