Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 1 | #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 Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 10 | // TIM11.1 on PB9, aka digital input 6. |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 11 | static volatile uint32_t ultrasonic_pulse_length = 0; |
| 12 | |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 13 | typedef struct { |
| 14 | uint32_t posedges, negedges; |
| 15 | } EdgeCounts; |
| 16 | |
| 17 | #define COPY_EDGE_COUNTS(edge_counts, hall_effect_edges) \ |
Brian Silverman | 258349f | 2014-02-17 21:38:53 -0800 | [diff] [blame] | 18 | hall_effect_edges.posedges = edge_counts.negedges; \ |
| 19 | hall_effect_edges.negedges = edge_counts.posedges; |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 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 | |
| 34 | static volatile struct { |
| 35 | int32_t posedge, negedge; |
| 36 | } pusher_distal_captures, pusher_proximal_captures; |
| 37 | |
Brian Silverman | 258349f | 2014-02-17 21:38:53 -0800 | [diff] [blame] | 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.negedge; \ |
| 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); \ |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 60 | } |
| 61 | |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 62 | typedef struct { |
| 63 | int32_t posedge, negedge; |
| 64 | EdgeCounts front, calibration, back; |
| 65 | } SingleClawCaptures; |
| 66 | |
| 67 | #define CLAW(front_num, calibration_num, back_num, name, encoder) \ |
| 68 | static volatile SingleClawCaptures name = {0, 0, {0, 0}, {0, 0}, {0, 0}}; \ |
| 69 | HALL_CAPTURE(front_num, name.front, encoder, name); \ |
| 70 | HALL_CAPTURE(calibration_num, name.calibration, encoder, name); \ |
| 71 | HALL_CAPTURE(back_num, name.back, encoder, name); \ |
| 72 | static inline void fill_##name##_values(struct DataStruct *packet) { \ |
| 73 | digital_capture_disable(front_num); \ |
| 74 | digital_capture_disable(calibration_num); \ |
| 75 | digital_capture_disable(back_num); \ |
| 76 | packet->main.name.position = encoder_read(encoder); \ |
Brian Silverman | 258349f | 2014-02-17 21:38:53 -0800 | [diff] [blame] | 77 | packet->main.name.negedge_position = name.posedge; \ |
| 78 | packet->main.name.posedge_position = name.negedge; \ |
| 79 | packet->main.name.bools.front = !digital_read(front_num); \ |
| 80 | packet->main.name.bools.calibration = !digital_read(calibration_num); \ |
| 81 | packet->main.name.bools.back = !digital_read(back_num); \ |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 82 | COPY_EDGE_COUNTS(name.front, packet->main.name.front); \ |
| 83 | COPY_EDGE_COUNTS(name.calibration, packet->main.name.calibration); \ |
| 84 | COPY_EDGE_COUNTS(name.back, packet->main.name.back); \ |
| 85 | digital_capture_enable(front_num); \ |
| 86 | digital_capture_enable(calibration_num); \ |
| 87 | digital_capture_enable(back_num); \ |
| 88 | } |
| 89 | |
Brian Silverman | 258349f | 2014-02-17 21:38:53 -0800 | [diff] [blame] | 90 | CLAW(1, 2, 0, top_claw, 2); |
| 91 | CLAW(10, 11, 9, bottom_claw, 7); |
Brian Silverman | 30a65dd | 2014-02-17 17:32:14 -0800 | [diff] [blame] | 92 | SHOOTER(7, 5, 4, 8, 0) |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 93 | |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 94 | void TIM1_TRG_COM_TIM11_IRQHandler(void) { |
| 95 | TIM11->SR = ~TIM_SR_CC1IF; |
Brian Silverman | a747734 | 2014-02-26 21:35:55 -0800 | [diff] [blame] | 96 | if (digital_read(6)) { |
| 97 | TIM11->EGR = TIM_EGR_UG; |
| 98 | } else { |
| 99 | ultrasonic_pulse_length = TIM11->CCR1; |
| 100 | } |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void robot_init(void) { |
Brian Silverman | c47182f | 2014-02-16 21:43:36 -0800 | [diff] [blame] | 104 | gpio_setup_alt(GPIOB, 9, 3); |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 105 | RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; |
Brian Silverman | 5f4bfe0 | 2014-02-18 00:57:53 -0800 | [diff] [blame] | 106 | TIM11->CR1 = TIM_CR1_URS; |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 107 | TIM11->DIER = TIM_DIER_CC1IE; |
| 108 | TIM11->CCMR1 = TIM_CCMR1_CC1S_0 /* input pin 1 -> timer input 1 */; |
Brian Silverman | a747734 | 2014-02-26 21:35:55 -0800 | [diff] [blame] | 109 | TIM11->CCER = TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC1E; |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 110 | TIM11->EGR = TIM_EGR_UG; |
| 111 | TIM11->PSC = 1200 - 1; // 100kHZ timer |
| 112 | TIM11->CR1 |= TIM_CR1_CEN; |
| 113 | NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 3); |
| 114 | NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn); |
| 115 | } |
| 116 | |
| 117 | void robot_fill_packet(struct DataStruct *packet) { |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 118 | packet->main.left_drive = encoder_read(6); |
| 119 | packet->main.right_drive = encoder_read(5); |
Austin Schuh | 809c256 | 2014-03-02 11:50:19 -0800 | [diff] [blame] | 120 | packet->main.low_left_drive_hall = analog_get(7); |
| 121 | packet->main.low_right_drive_hall = analog_get(0); |
| 122 | packet->main.high_left_drive_hall = analog_get(6); |
| 123 | packet->main.high_right_drive_hall = analog_get(1); |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 124 | |
Brian Silverman | 5665832 | 2014-03-22 16:57:22 -0700 | [diff] [blame] | 125 | packet->main.battery_voltage_high = analog_get(5); |
| 126 | packet->main.battery_voltage_low = analog_get(3); |
| 127 | |
Brian Silverman | fac5c29 | 2014-02-17 15:26:57 -0800 | [diff] [blame] | 128 | packet->main.ultrasonic_pulse_length = ultrasonic_pulse_length; |
| 129 | |
| 130 | fill_top_claw_values(packet); |
| 131 | fill_bottom_claw_values(packet); |
Brian Silverman | 258349f | 2014-02-17 21:38:53 -0800 | [diff] [blame] | 132 | fill_shooter_values(packet); |
Brian Silverman | 7867026 | 2014-01-17 23:40:47 -0800 | [diff] [blame] | 133 | } |