// Raspberry Pi LPC1114 I/O Processor Expansion Board SPI Agent Firmware // LEGOŽ Power Functions Remote Control services // Copyright (C)2014-2018, 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. using System; namespace SPIAgent { /// /// The LEGORC class implements LEGO(R) Power Functions Remote Control Services. /// public class LEGORC { /// /// The range of LEGO(R) Power Functions Remote Control channels is 1 to 4. /// public const int MIN_CHANNEL = 1; /// /// The range of LEGO(R) Power Functions Remote Control channels is 1 to 4. /// public const int MAX_CHANNEL = 4; /// /// The range of LEGO(R) Power Functions Remote Control speed values is 0 to 255. /// Some motor selections impose even smaller speed ranges. /// public const int MIN_SPEED = 0; /// /// The range of LEGO(R) Power Functions Remote Control speed values is 0 to 255. /// Some motor selections impose even smaller speed ranges. /// public const int MAX_SPEED = 255; /// /// LEGO(R) Power Functions Remote Control moter identifiers. /// public enum MOTOR { ALLSTOP, MOTORA, MOTORB, COMBODIRECT, COMBOPWM, SENTINEL } /// /// LEGO(R) Power Functions Remote Control moter direction identifiers. /// public enum DIRECTION { REVERSE, FORWARD, SENTINEL } private ITransport mytransport; private int mypin; private SPIAGENT_COMMAND_MSG_t cmd; private SPIAGENT_RESPONSE_MSG_t resp; /// /// LEGO(R) Power Functions Remote Control output object constructor. /// /// SPI Agent Firmware transport object. /// LPC1114 GPIO pin number. /// LPC1114_GPIO0 through LPC1114_GPIO7 are allowed. public LEGORC(ITransport spiagent, int pin) { // Validate parameters if (spiagent == null) { throw new NullReferenceException("SPI Agent Firmware transport handle is null"); } if (!Pins.IS_GPIO(pin)) { throw new ArgumentException("LEGO(R) RC pin number is invalid"); } cmd = new SPIAGENT_COMMAND_MSG_t(); resp = new SPIAGENT_RESPONSE_MSG_t(); // Build the command message cmd.command = (int)Commands.SPIAGENT_CMD_CONFIGURE_GPIO_OUTPUT; cmd.pin = pin; cmd.data = 0; // Dispatch the command spiagent.Command(cmd, ref resp); // Handle errors if (resp.error != 0) { throw new SPIAgent_Exception("SPI Agent Firmware returned error " + ((errno)resp.error).ToString()); } mytransport = spiagent; mypin = pin; } /// /// Issue a LEGO(R) Power Functions Remote Control command. /// /// Channel number. /// Motor identifier. /// Direction identifier. /// Speed. public void Command(int c, MOTOR m, DIRECTION d, int s) { // Validate parameters if ((c < MIN_CHANNEL) || (c > MAX_CHANNEL)) { throw new ArgumentException("LEGO(R) channel parameter is invalid"); } if (m >= MOTOR.SENTINEL) { throw new ArgumentException("LEGO(R) motor parameter is invalid"); } if (d >= DIRECTION.SENTINEL) { throw new ArgumentException("LEGO(R) direction parameter is invalid"); } if ((s < MIN_SPEED) || (s > MAX_SPEED)) { throw new ArgumentException("LEGO(R) speed parameter is invalid"); } // Build the command message cmd.command = (int)Commands.SPIAGENT_CMD_PUT_LEGORC; cmd.pin = mypin; cmd.data = s | ((int)d << 8) | ((int)m << 16) | (c << 24); // Dispatch the command mytransport.Command(cmd, ref resp); // Handle errors if (resp.error != 0) { throw new SPIAgent_Exception("SPI Agent Firmware returned error " + ((errno)resp.error).ToString()); } } } }