4040#endif
4141
4242struct _pbdrv_counter_dev_t {
43- int32_t count ;
43+ /**
44+ * Position of the motor in degrees.
45+ */
46+ int32_t position ;
47+ /**
48+ * Quadrature int pin.
49+ */
4450 pbdrv_gpio_t gpio_int ;
51+ /**
52+ * Quadrature dir pin.
53+ */
4554 pbdrv_gpio_t gpio_dir ;
55+ /**
56+ * Additional GPIO for device detection (not used).
57+ */
4658 pbdrv_gpio_t gpio_det ;
59+ /**
60+ * ADC channel for device detection.
61+ */
4762 uint8_t adc_channel ;
63+ /**
64+ * Last instantaneous ADC device detection.
65+ */
4866 lego_device_type_id_t last_type_id ;
67+ /**
68+ * Stable device detection.
69+ */
4970 lego_device_type_id_t stable_type_id ;
71+ /**
72+ * How many times the same type ID was found sequentially.
73+ */
5074 uint32_t type_id_count ;
75+ /**
76+ * The position at which the type ID detection was started.
77+ */
78+ int32_t type_id_position ;
5179};
5280
5381static pbdrv_counter_dev_t counters [] = {
5482 {
55- .count = 0 ,
83+ .position = 0 ,
5684 .gpio_int = PBDRV_GPIO_EV3_PIN (11 , 19 , 16 , 5 , 11 ),
5785 .gpio_dir = PBDRV_GPIO_EV3_PIN (1 , 15 , 12 , 0 , 4 ),
5886 .gpio_det = PBDRV_GPIO_EV3_PIN (12 , 15 , 12 , 5 , 4 ),
5987 .adc_channel = 1 ,
6088 },
6189 {
62- .count = 0 ,
90+ .position = 0 ,
6391 .gpio_int = PBDRV_GPIO_EV3_PIN (11 , 31 , 28 , 5 , 8 ),
6492 .gpio_dir = PBDRV_GPIO_EV3_PIN (5 , 27 , 24 , 2 , 9 ),
6593 .gpio_det = PBDRV_GPIO_EV3_PIN (6 , 11 , 8 , 2 , 5 ),
6694 .adc_channel = 0 ,
6795 },
6896 {
69- .count = 0 ,
97+ .position = 0 ,
7098 .gpio_int = PBDRV_GPIO_EV3_PIN (11 , 11 , 8 , 5 , 13 ),
7199 .gpio_dir = PBDRV_GPIO_EV3_PIN (7 , 7 , 4 , 3 , 14 ),
72100 .gpio_det = PBDRV_GPIO_EV3_PIN (7 , 31 , 28 , 3 , 8 ),
73101 .adc_channel = 13 ,
74102 },
75103 {
76- .count = 0 ,
104+ .position = 0 ,
77105 .gpio_int = PBDRV_GPIO_EV3_PIN (13 , 27 , 24 , 6 , 9 ),
78106 .gpio_dir = PBDRV_GPIO_EV3_PIN (5 , 31 , 28 , 2 , 8 ),
79107 .gpio_det = PBDRV_GPIO_EV3_PIN (11 , 3 , 0 , 5 , 15 ),
@@ -113,9 +141,6 @@ static bool adc_is_close(uint32_t adc, uint32_t reference) {
113141 * The original firmware uses a dynamic process to distinguish other non-motor
114142 * devices. This is not implemented here. It does not appear necessary for
115143 * motors.
116- *
117- * If we find that we occasionally get "in-between" values, we can have the
118- * adc process poll us to maintain a minium count of unchanged states.
119144 */
120145static lego_device_type_id_t pbdrv_counter_ev3_get_type (uint16_t adc ) {
121146
@@ -128,7 +153,10 @@ static lego_device_type_id_t pbdrv_counter_ev3_get_type(uint16_t adc) {
128153 }
129154
130155 if (adc_is_close (adc , ADC_EV3_LARGE_0 ) || adc_is_close (adc , ADC_EV3_LARGE_1 ) || adc_is_close (adc , ADC_NXT_LARGE_1 )) {
131- return LEGO_DEVICE_TYPE_ID_NXT_MOTOR ;
156+ // We can only detect the difference between NXT and EV3 motors 50% of
157+ // the time, depending on the optical encoder state. So always return
158+ // the same type for consistency. Their parameters are relatively close.
159+ return LEGO_DEVICE_TYPE_ID_EV3_LARGE_MOTOR ;
132160 }
133161
134162 return LEGO_DEVICE_TYPE_ID_NONE ;
@@ -140,29 +168,26 @@ static lego_device_type_id_t pbdrv_counter_ev3_get_type(uint16_t adc) {
140168/**
141169 * Updates the type of all EV3 motors based on the current ADC values.
142170 */
143- static void pbdrv_counter_ev3_update_type (void ) {
144-
145- for (uint8_t i = 0 ; i < PBIO_ARRAY_SIZE (counters ); i ++ ) {
146-
147- // Get type detected now.
148- pbdrv_counter_dev_t * dev = & counters [i ];
149- uint16_t adc = 0 ;
150- pbdrv_adc_get_ch (dev -> adc_channel , & adc );
151- lego_device_type_id_t type_id = pbdrv_counter_ev3_get_type (adc );
152-
153- // Update number of consecutive identical detections.
154- if (dev -> last_type_id == type_id ) {
155- dev -> type_id_count ++ ;
156- } else {
157- dev -> last_type_id = type_id ;
158- dev -> type_id_count = 1 ;
159- }
171+ static void pbdrv_counter_ev3_update_type (pbdrv_counter_dev_t * dev ) {
172+
173+ // Get type detected now.
174+ uint16_t adc = 0 ;
175+ pbdrv_adc_get_ch (dev -> adc_channel , & adc );
176+ lego_device_type_id_t type_id = pbdrv_counter_ev3_get_type (adc );
177+
178+ // Update number of consecutive identical detections.
179+ if (dev -> last_type_id == type_id && dev -> position == dev -> type_id_position ) {
180+ dev -> type_id_count ++ ;
181+ } else {
182+ dev -> last_type_id = type_id ;
183+ dev -> type_id_count = 1 ;
184+ dev -> type_id_position = dev -> position ;
185+ }
160186
161- // Update stable type if we have seen enough identical detections,
162- // including none detections.
163- if (dev -> type_id_count >= PBDRV_COUNTER_EV3_TYPE_MIN_STABLE_COUNT ) {
164- dev -> stable_type_id = type_id ;
165- }
187+ // Update stable type if we have seen enough identical detections,
188+ // including none detections.
189+ if (dev -> type_id_count >= PBDRV_COUNTER_EV3_TYPE_MIN_STABLE_COUNT ) {
190+ dev -> stable_type_id = type_id ;
166191 }
167192}
168193
@@ -178,7 +203,9 @@ static pbio_error_t pbdrv_counter_device_detect_process_thread(pbio_os_state_t *
178203 PBIO_OS_ASYNC_BEGIN (state );
179204
180205 for (;;) {
181- pbdrv_counter_ev3_update_type ();
206+ for (uint8_t i = 0 ; i < PBIO_ARRAY_SIZE (counters ); i ++ ) {
207+ pbdrv_counter_ev3_update_type (& counters [i ]);
208+ }
182209 PBIO_OS_AWAIT_MS (state , & timer , PBDRV_COUNTER_EV3_TYPE_LOOP_TIME );
183210 }
184211
@@ -210,8 +237,8 @@ pbio_error_t pbdrv_counter_get_angle(pbdrv_counter_dev_t *dev, int32_t *rotation
210237 return err ;
211238 }
212239
213- * millidegrees = (dev -> count % 360 ) * 1000 ;
214- * rotations = dev -> count / 360 ;
240+ * millidegrees = (dev -> position % 360 ) * 1000 ;
241+ * rotations = dev -> position / 360 ;
215242 return PBIO_SUCCESS ;
216243}
217244
@@ -234,12 +261,12 @@ static void pbdrv_counter_ev3_irq_handler(uint32_t bank_id, uint32_t bank_int_id
234261 continue ;
235262 }
236263
237- // Clear the interrupt and update the count .
264+ // Clear the interrupt and update the position .
238265 HWREG (SOC_GPIO_0_REGS + GPIO_INTSTAT ((bank_id / 2 ))) = mask ;
239266 if (pbdrv_gpio_input (& dev -> gpio_int ) ^ pbdrv_gpio_input (& dev -> gpio_dir )) {
240- dev -> count ++ ;
267+ dev -> position ++ ;
241268 } else {
242- dev -> count -- ;
269+ dev -> position -- ;
243270 }
244271 }
245272
0 commit comments