33 #if defined(PIOS_INCLUDE_FLYINGPIO)
42 #include "actuatorcommand.h"
49 enum pios_flyingpio_dev_magic {
50 PIOS_FLYINGPIO_DEV_MAGIC = 0x4f497046
57 static int32_t PIOS_FLYINGPIO_ADC_PinGet(uintptr_t dev_int, uint32_t pin);
58 static uint8_t PIOS_FLYINGPIO_ADC_NumberOfChannels(uintptr_t dev_int);
59 static float PIOS_FLYINGPIO_ADC_LSB_Voltage(uintptr_t dev_int);
62 .
get_pin = PIOS_FLYINGPIO_ADC_PinGet,
63 .number_of_channels = PIOS_FLYINGPIO_ADC_NumberOfChannels,
64 .lsb_voltage = PIOS_FLYINGPIO_ADC_LSB_Voltage,
67 #define MIN_QUIET_TIME 300
72 struct pios_flyingpio_dev {
73 enum pios_flyingpio_dev_magic
magic;
77 uint32_t last_msg_time;
92 #define MAX_CONSEC_ERRS 5
95 static struct pios_flyingpio_dev *fpio_dev;
104 static struct pios_flyingpio_dev *PIOS_FLYINGPIO_Alloc();
110 static int32_t PIOS_FLYINGPIO_Validate(
struct pios_flyingpio_dev *dev);
112 static void PIOS_FLYINGPIO_ActuatorUpdate();
113 static int PIOS_FLYINGPIO_ActuatorSetMode(
const uint16_t *out_rate,
114 const int banks,
const uint16_t *channel_max,
115 const uint16_t *channel_min);
116 static void PIOS_FLYINGPIO_ActuatorSet(uint8_t
servo,
float position);
119 .
update = PIOS_FLYINGPIO_ActuatorUpdate,
120 .set_mode = PIOS_FLYINGPIO_ActuatorSetMode,
121 .set = PIOS_FLYINGPIO_ActuatorSet
124 static struct pios_flyingpio_dev *PIOS_FLYINGPIO_Alloc()
126 struct pios_flyingpio_dev *dev;
128 dev = (
struct pios_flyingpio_dev *)
PIOS_malloc(
sizeof(*fpio_dev));
132 dev->magic = PIOS_FLYINGPIO_DEV_MAGIC;
139 static int32_t PIOS_FLYINGPIO_Validate(
struct pios_flyingpio_dev *dev)
143 if (dev->magic != PIOS_FLYINGPIO_DEV_MAGIC)
145 if (dev->spi_id == 0)
151 uint32_t slave_idx, uint8_t protocol)
153 fpio_dev = PIOS_FLYINGPIO_Alloc();
154 if (fpio_dev == NULL)
158 fpio_dev->spi_id = spi_id;
159 fpio_dev->spi_slave = slave_idx;
161 fpio_dev->protocol = protocol;
171 static int PIOS_FLYINGPIO_SendCmd(
struct flyingpi_msg *msg) {
178 if (span < MIN_QUIET_TIME) {
200 (uint8_t *)&resp, len)) {
213 printf(
"fpio: VERYBAD: Bad CRC on response data %d\n\t",
216 uint8_t *msg_data = (
void *) &resp;
218 for (
int i = 0;
i < 16;
i++) {
227 printf(
"fpio: VERYBAD: Unexpected response message type\n");
246 if (!(fpio_dev->msg_num & 1023)) {
258 fpio_dev->err_cnt = 0;
269 static void PIOS_FLYINGPIO_ActuatorUpdate()
274 static int upd_num = 0;
293 float fraction = channel_values[
i] -
297 fraction *= 65535.0f;
300 if (fraction > 65535) {
302 }
else if (fraction < 0) {
309 if (!(upd_num & 1023)) {
310 printf(
"fpio: actuator: %d %f\n",
i, fraction);
318 if (PIOS_FLYINGPIO_SendCmd(&tx_buf)) {
320 PIOS_FLYINGPIO_SendCmd(&actuator_cfg);
325 static int PIOS_FLYINGPIO_ActuatorSetMode(
const uint16_t *out_rate,
326 const int banks,
const uint16_t *channel_max,
327 const uint16_t *channel_min) {
335 cmd->
rate[
i] = out_rate[
i];
338 for (
int i = 0;
i < ACTUATORCOMMAND_CHANNEL_NUMELEM;
i++) {
339 uint16_t true_min, true_max;
341 if (channel_min[
i] > channel_max[
i]) {
342 true_min = channel_max[
i];
343 true_max = channel_min[
i];
345 true_min = channel_min[
i];
346 true_max = channel_max[
i];
355 while (PIOS_FLYINGPIO_SendCmd(&actuator_cfg)) {
364 static void PIOS_FLYINGPIO_ActuatorSet(uint8_t
servo,
float position) {
367 channel_values[
servo] = position;
374 if (channel >= FPPROTO_MAX_RCCHANS) {
378 return dev->rcvr_value[channel];
381 static int32_t PIOS_FLYINGPIO_ADC_PinGet(uintptr_t dev_int, uint32_t pin) {
388 return dev->adc_value[pin];
391 static uint8_t PIOS_FLYINGPIO_ADC_NumberOfChannels(uintptr_t dev_int) {
395 #define VREF_PLUS 3.3f
396 static float PIOS_FLYINGPIO_ADC_LSB_Voltage(uintptr_t dev_int) {
398 return VREF_PLUS / (((uint32_t)1 << 16) - 1);
401 #endif // PIOS_INCLUDE_FLYINGPIO
uint16_t valid_messages_recvd
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
int32_t(* read)(uintptr_t id, uint8_t channel)
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_SPI_RC_PinSet(pios_spi_t spi_dev, uint32_t slave_id, bool pin_value)
uint16_t adc_data[FPPROTO_MAX_ADCCHANS]
int32_t PIOS_SPI_ClaimBus(pios_spi_t spi_dev)
void * PIOS_malloc(size_t size)
uint16_t values[FPPROTO_MAX_SERVOS]
int32_t PIOS_FLYINGPIO_Receiver_Get(uintptr_t dev_int, uint8_t channel)
Returns receiver data returned by flyingpio.
uint8_t data[XFER_BYTES_PER_PACKET]
#define FPPROTO_MAX_ADCCHANS
#define FLYINGPICMD_ACTUATOR
static struct flyingpicmd_cfg_fa cfg
const struct pios_adc_driver pios_flyingpio_adc_driver
uint16_t receiver_protocol
int32_t PIOS_SPI_SetClockSpeed(pios_spi_t spi_dev, uint32_t speed)
uint16_t rate[FPPROTO_MAX_BANKS]
int32_t PIOS_SPI_TransferBlock(pios_spi_t spi_dev, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len)
int32_t PIOS_FLYINGPIO_SPI_Init(pios_flyingpio_dev_t *dev, pios_spi_t spi_id, uint32_t slave_idx, uint8_t protocol)
Initialize the FlyingPIO programmed-IO expander.
struct pios_flyingpio_dev * pios_flyingpio_dev_t
void PIOS_Servo_SetCallbacks(const struct pios_servo_callbacks *cb)
#define FPPROTO_MAX_BANKS
#define FPPROTO_MAX_SERVOS
void PIOS_Thread_Sleep(uint32_t time_ms)
Includes PiOS and core architecture components.
int printf(const char *format,...)
int32_t PIOS_SPI_ReleaseBus(pios_spi_t spi_dev)
static ManualControlCommandData cmd
const struct pios_rcvr_driver pios_flyingpio_rcvr_driver
#define PIOS_Assert(test)
#define FPPROTO_MAX_RCCHANS
int32_t(* get_pin)(uintptr_t id, uint32_t pin)
uint16_t chan_data[FPPROTO_MAX_RCCHANS]
static bool flyingpi_calc_crc(struct flyingpi_msg *msg, bool fill_in, int *total_len)
int32_t PIOS_DELAY_WaituS(uint32_t uS)
struct flyingpicmd_cfg_fa::@15 actuators[FPPROTO_MAX_SERVOS]
#define PIOS_LED_HEARTBEAT
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.