Advertisement
Guest User

Untitled

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