Advertisement
Guest User

Untitled

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