Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkubanek committed Oct 25, 2023
2 parents ab1b9e6 + 5f4f80d commit 8a3ece8
Show file tree
Hide file tree
Showing 26 changed files with 385 additions and 302 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: ChangelogUpdated
on:
pull_request:
types: [assigned, opened, synchronize, reopened, labeled, unlabeled]
branches:
- develop
jobs:
build:
name: Check Actions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Changelog check
uses: Zomzog/[email protected]
with:
fileName: doc/version-history.rst
checkNotification: Simple
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16 changes: 0 additions & 16 deletions .github/workflows/clang-format.yaml

This file was deleted.

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@
tests/test_*
!tests/test_*.cpp
!tests/test_*.c
.pre-commit-config.yaml
.clang-format
.flake8
.isort.cfg
.mypy.ini
.ruff.toml
9 changes: 9 additions & 0 deletions .ts_pre_commit_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
black: true
check-xml: true
check-yaml: true
clang-format: true
flake8: true
format-xmllint: true
isort: true
mypy: true
ruff: true
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM lsstts/develop-env:c0028.004
FROM lsstts/develop-env:develop

USER root
RUN chmod a+rwX -R /home/saluser/
Expand Down
6 changes: 4 additions & 2 deletions Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ else
endif

PKG_LIBS := $(shell pkg-config yaml-cpp --libs $(silence)) \
$(shell pkg-config spdlog --libs $(silence))
$(shell pkg-config spdlog --libs $(silence)) \
$(shell pkg-config fmt --libs $(silence))

LIBS += $(PKG_LIBS) -ldl -lpthread

BOOST_CPPFLAGS := -I/usr/include/boost169
PKG_CPP_FLAGS := $(shell pkg-config yaml-cpp --cflags $(silence)) \
$(shell pkg-config spdlog --cflags $(silence))
$(shell pkg-config spdlog --cflags $(silence)) \
$(shell pkg-config fmt --cflags $(silence))

CPP_FLAGS += $(PKG_CPP_FLAGS)

Expand Down
16 changes: 16 additions & 0 deletions include/cRIO/ElectromechanicalPneumaticILC.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class ElectromechanicalPneumaticILC : public virtual ILC {
*/
void reportHardpointForceStatus(uint8_t address) { callFunction(address, 67, 1800); }

/**
* Unicast command to read hardpoint LVDT. ILC command 122 (0x7a).
*
* @param address ILC address
*/
void reportHardpointLVDT(uint8_t address) { callFunction(address, 122, 400); }

void setSAAForceOffset(uint8_t address, bool slewFlag, float primary) {
callFunction(address, 75, 1800, static_cast<uint8_t>(slewFlag ? 0xFF : 0x00),
int24_t(primary * 1000));
Expand Down Expand Up @@ -99,6 +106,15 @@ class ElectromechanicalPneumaticILC : public virtual ILC {
virtual void processHardpointForceStatus(uint8_t address, uint8_t status, int32_t encoderPostion,
float loadCellForce) = 0;

/**
* Called when response from call to command 122 (0x7a) is read.
*
* @param address returned from this ILC
* @param breakawayLVDT breakway LVDT value
* @param displacementLVDT displacement LVDT value
*/
virtual void processHardpointLVDT(uint8_t address, float breakawayLVDT, float displacementLVDT) = 0;

virtual void processSAAForceStatus(uint8_t address, uint8_t status, float primaryLoadCellForce) = 0;
virtual void processDAAForceStatus(uint8_t address, uint8_t status, float primaryLoadCellForce,
float secondaryLoadCellForce) = 0;
Expand Down
10 changes: 6 additions & 4 deletions include/cRIO/FPGA.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@
#include <stddef.h>
#include <stdint.h>

#include "ILC.h"
#include "MPU.h"
#include "SimpleFPGA.h"
#include <cRIO/ILC.h>
#include <cRIO/SimpleFPGA.h>

using namespace std::chrono_literals;

namespace LSST {
namespace cRIO {

class MPU;

/**
* Interface class for cRIO FPGA. Subclasses can talk either to the real HW, or
* be a software simulator.
Expand Down Expand Up @@ -186,11 +187,12 @@ class FPGA : public SimpleFPGA {
*
* @param irqs IRQ mask. Each interrupt corresponds to a bit
* @param timeout timeout in milliseconds
* @param timedout true if call timedouted, false if finished in time
* @param triggered
*
* @note the method shall allocate context (for IRQ handling) as needed from the current thread id
*/
virtual void waitOnIrqs(uint32_t irqs, uint32_t timeout, uint32_t* triggered = NULL) = 0;
virtual void waitOnIrqs(uint32_t irqs, uint32_t timeout, bool& timedout, uint32_t* triggered = NULL) = 0;

/**
* Acknowledges IRQs. Clear IRQs on FPGA.
Expand Down
109 changes: 90 additions & 19 deletions include/cRIO/MPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#ifndef CRIO_MPU_H_
#define CRIO_MPU_H_

#include <chrono>
#include <list>
#include <map>
#include <mutex>
Expand All @@ -31,34 +32,37 @@

#include <spdlog/fmt/fmt.h>

#include <cRIO/FPGA.h>
#include <cRIO/ModbusBuffer.h>

namespace LSST {
namespace cRIO {

/**
* Modbus Processing Unit (MPU) commands. Please see
* https://github.com/lsst-ts/Modbus_Processing_Unit for command details.
* https://github.com/lsst-ts/ts_M1M3Thermal/blob/develop/doc/version-history.rst
*/
namespace MPUCommands {
const static uint8_t STOP = 0;
const static uint8_t WRITE_BYTE = 1;
const static uint8_t WAIT_MS = 2;
const static uint8_t READ = 3;
const static uint8_t LOOP = 4;
const static uint8_t CHECK_CRC = 5;
const static uint8_t OUTPUT = 6;
const static uint8_t WRITE = 20;
const static uint8_t TELEMETRY_BYTE = 30;
const static uint8_t TELEMETRY_16 = 31;
const static uint8_t TELEMETRY_32 = 32;
const static uint8_t TELEMETRY_64 = 33;
const static uint8_t EXIT = 255;
const static uint8_t WRITE = 1;
const static uint8_t READ_US = 2;
const static uint8_t READ_MS = 3;
const static uint8_t IRQ = 240;
const static uint8_t TELEMETRY = 254;
const static uint8_t CLEAR = 255;
} // namespace MPUCommands

typedef enum { WRITE, READ, IDLE } loop_state_t;

/**
* The Modbus Processing Unit class. Prepares buffer with commands to send to
* FPGA, read responses & telemetry values.
*
* Values can be queried in a loop. Code then calls registered callback
* function everytime new data become available. For code to work that way,
* interrupt (
*
* If FPGA is instructed to raise an interrupt during (most likely at the end
* of) buffer execution with the 240 opcode,
*/
class MPU : public ModbusBuffer {
public:
Expand All @@ -79,6 +83,8 @@ class MPU : public ModbusBuffer {
*/
uint8_t getBus() { return _bus; }

virtual uint32_t getIrq() { return 1 << (10 + getBus()); }

void setAddress(uint8_t address) { _mpu_address = address; }

bool containsRead() { return _contains_read; }
Expand All @@ -89,7 +95,7 @@ class MPU : public ModbusBuffer {

void readEndOfFrame() override {}

void readInputStatus(uint16_t address, uint16_t count = 1, uint8_t timeout = 100);
void readInputStatus(uint16_t address, uint16_t count = 1, uint16_t timeout = 100);

/**
* Reads holding register(s).
Expand All @@ -98,7 +104,7 @@ class MPU : public ModbusBuffer {
* @param count number of registers to read
* @param timeout timeout for register readout (in ms)
*/
void readHoldingRegisters(uint16_t address, uint16_t count, uint8_t timeout = 100);
void readHoldingRegisters(uint16_t address, uint16_t count, uint16_t timeout = 100);

/**
* Write single register.
Expand All @@ -107,7 +113,7 @@ class MPU : public ModbusBuffer {
* @param value register value
* @param timeout timeout (in ms)
*/
void presetHoldingRegister(uint16_t address, uint16_t value, uint8_t timeout = 100);
void presetHoldingRegister(uint16_t address, uint16_t value, uint16_t timeout = 100);

/**
* Sets modbus holding registers.
Expand All @@ -117,16 +123,75 @@ class MPU : public ModbusBuffer {
* @param count number of registers to write
* @param timeout timeout (in ms)
*/
void presetHoldingRegisters(uint16_t address, uint16_t *values, uint8_t count, uint8_t timeout = 100);
void presetHoldingRegisters(uint16_t address, uint16_t *values, uint8_t count, uint16_t timeout = 100);

/**
* Returns commands buffer.
*
* @return current command buffer
*/
std::vector<uint8_t> getCommandVector() { return _commands; }
std::vector<uint8_t> getCommandVector();

/***
* Called to set loop read timeout.
*
* @param callback function to call when new data are available
* @param timeout timeout. If data cannot be retrieved within timeout,
* callback function is called with timedout parameter set to true.
*/
void setLoopTimeOut(std::chrono::microseconds timeout) { _loop_timeout = timeout; }

/***
* Called to write commands to retrieve values needed in loopRead.
*/
virtual void loopWrite() = 0;

/***
* Called to process data read in the loop.
*
* @param timeout
*/
virtual void loopRead(bool timedout) = 0;

/**
* Runs command loop. This is a state machine, with state stored in
* _loopStatus variable.
*
* In WRITE state, it calls loopWrite to prepare commands for FPGA.
*
* In READ state, it waits for bus IRQ. If wait succeed (IRQ was triggered),
* it reads the output data into a buffer, process the acquired buffer, and
* calls callback (if set).
*
* @param FPGA fpga used to process MPU commands.
*/
void runLoop(FPGA &fpga);

loop_state_t getLoopState() { return _loop_state; }

/***
* Returns cached input state. Input state shall be cached - queried with
* readInputStatus method.
*
* @param address input state address
*
* @return cached input state
*
* @throws std::out_of_range if the address isn't cached
*/

bool getInputStatus(uint16_t address) { return _inputStatus.at(address); }

/***
* Returns register value. This access only cached values - register shall be first read
* using readHoldingRegisters method.
*
* @param address register address
*
* @return cached regiter value
*
* @throws std::runtime_error when register value isn't cached
*/
uint16_t getRegister(uint16_t address) {
std::lock_guard<std::mutex> lg(_registerMutex);
try {
Expand All @@ -137,6 +202,8 @@ class MPU : public ModbusBuffer {
}

private:
void _pushTimeout(uint16_t timeout);

std::vector<uint8_t> _commands;
uint8_t _bus;
uint8_t _mpu_address;
Expand All @@ -152,6 +219,10 @@ class MPU : public ModbusBuffer {

std::map<uint16_t, bool> _inputStatus;
std::map<uint16_t, uint16_t> _registers;

std::chrono::microseconds _loop_timeout;
std::chrono::time_point<std::chrono::steady_clock> _loop_next_read;
loop_state_t _loop_state;
};

} // namespace cRIO
Expand Down
Loading

0 comments on commit 8a3ece8

Please sign in to comment.