hal package

Note

Dealing with HAL is an advanced topic, and the documentation isn’t as good as it could be. Be prepared to read the code directly!

Generally, RobotPy users don’t need to interact much with the HAL package except in simulation.

hal_data

When running the robot code in simulation or in unit tests, anytime something needs to interact with the hardware, typically functions in the HAL are called. The simulated version of the HAL functions either set or get data to/from a giant dictionary that we call the ‘hal_data’.

To learn about the contents of the data in the dictionary, go to hal-sim/hal_impl/data.py and read the reset_hal_data function.

I2C/SPI Simulation Helpers

Interacting with custom I2C and SPI devices requires custom code. Because we can’t predict what kind of data your device will return when you ask for it, the default simulation interfaces will discard all data written to the device, and raise an exception when you try to read from the device. If you don’t want to receive these errors, then you need to do the following:

  1. Create a simulation class that inherits from either I2CSimBase or SPISimBase, and override the needed functions.
  2. Create an instance of the class, and pass it as the simPort argument of the I2C or SPI object constructor

For a working example of how to do this, look at the constructor of the ADXRS450_Gyro, and its corresponding simulation interface ADXRS450_Gyro_Sim found at hal-sim/hal_impl/spi_helpers.py.

Note

The sim helper objects aren’t installed on the roborio, so you should only import them if a simulated hal is running. You can use the hal.isSimulation function to determine this.

class hal_impl.i2c_helpers.I2CSimBase[source]

Base class to use for i2c protocol simulators.

Has all functions that need to be implemented, but throws exceptions when data is asked of it. Will throw away set* function data, as most low-fidelity simulation will probably not care about such things.

closeI2C(port)[source]
initializeI2C(port, status)[source]
readI2C(port, deviceAddress, buffer, count)[source]

Reads data from the I2C device. To return data to your code, you need to write bytes to the buffer parameter. A simple example of returning 3 bytes might be:

def readI2C(self, port, deviceAddress, buffer, count):
    buffer[:] = b'123'
    return len(buffer)
Returns:number of bytes read
transactionI2C(port, deviceAddress, dataToSend, sendSize, dataReceived, receiveSize)[source]

Writes data to the I2C device and then reads from it. You can read bytes from the dataToSend parameter. To return data, you need to write bytes to the data_received parameter. object.

A simple example of returning 3 bytes might be:

def transactionI2C(self, port, deviceAddress, dataToSend, sendSize, dataReceived, receiveSize):
    dataReceived[:] = b'123'
    return len(dataReceived)
Returns:number of bytes returned
writeI2C(port, deviceAddress, dataToSend, sendSize)[source]
Returns:number of bytes written
class hal_impl.spi_helpers.SPISimBase[source]

Base class to use for SPI protocol simulators.

Has all functions that need to be implemented, but throws exceptions when data is asked of it. Will throw away set* function data, as most low-fidelity simulation will probably not care about such things.

closeSPI(port)[source]
forceSPIAutoRead(port, status)[source]
freeSPIAuto(port, status)[source]
getSPIAutoDroppedCount(port, status)[source]
Returns:int32
getSPIHandle(port)[source]
initSPIAuto(port, bufferSize, status)[source]
initializeSPI(port, status)[source]
readSPI(port, buffer, count)[source]

Reads data from the SPI device. To return data to your code, you need to write bytes to the buffer parameter. A simple example of returning 3 bytes might be:

def readSPI(self, port, buffer, count):
    buffer[:] = b'123'
    return len(buffer)
Returns:number of bytes read
readSPIAutoReceivedData(port, buffer, numToRead, timeout, status)[source]
Returns:number of bytes read
setSPIAutoTransmitData(port, dataToSend, dataSize, zeroSize, status)[source]
setSPIChipSelectActiveHigh(port, status)[source]
setSPIChipSelectActiveLow(port, status)[source]
setSPIHandle(port, handle)[source]
setSPIOpts(port, msbFirst, sampleOnTrailing, clkIdleHigh)[source]
setSPISpeed(port, speed)[source]
startSPIAutoRate(port, period, status)[source]
startSPIAutoTrigger(port, digitalSourceHandle, analogTriggerType, triggerRising, triggerFalling, status)[source]
stopSPIAuto(port, status)[source]
transactionSPI(port, dataToSend, dataReceived, size)[source]

Writes data to the I2C device and then reads from it. You can read bytes from the dataToSend parameter. To return data, you need to write bytes to the data_received parameter. object.

A simple example of returning 3 bytes might be:

def transactionSPI(self, port, dataToSend, dataReceived, size):
    dataReceived[:] = b'123'
    return len(dataReceived)
Returns:number of bytes returned
writeSPI(port, dataToSend, sendSize)[source]
Returns:number of bytes written