/* This performs a two-way transfer over AXI DMA, both sending data out and * receiving it back over DMA. The user determines if this call is blocking. */ int axidma_twoway_transfer(axidma_dev_t dev, int tx_channel, void *tx_buf, size_t tx_len, int rx_channel, void *rx_buf, size_t rx_len, bool wait) { int rc; struct axidma_inout_transaction trans; assert(valid_channel(dev, tx_channel, AXIDMA_WRITE)); assert(valid_channel(dev, rx_channel, AXIDMA_READ)); // Setup the argument structure for the IOCTL trans.wait = wait; trans.tx_channel_id = tx_channel; trans.tx_buf = tx_buf; trans.tx_buf_len = tx_len; trans.rx_channel_id = rx_channel; trans.rx_buf = rx_buf; trans.rx_buf_len = rx_len; // Perform the read-write transfer rc = ioctl(dev->fd, AXIDMA_DMA_READWRITE, &trans); if (rc < 0) { perror("Failed to perform the AXI DMA read-write transfer"); } return rc; }
/* This performs a one-way transfer over AXI DMA, the direction being specified * by the user. The user determines if this is blocking or not with `wait. */ int axidma_oneway_transfer(axidma_dev_t dev, enum axidma_dir dir, int channel, void *buf, size_t len, bool wait) { int rc; struct axidma_transaction trans; unsigned long axidma_cmd; assert(dir == AXIDMA_READ || dir == AXIDMA_WRITE); assert(dir != AXIDMA_READ || valid_channel(dev, channel, AXIDMA_READ)); assert(dir != AXIDMA_WRITE || valid_channel(dev, channel, AXIDMA_WRITE)); // Setup the argument structure to the IOCTL trans.wait = wait; trans.channel_id = channel; trans.buf = buf; trans.buf_len = len; axidma_cmd = dir_to_ioctl(dir); // Perform the given transfer rc = ioctl(dev->fd, axidma_cmd, &trans); if (rc < 0) { perror("Failed to perform the AXI DMA transfer"); return rc; } return 0; }
/* send a buffer out a MAVLink channel */ void comm_send_buffer(mavlink_channel_t chan, const uint8_t *buf, uint8_t len) { if (!valid_channel(chan)) { return; } mavlink_comm_port[chan]->write(buf, len); }
/// Read a byte from the nominated MAVLink channel /// /// @param chan Channel to receive on /// @returns Byte read /// uint8_t comm_receive_ch(mavlink_channel_t chan) { if (!valid_channel(chan)) { return 0; } return (uint8_t)mavlink_comm_port[chan]->read(); }
/* lock a channel, preventing use by MAVLink */ void GCS_MAVLINK::lock_channel(mavlink_channel_t _chan, bool lock) { if (!valid_channel(chan)) { return; } if (lock) { mavlink_locked_mask |= (1U<<(unsigned)_chan); } else { mavlink_locked_mask &= ~(1U<<(unsigned)_chan); } }
/* This function stops all transfers on the given channel with the given * direction. This function is required to stop any video transfers, or any * non-blocking transfers. */ void axidma_stop_transfer(axidma_dev_t dev, int channel, enum axidma_dir dir) { struct axidma_chan chan; assert(dir == AXIDMA_READ || dir == AXIDMA_WRITE); assert(dir != AXIDMA_READ || valid_channel(dev, channel, AXIDMA_READ)); assert(dir != AXIDMA_WRITE || valid_channel(dev, channel, AXIDMA_WRITE)); // Setup the argument structure for the IOCTL chan.channel_id = channel; chan.dir = dir; chan.type = AXIDMA_DMA; // Stop all transfers on the given DMA channel if (ioctl(dev->fd, AXIDMA_STOP_DMA_CHANNEL, &chan) < 0) { perror("Failed to stop the DMA channel"); assert(false); } return; }
/// Check for available data on the nominated MAVLink channel /// /// @param chan Channel to check /// @returns Number of bytes available uint16_t comm_get_available(mavlink_channel_t chan) { if (!valid_channel(chan)) { return 0; } if ((1U<<chan) & mavlink_locked_mask) { return 0; } int16_t bytes = mavlink_comm_port[chan]->available(); if (bytes == -1) { return 0; } return (uint16_t)bytes; }
/// Check for available transmit space on the nominated MAVLink channel /// /// @param chan Channel to check /// @returns Number of bytes available uint16_t comm_get_txspace(mavlink_channel_t chan) { if (!valid_channel(chan)) { return 0; } if ((1U<<chan) & mavlink_locked_mask) { return 0; } int16_t ret = mavlink_comm_port[chan]->txspace(); if (ret < 0) { ret = 0; } return (uint16_t)ret; }
void GCS_MAVLINK::init(AP_HAL::UARTDriver *port, mavlink_channel_t mav_chan) { if (!valid_channel(mav_chan)) { return; } _port = port; chan = mav_chan; mavlink_comm_port[chan] = _port; initialised = true; _queued_parameter = NULL; reset_cli_timeout(); }
/* return true if a channel has flow control */ bool GCS_MAVLINK::have_flow_control(void) { if (!valid_channel(chan)) { return false; } if (mavlink_comm_port[chan] == NULL) { return false; } if (chan == MAVLINK_COMM_0) { // assume USB console has flow control return hal.gpio->usb_connected() || mavlink_comm_port[chan]->get_flow_control() != AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE; } else { // all other channels return mavlink_comm_port[chan]->get_flow_control() != AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE; } }
/* This function performs a video transfer over AXI DMA, setting up the DMA to * read from the given frame buffers on-demand continuously. This call is * always non-blocking. The transfer must be stopped with a call to * axidma_stop_transfer. */ int axidma_video_transfer(axidma_dev_t dev, int display_channel, size_t width, size_t height, size_t depth, void **frame_buffers, int num_buffers) { int rc; struct axidma_video_transaction trans; assert(valid_channel(dev, display_channel, AXIDMA_WRITE)); // Setup the argument structure for the IOCTL trans.channel_id = display_channel; trans.num_frame_buffers = num_buffers; trans.frame_buffers = frame_buffers; trans.width = width; trans.height = height; trans.depth = depth; // Perform the video transfer rc = ioctl(dev->fd, AXIDMA_DMA_VIDEO_WRITE, &trans); if (rc < 0) { perror("Failed to perform the AXI DMA video write transfer"); } return rc; }