1 #include "nxt_motors.h"
5 #include "interrupts.h"
16 #define MOTOR_PIN_MASK ((1 << MA0) | (1<<MA1) | (1<<MB0) | (1<<MB1) | (1<<MC0) | (1<<MC1))
17 #define MOTOR_INTERRUPT_PINS ((1 << MA0) | (1<<MB0) | (1<<MC0))
20 static struct motor_struct {
25 } motor[NXT_N_MOTORS];
27 static U32 nxt_motor_initialised;
28 static U32 interrupts_this_period;
31 nxt_motor_get_count(U32 n)
34 return motor[n].current_count;
40 nxt_motor_set_count(U32 n, int count)
43 motor[n].current_count = count;
47 nxt_motor_set_speed(U32 n, int speed_percent, int brake)
49 if (n < NXT_N_MOTORS) {
50 if (speed_percent > 100)
52 if (speed_percent < -100)
54 motor[n].speed_percent = speed_percent;
55 nxt_avr_set_motor(n, speed_percent, brake);
60 nxt_motor_command(U32 n, int cmd, int target_count, int speed_percent)
62 if (n < NXT_N_MOTORS) {
63 motor[n].target_count = target_count;
64 motor[n].speed_percent = speed_percent;
70 nxt_motor_1kHz_process(void)
72 if (nxt_motor_initialised) {
73 interrupts_this_period = 0;
74 *AT91C_PIOA_IER = MOTOR_INTERRUPT_PINS;
80 nxt_motor_quad_decode(struct motor_struct *m, U32 value)
83 if (m->last != value) {
84 if ((m->last + 1) & 3 == value)
86 else if ((value + 1) & 3 == m->last)
95 if (edge != m->last) {
100 else if (!edge && dir)
102 else if (!edge && !dir)
109 extern void nxt_motor_isr_entry(void);
112 nxt_motor_isr_C(void)
114 U32 i_state = interrupts_get_and_disable();
116 U32 pinChanges = *AT91C_PIOA_ISR; // Acknowledge change
117 U32 currentPins = *AT91C_PIOA_PDSR; // Read pins
121 interrupts_this_period++;
122 if (interrupts_this_period > 4) {
123 *AT91C_PIOA_IDR = MOTOR_INTERRUPT_PINS;
124 // Todo : tacho speed fault
129 pins = ((currentPins >> MA0) & 1) | ((currentPins >> (MA1 - 1)) & 2);
130 nxt_motor_quad_decode(&motor[0], pins);
133 pins = ((currentPins >> MB0) & 1) | ((currentPins >> (MB1 - 1)) & 2);
134 nxt_motor_quad_decode(&motor[1], pins);
137 pins = ((currentPins >> MC0) & 1) | ((currentPins >> (MC1 - 1)) & 2);
138 nxt_motor_quad_decode(&motor[2], pins);
150 *AT91C_PMC_PCER = (1 << AT91C_PERIPHERAL_ID_PIOA); /* Power to the pins! */
151 *AT91C_PIOA_IDR = ~0;
152 *AT91C_PIOA_IFER = MOTOR_PIN_MASK;
153 *AT91C_PIOA_PPUDR = MOTOR_PIN_MASK;
154 *AT91C_PIOA_PER = MOTOR_PIN_MASK;
155 *AT91C_PIOA_ODR = MOTOR_PIN_MASK;
158 aic_mask_off(AT91C_PERIPHERAL_ID_PIOA);
159 aic_set_vector(AT91C_PERIPHERAL_ID_PIOA, AIC_INT_LEVEL_NORMAL,
160 nxt_motor_isr_entry);
161 aic_mask_on(AT91C_PERIPHERAL_ID_PIOA);
163 *AT91C_PIOA_IER = MOTOR_INTERRUPT_PINS;
165 nxt_motor_initialised = 1;