blob: 5c51fe88c4fc1ca10f7b869c820046388d3b890b [file] [log] [blame]
Brian Silverman78670262014-01-17 23:40:47 -08001#include "cape/robot.h"
2
3#include <STM32F2XX.h>
4
5#include "cape/encoder.h"
6#include "cape/analog.h"
7#include "cape/digital.h"
8#include "cape/util.h"
9
Brian Silvermanfac5c292014-02-17 15:26:57 -080010// TIM11.1 on PB9, aka digital input 6.
Brian Silverman78670262014-01-17 23:40:47 -080011static volatile uint32_t ultrasonic_pulse_length = 0;
12
Brian Silvermanfac5c292014-02-17 15:26:57 -080013typedef struct {
14 uint32_t posedges, negedges;
15} EdgeCounts;
16
17#define COPY_EDGE_COUNTS(edge_counts, hall_effect_edges) \
18 hall_effect_edges.posedges = edge_counts.posedges; \
19 hall_effect_edges.negedges = edge_counts.negedges;
20
21#define HALL_CAPTURE(num, edges, encoder, capture) \
22 void digital_capture_##num##P(void) { \
23 ++edges.posedges; \
24 capture.posedge = encoder_read(encoder); \
25 } \
26 void digital_capture_##num##N(void) { \
27 ++edges.negedges; \
28 capture.negedge = encoder_read(encoder); \
29 }
30#define HALL_CAPTURE_DECL(num, edges, encoder, capture) \
31 static volatile EdgeCounts edges = {0, 0}; \
32 HALL_CAPTURE(num, edges, encoder, capture)
33
34static volatile struct {
35 int32_t posedge, negedge;
36} pusher_distal_captures, pusher_proximal_captures;
37
38#define SHOOTER(plunger_num, pusher_distal_num, pusher_proximal_num, \
39 latch_num, encoder) \
40 HALL_CAPTURE_DECL(pusher_distal_num, pusher_distal, encoder, \
41 pusher_distal_captures); \
42 HALL_CAPTURE_DECL(pusher_proximal_num, pusher_proximal, encoder, \
43 pusher_proximal_captures); \
44 static inline void fill_shooter_values(struct DataStruct *packet) { \
45 digital_capture_disable(pusher_distal_num); \
46 digital_capture_disable(pusher_proximal_num); \
47 packet->main.shooter_position = encoder_read(encoder); \
48 packet->main.pusher_distal_posedge_position = \
49 pusher_distal_captures.posedge; \
50 packet->main.pusher_proximal_posedge_position = \
51 pusher_proximal_captures.negedge; \
52 packet->main.bools.pusher_distal = digital_read(pusher_distal_num); \
53 packet->main.bools.pusher_proximal = digital_read(pusher_proximal_num); \
54 COPY_EDGE_COUNTS(pusher_distal, packet->main.pusher_distal); \
55 COPY_EDGE_COUNTS(pusher_proximal, packet->main.pusher_proximal); \
56 digital_capture_enable(pusher_distal_num); \
57 digital_capture_enable(pusher_proximal_num); \
58 packet->main.bools.plunger = digital_read(plunger_num); \
59 packet->main.bools.latch = digital_read(latch_num); \
60 }
61
62SHOOTER(0, 1, 2, 3, 0)
63
64typedef struct {
65 int32_t posedge, negedge;
66 EdgeCounts front, calibration, back;
67} SingleClawCaptures;
68
69#define CLAW(front_num, calibration_num, back_num, name, encoder) \
70 static volatile SingleClawCaptures name = {0, 0, {0, 0}, {0, 0}, {0, 0}}; \
71 HALL_CAPTURE(front_num, name.front, encoder, name); \
72 HALL_CAPTURE(calibration_num, name.calibration, encoder, name); \
73 HALL_CAPTURE(back_num, name.back, encoder, name); \
74 static inline void fill_##name##_values(struct DataStruct *packet) { \
75 digital_capture_disable(front_num); \
76 digital_capture_disable(calibration_num); \
77 digital_capture_disable(back_num); \
78 packet->main.name.position = encoder_read(encoder); \
79 packet->main.name.posedge_position = name.posedge; \
80 packet->main.name.negedge_position = name.negedge; \
81 packet->main.name.bools.front = digital_read(front_num); \
82 packet->main.name.bools.calibration = digital_read(calibration_num); \
83 packet->main.name.bools.back = digital_read(back_num); \
84 COPY_EDGE_COUNTS(name.front, packet->main.name.front); \
85 COPY_EDGE_COUNTS(name.calibration, packet->main.name.calibration); \
86 COPY_EDGE_COUNTS(name.back, packet->main.name.back); \
87 digital_capture_enable(front_num); \
88 digital_capture_enable(calibration_num); \
89 digital_capture_enable(back_num); \
90 }
91
92CLAW(4, 5, 7, top_claw, 2);
93CLAW(8, 9, 10, bottom_claw, 7);
94
Brian Silverman78670262014-01-17 23:40:47 -080095void TIM1_TRG_COM_TIM11_IRQHandler(void) {
96 TIM11->SR = ~TIM_SR_CC1IF;
97 ultrasonic_pulse_length = TIM11->CCR1;
98}
99
100void robot_init(void) {
Brian Silvermanc47182f2014-02-16 21:43:36 -0800101 gpio_setup_alt(GPIOB, 9, 3);
Brian Silverman78670262014-01-17 23:40:47 -0800102 RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
103 TIM11->CR1 = TIM_CR1_URS;
104 TIM11->SMCR = 5 << 4 /* TI1 */ |
105 4 << 0 /* reset and start on edge */;
106 TIM11->DIER = TIM_DIER_CC1IE;
107 TIM11->CCMR1 = TIM_CCMR1_CC1S_0 /* input pin 1 -> timer input 1 */;
108 TIM11->CCER = TIM_CCER_CC1P /* go on falling edge */;
109 TIM11->EGR = TIM_EGR_UG;
110 TIM11->PSC = 1200 - 1; // 100kHZ timer
111 TIM11->CR1 |= TIM_CR1_CEN;
112 NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 3);
113 NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
114}
115
116void robot_fill_packet(struct DataStruct *packet) {
Brian Silvermanfac5c292014-02-17 15:26:57 -0800117 packet->main.left_drive = encoder_read(6);
118 packet->main.right_drive = encoder_read(5);
119 packet->main.left_drive_hall = analog_get(0);
120 packet->main.right_drive_hall = analog_get(1);
121
122 packet->main.ultrasonic_pulse_length = ultrasonic_pulse_length;
123
124 fill_top_claw_values(packet);
125 fill_bottom_claw_values(packet);
Brian Silverman78670262014-01-17 23:40:47 -0800126}