diff --git a/docs/src/man/man3/hm2_pktuart.3.adoc b/docs/src/man/man3/hm2_pktuart.3.adoc index 802e5ae4660..dea310ee7ab 100644 --- a/docs/src/man/man3/hm2_pktuart.3.adoc +++ b/docs/src/man/man3/hm2_pktuart.3.adoc @@ -150,11 +150,15 @@ This is typically a multi-step process: 1. rxstatus indicates that there are packets of data, but at this point we need to know how big each packet is (and reading two much or two little data from the FIFOs will cause problems). 2. Queue a read of the frame sizes. **hm2_pktuart_queue_get_frame_sizes(name, fsizes[])** On return, the fsizes[] array will have been loaded with the frame sizes (size in bytes). +The function returns the number of frame-size reads queued, or a negative error code. If fsizes are [8] [7] [6] and you only read 1 frame from the data FIFO then on the next call to get_frame_sizes the returned array would be [7] [6]. 3. Wait one thread cycle to get the data. Note that there is no serial latency here, the data is already on the FPGA but we can only know how much data to request once we know the packet size 4. Queue enough data reads to get all the data frames that the packet is spread over. int hm2_pktuart_queue_read_data(name, data, bytes) On return the data[] array will have been loaded with enough 32-bit frames to include "bytes" bytes. +The function returns the number of 32-bit data reads queued, or a negative error code. +Both queue helpers stop at the first queue failure; earlier reads may already +be queued. A successful return does not confirm completion of hardware I/O. 5. Parse the data. === Data Formats === diff --git a/src/hal/drivers/mesa-hostmot2/pktuart.c b/src/hal/drivers/mesa-hostmot2/pktuart.c index 4560ba18059..412b44f591b 100644 --- a/src/hal/drivers/mesa-hostmot2/pktuart.c +++ b/src/hal/drivers/mesa-hostmot2/pktuart.c @@ -129,7 +129,7 @@ int hm2_pktuart_parse_md(hostmot2_t *hm2, int md_index) // For the time being we assume that all PktUARTS come on pairs if(inst->clock_freq == 0) { inst->clock_freq = md->clock_freq; - r = rtapi_snprintf(inst->name, sizeof(inst->name), "%s.pktuart.%01d", hm2->llio->name, i); + rtapi_snprintf(inst->name, sizeof(inst->name), "%s.pktuart.%01d", hm2->llio->name, i); HM2_PRINT("created PktUART Interface function %s.\n", inst->name); } if(md->gtag == HM2_GTAG_PKTUART_TX) { @@ -300,24 +300,24 @@ static int config_tx(const char *name, const hostmot2_t* hm2, hm2_pktuart_instan } if((cfg->flags & HM2_PKTUART_CONFIG_FORCECONFIG) || bitrate != inst->tx_bitrate) { - inst->tx_bitrate = bitrate; - if((r = writefn(hm2->llio, inst->tx_bitrate_addr, &bitrate, sizeof(bitrate))) < 0) { + if((r = writefn(hm2->llio, inst->tx_bitrate_addr, &bitrate, sizeof(bitrate))) == 0) { HM2_ERR("Configure TX baudrate: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } + inst->tx_bitrate = bitrate; } if((cfg->flags & HM2_PKTUART_CONFIG_FORCECONFIG) || mode != inst->tx_mode) { - inst->tx_mode = mode; - if((r = writefn(hm2->llio, inst->tx_mode_addr, &mode, sizeof(mode))) < 0) { + if((r = writefn(hm2->llio, inst->tx_mode_addr, &mode, sizeof(mode))) == 0) { HM2_ERR("Configure TX mode: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } + inst->tx_mode = mode; } if(cfg->flags & HM2_PKTUART_CONFIG_FLUSH) { rtapi_u32 buff = HM2_PKTUART_CLEAR; // clear data FIFO and count register - if((r = writefn(hm2->llio, inst->tx_mode_addr, &buff, sizeof(buff))) < 0) { + if((r = writefn(hm2->llio, inst->tx_mode_addr, &buff, sizeof(buff))) == 0) { HM2_ERR("Configure TX flush: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } } return 0; @@ -380,24 +380,24 @@ static int config_rx(const char *name, const hostmot2_t *hm2, hm2_pktuart_instan } if((cfg->flags & HM2_PKTUART_CONFIG_FORCECONFIG) || bitrate != inst->rx_bitrate) { - inst->rx_bitrate = bitrate; - if((r = writefn(hm2->llio, inst->rx_bitrate_addr, &bitrate, sizeof(bitrate))) < 0) { + if((r = writefn(hm2->llio, inst->rx_bitrate_addr, &bitrate, sizeof(bitrate))) == 0) { HM2_ERR("Configure RX baudrate: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } + inst->rx_bitrate = bitrate; } if((cfg->flags & HM2_PKTUART_CONFIG_FORCECONFIG) || mode != inst->rx_mode) { - inst->rx_mode = mode; - if((r = writefn(hm2->llio, inst->rx_mode_addr, &mode, sizeof(mode))) < 0) { + if((r = writefn(hm2->llio, inst->rx_mode_addr, &mode, sizeof(mode))) == 0) { HM2_ERR("Configure RX mode: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } + inst->rx_mode = mode; } if(cfg->flags & HM2_PKTUART_CONFIG_FLUSH) { rtapi_u32 buff = HM2_PKTUART_CLEAR; // clear data FIFO and count register - if((r = writefn(hm2->llio, inst->rx_mode_addr, &buff, sizeof(buff))) < 0) { + if((r = writefn(hm2->llio, inst->rx_mode_addr, &buff, sizeof(buff))) == 0) { HM2_ERR("Configure RX flush: hm2->llio->%s failure %s (error %d)\n", writenm, name, r); - return r; + return -EIO; } } return 0; @@ -456,10 +456,10 @@ static void perform_reset(const char *name, int queue) } // clear sends, data FIFO and count register - if((i = wr(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) < 0) + if((i = wr(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) == 0) HM2_ERR("Failed to %s reset of TX data and FIFO (error %d)\n", msg, i); // clear receives, data FIFO and count register - if((i = wr(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) < 0) + if((i = wr(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) == 0) HM2_ERR("Failed to %s reset of RX data and FIFO (error %d)\n", msg, i); } @@ -515,11 +515,11 @@ int hm2_pktuart_setup(const char *name, unsigned bitrate, rtapi_s32 tx_mode, rta buff = (rtapi_u32)((bitrate * 1048576.0)/inst->clock_freq); // 20 bits in v0 & v1 } if(buff != inst->tx_bitrate) { - inst->tx_bitrate = buff; - if((r = hm2->llio->write(hm2->llio, inst->tx_bitrate_addr, &buff, sizeof(rtapi_u32))) < 0) { + if((r = hm2->llio->write(hm2->llio, inst->tx_bitrate_addr, &buff, sizeof(rtapi_u32))) == 0) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on tx bitrate (error %d)\n", name, r); - return r; + return -EIO; } + inst->tx_bitrate = buff; } if(hm2->pktuart.rx_version >= 2) { buff = (rtapi_u32)((bitrate * 16777216.0)/inst->clock_freq); // 24 bits in v2+ @@ -527,43 +527,43 @@ int hm2_pktuart_setup(const char *name, unsigned bitrate, rtapi_s32 tx_mode, rta buff = (rtapi_u32)((bitrate * 1048576.0)/inst->clock_freq); // 20 bits in v0 & v1 } if(buff != inst->rx_bitrate) { - inst->rx_bitrate = buff; - if((r = hm2->llio->write(hm2->llio, inst->rx_bitrate_addr, &buff, sizeof(rtapi_u32))) < 0) { + if((r = hm2->llio->write(hm2->llio, inst->rx_bitrate_addr, &buff, sizeof(rtapi_u32))) == 0) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on rx bitrate (error %d)\n", name, r); - return r; + return -EIO; } + inst->rx_bitrate = buff; } } if(tx_mode >= 0) { buff = ((rtapi_u32)tx_mode) & HM2_PKTUART_TXMODE_MASK; - if((r = hm2->llio->write(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) < 0) { + if((r = hm2->llio->write(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) == 0) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on tx_mode (error %d)\n", name, r); - return r; + return -EIO; } } if(rx_mode >= 0) { buff = ((rtapi_u32)rx_mode) & HM2_PKTUART_RXMODE_MASK; - if((r = hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) < 0) { + if((r = hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) == 0) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on rx_mode (error %d)\n", name, r); - return r; + return -EIO; } } buff = HM2_PKTUART_CLEAR; if(txclear == 1) { // clear sends, data FIFO and count register - if((r = hm2->llio->write(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) < 0) { + if((r = hm2->llio->write(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32))) == 0) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on tx clear (error %d)\n", name, r); - return r; + return -EIO; } } if(rxclear == 1) { // clear receives, data FIFO and count register - if((r = hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) < 0 ) { + if((r = hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32))) == 0 ) { HM2_ERR("PktUART setup: hm2->llio->write failure %s on rx clear (error %d)\n", name, r); - return r; + return -EIO; } } @@ -615,9 +615,9 @@ int hm2_pktuart_send(const char *name, const unsigned char data[], rtapi_u8 *num while(c < count - 3) { rtapi_u32 buff = data[c] + (data[c+1] << 8) + (data[c+2] << 16) + (data[c+3] << 24); r = hm2->llio->queue_write(hm2->llio, hm2->pktuart.instance[inst].tx_addr, &buff, sizeof(buff)); - if(r < 0) { + if(r == 0) { HM2_ERR("%s send: hm2->llio->queue_write failure\n", name); - return r; + return -EIO; } c += 4; } @@ -634,9 +634,9 @@ int hm2_pktuart_send(const char *name, const unsigned char data[], rtapi_u8 *num return -1; } // end switch r = hm2->llio->queue_write(hm2->llio, hm2->pktuart.instance[inst].tx_addr, &buff, sizeof(buff)); - if(r < 0) { + if(r == 0) { HM2_ERR("%s send: hm2->llio->queue_write failure\n", name); - return r; + return -EIO; } } (*num_frames)++; @@ -652,9 +652,9 @@ int hm2_pktuart_send(const char *name, const unsigned char data[], rtapi_u8 *num // Not possible to check for errors on the fly when using queued // transfers. The data does not arrive immediately. Therefore, no // checks can be done here. - if(r < 0) { + if(r == 0) { HM2_ERR("%s send: hm2->llio->queue_write failure\n", name); - return r; + return -EIO; } } return count; @@ -698,9 +698,9 @@ int hm2_pktuart_read(const char *name, unsigned char data[], rtapi_u8 *num_frame // First poll the mode register for a non zero frames received count // (mode register bits 20..16) r = hm2->llio->read(hm2->llio, hm2->pktuart.instance[inst].rx_mode_addr, &buff, sizeof(rtapi_u32)); - if(r < 0) { + if(r == 0) { HM2_ERR("%s read: hm2->llio->read failure\n", name); - return r; + return -EIO; } if(buff & (0x1 << 21)) { countp = (buff >> 16) & 0x1f; @@ -753,6 +753,10 @@ int hm2_pktuart_read(const char *name, unsigned char data[], rtapi_u8 *num_frame of received packets. Since it is a FIFO it must only be read once after it has be determined that there are packets available to read. */ r = hm2->llio->read(hm2->llio, hm2->pktuart.instance[inst].rx_fifo_count_addr, &buff, sizeof(buff)); + if(r == 0) { + HM2_ERR("%s read: hm2->llio->read failure\n", name); + return -EIO; + } countb = buff & 0x3ff; // PktUARTr receive count register Bits 9..0 : bytes in receive packet @@ -791,9 +795,9 @@ int hm2_pktuart_read(const char *name, unsigned char data[], rtapi_u8 *num_frame while(c < countb - 3) { r = hm2->llio->read(hm2->llio, hm2->pktuart.instance[inst].rx_addr, &buff, sizeof(buff)); - if(r < 0) { + if(r == 0) { HM2_ERR("%s read: hm2->llio->read failure\n", name); - return r; + return -EIO; } data[bytes_total+c+0] = (buff & 0x000000FF); // i*frame_sizes[i] @@ -805,9 +809,9 @@ int hm2_pktuart_read(const char *name, unsigned char data[], rtapi_u8 *num_frame if(countb - c) { r = hm2->llio->read(hm2->llio, hm2->pktuart.instance[inst].rx_addr, &buff, sizeof(buff)); - if(r < 0) { - HM2_ERR("%s read: hm2->llio->queue_write failure\n", name); - return -1; + if(r == 0) { + HM2_ERR("%s read: hm2->llio->read failure\n", name); + return -EIO; } switch(countb - c) { case 1: @@ -867,11 +871,12 @@ int hm2_pktuart_queue_get_frame_sizes(const char *name, rtapi_u32 fsizes[]) for(j = 0; j < nfs; j++ ) { r = hm2->llio->queue_read(hm2->llio, hm2->pktuart.instance[inst].rx_fifo_count_addr, &fsizes[j], sizeof(rtapi_u32)); - if(r < 0) { + if(r == 0) { HM2_ERR("Unable to queue Rx FIFO count read %d of %d (error %d))\n", j, nfs, r); + return -EIO; } } - return j - 1; + return j; } EXPORT_SYMBOL_GPL(hm2_pktuart_queue_get_frame_sizes); @@ -904,6 +909,7 @@ int hm2_pktuart_queue_read_data(const char *name, rtapi_u32 data[], int bytes) HM2_ERR("%s has not been configured.\n", name); return -EINVAL; } + if(bytes < 0) return -EINVAL; // queue enough reads to get the whole frame. Data will be transferred // to data[] next thread cycle, direct from FPGA, no serial latency @@ -911,11 +917,12 @@ int hm2_pktuart_queue_read_data(const char *name, rtapi_u32 data[], int bytes) for(i = 0; i < nrx; i++ ) { r = hm2->llio->queue_read(hm2->llio, hm2->pktuart.instance[inst].rx_addr, &data[i], sizeof(rtapi_u32)); - if(r < 0) { + if(r == 0) { HM2_ERR("Unable to queue Rx FIFO read %d of %d (error %d)\n", i, nrx, r); + return -EIO; } } - return i - 1; + return i; } EXPORT_SYMBOL_GPL(hm2_pktuart_queue_read_data);