Advertisement
Guest User

Untitled

a guest
Jun 13th, 2021
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.98 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stddef.h>
  3.  
  4. struct Message {
  5. uint32_t id;
  6. uint32_t time;
  7. uint32_t position;
  8. int32_t force;
  9. uint8_t duty_cycle;
  10. uint8_t wave_form;
  11. };
  12.  
  13. // layout of shared ddr3 memory (filled in by loader)
  14. struct DDRLayout {
  15. Message volatile *msgbuf;
  16. uint16_t num_msgs;
  17. uint16_t msg_size;
  18. };
  19.  
  20. struct SharedVars {
  21. // set by pru before halting
  22. char const *abort_file;
  23. int abort_line;
  24.  
  25. // read-pointer updated by python
  26. uint16_t ridx;
  27. };
  28.  
  29. far struct DDRLayout ddr __attribute__((location(0x10000))) = {};
  30. far struct SharedVars volatile shmem __attribute__((location(0x10100))) = {};
  31.  
  32.  
  33. // for easier debugging, record where in the source code we halted
  34.  
  35. __attribute__((noreturn))
  36. void abort_at( char const *file, int line )
  37. {
  38. shmem.abort_file = file;
  39. shmem.abort_line = line;
  40. for(;;) __halt();
  41. }
  42.  
  43. static inline void assert_at( bool cond, char const *file, int line )
  44. {
  45. if( ! cond )
  46. abort_at( file, line );
  47. }
  48.  
  49. #define abort() abort_at( __FILE__, __LINE__ )
  50. #define assert(cond) assert_at( (cond), __FILE__, __LINE__ )
  51.  
  52.  
  53. // local copy of write-pointer
  54. static uint16_t widx = 0;
  55.  
  56. // global var for write-pointer is located right after message ringbuffer
  57. #define ddr_msgbuf_end ( ddr.msgbuf + ddr.num_msgs )
  58. #define ddr_widx ( *(uint16_t volatile *)ddr_msgbuf_end )
  59.  
  60. void initialize()
  61. {
  62. // perform sanity-checking
  63. assert( 0x80000000 <= (uint32_t)ddr.msgbuf );
  64. assert( ddr.msgbuf < ddr_msgbuf_end );
  65. assert( ddr.msg_size == sizeof(Message) );
  66.  
  67. assert( ddr_widx == widx );
  68. assert( shmem.ridx == widx );
  69. }
  70.  
  71. static inline uint16_t next_idx( uint16_t idx )
  72. {
  73. if( ++idx == ddr.num_msgs )
  74. idx = 0;
  75. return idx;
  76. }
  77.  
  78. void send_message( uint32_t id, uint32_t position, int32_t force )
  79. {
  80. uint16_t next_widx = next_idx( widx );
  81.  
  82. if( next_widx == shmem.ridx ) {
  83. // can't send message, ringbuffer is full
  84. abort();
  85. }
  86.  
  87. Message volatile *msg = &ddr.msgbuf[ widx ];
  88.  
  89. // fill in contents of message
  90. msg->id = id;
  91. msg->force = force;
  92. msg->position = position;
  93. msg->duty_cycle = 0
  94. msg->wave_form = 0
  95. // update write-pointer
  96. ddr_widx = widx = next_widx;
  97. }
  98.  
  99.  
  100. static inline char uart_recv_byte()
  101. {
  102. for(;;) {
  103. uint8_t lsr = CT_UART.LSR;
  104. if( lsr & 0x1e )
  105. __halt(); // receive-error occurred
  106. if( lsr & 0x01 )
  107. return (char) CT_UART.RBR;
  108. }
  109. }
  110.  
  111.  
  112. // receive CR-terminated line from uart
  113. static inline uint8_t uart_recv_line( char volatile msg[], uint8_t maxlen )
  114. {
  115. uint8_t len = 0;
  116.  
  117. for(;;) {
  118. char c = uart_recv_byte();
  119. if( c == '\r' )
  120. break; // found end of line
  121. if( len == maxlen )
  122. __halt(); // line does not fit in buffer
  123. msg[ len++ ] = c;
  124. }
  125.  
  126. return len;
  127. }
  128.  
  129. // receive and parse measurement message from load cell
  130. int32_t receive_measurement()
  131. {
  132. // allocate buffer at fixed address for debugging convenience
  133. static char volatile msg[8] __attribute__((location(0x1f00)));
  134.  
  135. // receive line from uart
  136. uint8_t len = uart_recv_line( msg, sizeof msg );
  137.  
  138. // verify length and prefix
  139. if( len != 8 || msg[0] != 'N' || (msg[1] != '+' && msg[1] != '-'))
  140. __halt();
  141.  
  142. // parse the remainder as integer
  143. int32_t value = 0;
  144. uint8_t i;
  145. for( i = 2; i < len; i++ ) {
  146. if( msg[i] < '0' || msg[i] > '9' )
  147. __halt();
  148. value = value * 10 + ( msg[i] - '0' );
  149. }
  150. if (msg[1] == '-')
  151. value *= -1;
  152.  
  153. return value;
  154. }
  155.  
  156.  
  157. // encoder position in other PRU core's memory
  158. #define position_var ((uint32_t const volatile *)0x00002000)
  159.  
  160. void main() {
  161. initialize();
  162.  
  163. uint32_t id = 0;
  164. int32_t force = 0;
  165. uint32_t position =0;
  166.  
  167.  
  168.  
  169. for(;;) {
  170.  
  171.  
  172. // parse and interpret message from load cell
  173. force = receive_measurement();
  174.  
  175. // read position value from decoder
  176. position = *position_var;
  177.  
  178. send_message( ++id,force,position );
  179. __delay_cycles( 10000 );
  180. }
  181. }
  182.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement