axi_gen.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <math.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include "rp.h"
  7. #include "rp_asg_axi.h"
  8. // g++ axi_gen.c -std=c++20 -Wall -I/opt/redpitaya/include -L/opt/redpitaya/lib -static -lrp-hw-can -lrp -lrp-hw-calib -lrp-hw-profiles -lrp-gpio -lrp-i2c -lrp-hw -lm -lstdc++ -lpthread -li2c -lsocketcan -o axi_gen
  9. int main(int argc, char **argv) {
  10. // Select channel
  11. rp_channel_t channel = RP_CH_1;
  12. if(argc < 3)
  13. {
  14. fprintf(stderr, "Invalid args!");
  15. return -1;
  16. }
  17. // Data size in samples (16 bit)
  18. uint32_t bufferSize = 4096;
  19. uint32_t freq = 3000000;
  20. if(argv[0] != nullptr)
  21. {
  22. bufferSize = atoi(argv[1]); // Should be twice the actual number of samples
  23. }
  24. uint32_t dec_factor = 1;
  25. uint32_t num_buffers = 1;
  26. if(argv[1] != nullptr)
  27. {
  28. freq = atoi(argv[2]);
  29. }
  30. uint32_t ncyc = 1;
  31. uint32_t nor = 1;
  32. uint32_t period = 100;
  33. // Start addresses of buffers must be multiple of 4096 (DDR page size)
  34. uint32_t min_addr_diff = 4096;
  35. // Initialize the interface
  36. if (rp_Init() != RP_OK) {
  37. fprintf(stderr, "Rp api init failed!\n");
  38. return 1;
  39. }
  40. // Reset generator
  41. rp_GenReset();
  42. /* Setting up the Deep Memory Generation (DMG) */
  43. uint32_t dac_axi_start, dac_axi_size;
  44. // Get the reserved memory region start and size
  45. if (rp_AcqAxiGetMemoryRegion(&dac_axi_start, &dac_axi_size) != RP_OK) {
  46. fprintf(stderr, "Error get memory!\n");
  47. return 1;
  48. }
  49. // Lower the buffer size to the available memory size (if needed)
  50. uint32_t dmg_min_size = (uint32_t) (ceil((float) bufferSize / (float) min_addr_diff) * (float) min_addr_diff * (float) num_buffers);
  51. printf("Buffer size: %d\n", bufferSize);
  52. printf("Minimum size: %d\n", dmg_min_size);
  53. if (dmg_min_size > dac_axi_size) {
  54. printf("Buffer size is too large, reducing to available memory size\n");
  55. bufferSize = dac_axi_size / num_buffers;
  56. printf("Buffer size reduced to %d\n", bufferSize);
  57. }
  58. // Calculate the start address
  59. uint32_t gen1_start_addr = dac_axi_start;
  60. // Reserve memory for the generator
  61. printf("Reserved memory for OUT1 Start: %x Size: %x End: %x\n", gen1_start_addr, bufferSize, gen1_start_addr + bufferSize);
  62. if (rp_GenAxiReserveMemory(channel, gen1_start_addr, gen1_start_addr + bufferSize) != RP_OK) {
  63. fprintf(stderr, "Error setting address for DMG mode for OUT1\n");
  64. return 1;
  65. }
  66. // Set decimation factor
  67. if (rp_GenAxiSetDecimationFactor(channel, dec_factor) != RP_OK) {
  68. fprintf(stderr, "Error setting decimation for generator OUT1\n");
  69. return 1;
  70. }
  71. // Enable DMG mode
  72. if (rp_GenAxiSetEnable(channel, true) != RP_OK) {
  73. fprintf(stderr, "Error enable axi mode for OUT1\n");
  74. return 1;
  75. }
  76. // Define output waveform for both channels
  77. bufferSize /= 2; // Samples are float32 which is 4 bytes, int16 is 2 bytes
  78. float *t = (float *)malloc(bufferSize * sizeof(float));
  79. float *x = (float *)malloc(bufferSize * sizeof(float));
  80. for (uint32_t i = 1; i < bufferSize; i++) {
  81. t[i] = t[i-1] + 0.000000008f;
  82. }
  83. for (uint32_t i = 0; i < bufferSize; ++i) {
  84. // x[i] = sin(t[i] * freq * 2 * M_PI) * ((1.0f * (bufferSize - i)) / bufferSize);
  85. if(i > 512 && i < 3576)
  86. {
  87. x[i] = 1.0f;
  88. }
  89. else
  90. {
  91. x[i] = 0.0f;
  92. }
  93. }
  94. // Configure calibration and offset
  95. rp_GenSetAmplitudeAndOffsetOrigin(channel);
  96. // Set burst parameters
  97. rp_GenMode(channel, RP_GEN_MODE_BURST);
  98. rp_GenBurstCount(channel, ncyc);
  99. rp_GenBurstRepetitions(channel, nor);
  100. rp_GenBurstPeriod(channel, period);
  101. rp_GenAxiWriteWaveform(channel, x, bufferSize);
  102. rp_GenOutEnable(channel);
  103. rp_GenTriggerOnly(channel);
  104. // Release resources
  105. free(t);
  106. free(x);
  107. rp_Release();
  108. return 0;
  109. }