diff --git a/device_support/redpitaya/redpitaya.cpp b/device_support/redpitaya/redpitaya.cpp index 2a2c597a6e..22294d9c33 100644 --- a/device_support/redpitaya/redpitaya.cpp +++ b/device_support/redpitaya/redpitaya.cpp @@ -27,7 +27,13 @@ extern "C" void rpadcStop(int fd); void openTree(char *name, int shot, MDSplus::Tree **treePtr); void setTriggerTime(unsigned long long triggerTime); -} + int rpuartInit(int hi_div, int lo_div); + int rpuartGetSegment(int fd, int segment_size, char *c1, char *c2, char *c3, char *c4, char *c5); + int rpuartTrigger(); + int rpuartTriggerFd(int fd); + int rpuartStartStore(); + int rpuartStopStore(int fd); + } enum rpadc_mode @@ -797,3 +803,150 @@ void openTree(char *name, int shot, MDSplus::Tree **treePtr) } } + + +////////////////////rfx_triguart related stuff + +#undef DEVICE_NAME +#undef MODULE_NAME +#include + + +static int rpuartOpenChecked() +{ + int fd; + fd = open("/dev/rfx_triguart", O_RDWR | O_SYNC); + while(fd < 0) + { + printf("retrying open device....\b"); + sleep(1); + fd = open("/dev/rfx_triguart", O_RDWR | O_SYNC); + } + return fd; +} + + + +int rpuartInit(int hi_div, int lo_div) +{ + struct rpadc_configuration inConfig, outConfig; + int fd = rpuartOpenChecked(); + int reg; + ioctl(fd, RFX_TRIGUART_SET_DIV_HI_REG, &hi_div); + ioctl(fd, RFX_TRIGUART_SET_DIV_LO_REG, &lo_div); + reg = 0; + ioctl(fd, RFX_TRIGUART_GET_DIV_HI_REG, ®); + if(reg != hi_div) + { + printf("INTERNAL ERROR cannot set hi_div\n"); + close(fd); + return -1; + } + reg = 0; + ioctl(fd, RFX_TRIGUART_GET_DIV_LO_REG, ®); + if(reg != lo_div) + { + printf("INTERNAL ERROR cannot set lo_div\n"); + close(fd); + return -1; + } + + // stop device + reg = 4; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + + // Arm device + reg = 1; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + close(fd); + return 0; +} + +int rpuartTrigger() +{ + int fd = rpuartOpenChecked(); + unsigned int reg = 2; + ioctl(fd, RFX_TRIGUART_CLEAR_DATA_FIFO, 0); + reg = 8; //reset UARTs + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 2; //Trigger + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + close(fd); + return 0; +} + +int rpuartTriggerFd(int fd) +{ + unsigned int reg = 2; + ioctl(fd, RFX_TRIGUART_CLEAR_DATA_FIFO, 0); + reg = 8; //reset UARTs + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 2; //Trigger + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + return 0; +} + +int rpuartStartStore() +{ + int fd = rpuartOpenChecked(); + ioctl(fd, RFX_TRIGUART_START_READ, 0); + return fd; +} + + +int rpuartGetSegment(int fd, int segment_size, char *ch1, char *ch2, char *ch3, char *ch4, char *ch5) +{ + uint32_t hi, lo, rb; + for(int sample = 0; sample < segment_size; sample++) + { + do { + rb = read(fd, &lo, sizeof(int)); + }while(rb == 0); + if(rb < 0) + return -1; + do { + rb = read(fd, &hi, sizeof(int)); + } while(rb == 0); + if(rb < 0) + return -1; + ch1[sample] = lo; + ch2[sample] = lo >> 8; + ch3[sample] = lo >> 16; + ch4[sample] = lo >> 24; + ch5[sample] = hi; + ch1[sample] -= 128; + ch2[sample] -= 128; + ch3[sample] -= 128; + ch4[sample] -= 128; + ch5[sample] -= 128; + } + return 0; + } + +int rpuartStopStore(int fd) +{ + int reg; + // stop device + reg = 4; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + reg = 0; + ioctl(fd, RFX_TRIGUART_SET_CMD_REG_1, ®); + + close(fd); + return 0; +} + + + diff --git a/device_support/redpitaya/rfx_triguart.h b/device_support/redpitaya/rfx_triguart.h new file mode 100644 index 0000000000..4938cde65c --- /dev/null +++ b/device_support/redpitaya/rfx_triguart.h @@ -0,0 +1,157 @@ +#ifndef RFX_TRIGUART_H +#define RFX_TRIGUART_H + + +#include +#include + + + +#ifdef __cplusplus +extern "C" { +#endif + +//Temporaneo +#define DMA_SOURCE 1 +//////////////// + + +#define DEVICE_NAME "rfx_triguart" /* Dev name as it appears in /proc/devices */ +#define MODULE_NAME "rfx_triguart" + +//Generic IOCTL commands + +#define RFX_TRIGUART_IOCTL_BASE 'W' +#define RFX_TRIGUART_ARM_DMA _IO(RFX_TRIGUART_IOCTL_BASE, 1) +#define RFX_TRIGUART_START_DMA _IO(RFX_TRIGUART_IOCTL_BASE, 2) +#define RFX_TRIGUART_STOP_DMA _IO(RFX_TRIGUART_IOCTL_BASE, 3) +#define RFX_TRIGUART_SET_DMA_BUFLEN _IO(RFX_TRIGUART_IOCTL_BASE, 4) +#define RFX_TRIGUART_GET_DMA_BUFLEN _IO(RFX_TRIGUART_IOCTL_BASE, 5) +#define RFX_TRIGUART_IS_DMA_RUNNING _IO(RFX_TRIGUART_IOCTL_BASE, 6) +#define RFX_TRIGUART_GET_DMA_DATA _IO(RFX_TRIGUART_IOCTL_BASE, 7) +#define RFX_TRIGUART_SET_DRIVER_BUFLEN _IO(RFX_TRIGUART_IOCTL_BASE, 8) +#define RFX_TRIGUART_GET_DRIVER_BUFLEN _IO(RFX_TRIGUART_IOCTL_BASE, 9) +#define RFX_TRIGUART_GET_REGISTERS _IO(RFX_TRIGUART_IOCTL_BASE, 10) +#define RFX_TRIGUART_SET_REGISTERS _IO(RFX_TRIGUART_IOCTL_BASE, 11) +#define RFX_TRIGUART_FIFO_INT_HALF_SIZE _IO(RFX_TRIGUART_IOCTL_BASE, 12) +#define RFX_TRIGUART_FIFO_INT_FIRST_SAMPLE _IO(RFX_TRIGUART_IOCTL_BASE, 13) +#define RFX_TRIGUART_FIFO_FLUSH _IO(RFX_TRIGUART_IOCTL_BASE, 14) +#define RFX_TRIGUART_START_READ _IO(RFX_TRIGUART_IOCTL_BASE, 15) +#define RFX_TRIGUART_STOP_READ _IO(RFX_TRIGUART_IOCTL_BASE, 16) +#define RFX_TRIGUART_GET_CMD_REG _IO(RFX_TRIGUART_IOCTL_BASE, 20) +#define RFX_TRIGUART_SET_CMD_REG _IO(RFX_TRIGUART_IOCTL_BASE, 21) +#define RFX_TRIGUART_GET_CMD_REG_1 _IO(RFX_TRIGUART_IOCTL_BASE, 22) +#define RFX_TRIGUART_SET_CMD_REG_1 _IO(RFX_TRIGUART_IOCTL_BASE, 23) +#define RFX_TRIGUART_GET_DIV_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 24) +#define RFX_TRIGUART_SET_DIV_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 25) +#define RFX_TRIGUART_GET_DIV_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 26) +#define RFX_TRIGUART_SET_DIV_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 27) +#define RFX_TRIGUART_GET_K1_REG _IO(RFX_TRIGUART_IOCTL_BASE, 28) +#define RFX_TRIGUART_SET_K1_REG _IO(RFX_TRIGUART_IOCTL_BASE, 29) +#define RFX_TRIGUART_GET_K2_REG _IO(RFX_TRIGUART_IOCTL_BASE, 30) +#define RFX_TRIGUART_SET_K2_REG _IO(RFX_TRIGUART_IOCTL_BASE, 31) +#define RFX_TRIGUART_GET_STEP_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 32) +#define RFX_TRIGUART_SET_STEP_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 33) +#define RFX_TRIGUART_GET_STEP_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 34) +#define RFX_TRIGUART_SET_STEP_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 35) +#define RFX_TRIGUART_GET_TIME_OFS_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 36) +#define RFX_TRIGUART_SET_TIME_OFS_HI_REG _IO(RFX_TRIGUART_IOCTL_BASE, 37) +#define RFX_TRIGUART_GET_TIME_OFS_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 38) +#define RFX_TRIGUART_SET_TIME_OFS_LO_REG _IO(RFX_TRIGUART_IOCTL_BASE, 39) +#define RFX_TRIGUART_GET_DATA_FIFO_LEN _IO(RFX_TRIGUART_IOCTL_BASE, 40) +#define RFX_TRIGUART_GET_DATA_FIFO_VAL _IO(RFX_TRIGUART_IOCTL_BASE, 41) +#define RFX_TRIGUART_SET_DATA_FIFO_VAL _IO(RFX_TRIGUART_IOCTL_BASE, 42) +#define RFX_TRIGUART_CLEAR_DATA_FIFO _IO(RFX_TRIGUART_IOCTL_BASE, 43) +#define RFX_TRIGUART_GET_TIME_FIFO_LEN _IO(RFX_TRIGUART_IOCTL_BASE, 44) +#define RFX_TRIGUART_GET_TIME_FIFO_VAL _IO(RFX_TRIGUART_IOCTL_BASE, 45) +#define RFX_TRIGUART_SET_TIME_FIFO_VAL _IO(RFX_TRIGUART_IOCTL_BASE, 46) +#define RFX_TRIGUART_CLEAR_TIME_FIFO _IO(RFX_TRIGUART_IOCTL_BASE, 47) + + +#ifndef AXI_ENUMS_DEFINED +#define AXI_ENUMS_DEFINED +enum AxiStreamFifo_Register { + ISR = 0x00, ///< Interrupt Status Register (ISR) + IER = 0x04, ///< Interrupt Enable Register (IER) + TDFR = 0x08, ///< Transmit Data FIFO Reset (TDFR) + TDFV = 0x0c, ///< Transmit Data FIFO Vacancy (TDFV) + TDFD = 0x10, ///< Transmit Data FIFO 32-bit Wide Data Write Port + TDFD4 = 0x1000, ///< Transmit Data FIFO for AXI4 Data Write Port + TLR = 0x14, ///< Transmit Length Register (TLR) + RDFR = 0x18, ///< Receive Data FIFO reset (RDFR) + RDFO = 0x1c, ///< Receive Data FIFO Occupancy (RDFO) + RDFD = 0x20, ///< Receive Data FIFO 32-bit Wide Data Read Port (RDFD) + RDFD4 = 0x1000, ///< Receive Data FIFO for AXI4 Data Read Port (RDFD) + RLR = 0x24, ///< Receive Length Register (RLR) + SRR = 0x28, ///< AXI4-Stream Reset (SRR) + TDR = 0x2c, ///< Transmit Destination Register (TDR) + RDR = 0x30, ///< Receive Destination Register (RDR) + /// not supported yet .. /// + TID = 0x34, ///< Transmit ID Register + TUSER = 0x38, ///< Transmit USER Register + RID = 0x3c, ///< Receive ID Register + RUSER = 0x40 ///< Receive USER Register +}; + +enum AxiStreamFifo_ISREnum { + ISR_RFPE = 1 << 19, ///< Receive FIFO Programmable Empty + ISR_RFPF = 1 << 20, ///< Receive FIFO Programmable Full + ISR_TFPE = 1 << 21, ///< Transmit FIFO Programmable Empty + ISR_TFPF = 1 << 22, ///< Transmit FIFO Programmable Full + ISR_RRC = 1 << 23, ///< Receive Reset Complete + ISR_TRC = 1 << 24, ///< Transmit Reset Complete + ISR_TSE = 1 << 25, ///< Transmit Size Error + ISR_RC = 1 << 26, ///< Receive Complete + ISR_TC = 1 << 27, ///< Transmit Complete + ISR_TPOE = 1 << 28, ///< Transmit Packet Overrun Error + ISR_RPUE = 1 << 29, ///< Receive Packet Underrun Error + ISR_RPORE = 1 << 30, ///< Receive Packet Overrun Read Error + ISR_RPURE = 1 << 31, ///< Receive Packet Underrun Read Error +}; + +enum RegisterIdx { + FIFO_00_IDX = 0, + FIFO_01_IDX = 1, + FIFO_10_IDX = 2, + FIFO11_IDX = 3, + COMMAND_REG_IDX = 4, + PRE_POST_REG_IDX = 5, + DEC_REG_IDX = 6, + MODE_REG_IDX = 8 +}; +#endif + +#pragma pack(1) + +struct rfx_triguart_registers +{ + char cmd_reg_enable; + unsigned int cmd_reg; + char cmd_reg_1_enable; + unsigned int cmd_reg_1; + char div_hi_reg_enable; + unsigned int div_hi_reg; + char div_lo_reg_enable; + unsigned int div_lo_reg; + char k1_reg_enable; + unsigned int k1_reg; + char k2_reg_enable; + unsigned int k2_reg; + char step_hi_reg_enable; + unsigned int step_hi_reg; + char step_lo_reg_enable; + unsigned int step_lo_reg; + char time_ofs_hi_reg_enable; + unsigned int time_ofs_hi_reg; + char time_ofs_lo_reg_enable; + unsigned int time_ofs_lo_reg; + +}; + + + +#ifdef __cplusplus +} +#endif + +#endif // RFX_TRIGUART_H