Advertisement
DenseBrainMatrix

Untitled

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