Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions src/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,9 @@ static void setup_clock(void)
*
* - Systick priority to 1 with SCB.
* - USART3 with priority 2 with NVIC.
* - TIM1_UP with priority 0.
*
* Interruptions enabled:
*
* - TIM1 Update interrupt.
* - USART3 interrupt.
*
* @note The priority levels are assigned on steps of 16 because the processor
Expand All @@ -77,11 +75,9 @@ static void setup_clock(void)
*/
static void setup_exceptions(void)
{
nvic_set_priority(NVIC_TIM1_UP_IRQ, 0);
nvic_set_priority(NVIC_SYSTICK_IRQ, PRIORITY_FACTOR * 1);
nvic_set_priority(NVIC_USART3_IRQ, PRIORITY_FACTOR * 2);

nvic_enable_irq(NVIC_TIM1_UP_IRQ);
nvic_enable_irq(NVIC_USART3_IRQ);
}

Expand Down Expand Up @@ -406,40 +402,6 @@ static void setup_adc2(void)
start_adc(ADC2);
}

/**
* @brief TIM1 setup.
*
* The TIM1 generates an update event interruption that invokes the
* function tim1_up_isr.
*
* - Set TIM1 default values.
* - Configure the base time (no clock division ratio, no aligned mode,
* direction up).
* - Set clock division, prescaler and period parameters to get an update
* event with a frequency of 16 KHz. 16 interruptions by ms, 4 sensors with
* 4 states.
*
* \f$frequency = \frac{timerclock}{(preescaler + 1)(period + 1)}\f$
*
* - Enable the TIM1.
* - Enable the interruption of type update event on the TIM1.
*
* @note The TIM1 is conected to the APB2 prescaler.
*
* @see Reference manual (RM0008) "Advanced-control timers"
*/
static void setup_timer1(void)
{
rcc_periph_reset_pulse(RST_TIM1);
timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE,
TIM_CR1_DIR_UP);
timer_set_clock_division(TIM1, 0x00);
timer_set_prescaler(TIM1, (rcc_apb2_frequency / 160000 - 1));
timer_set_period(TIM1, 10 - 1);
timer_enable_counter(TIM1);
timer_enable_irq(TIM1, TIM_DIER_UIE);
}

/**
* @brief Execute all setup functions.
*/
Expand All @@ -455,6 +417,4 @@ void setup(void)
setup_pwm();
setup_mpu();
setup_systick();
setup_timer1();
setup_adc1();
}
96 changes: 31 additions & 65 deletions src/target/detection.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#define SIDE_WALL_DETECTION (CELL_DIMENSION * 0.90)
#define FRONT_WALL_DETECTION (CELL_DIMENSION * 1.5)
#define SIDE_CALIBRATION_READINGS 20
#define SENSORS_SM_TICKS 4
#define LOG_CONVERSION_TABLE_STEP 4
#define LOG_CONVERSION_TABLE_SIZE (ADC_RESOLUTION / LOG_CONVERSION_TABLE_STEP)

Expand Down Expand Up @@ -190,86 +189,52 @@ static void set_emitter_off(uint8_t emitter)
}

/**
* @brief State machine to manage the sensors activation and deactivation
* states and readings.
*
* In order to get accurate distance values, the phototransistor's output
* will be read with the infrared emitter sensors powered on and powered
* off. Besides, to avoid undesired interactions between different emitters and
* phototranistors, the reads will be done one by one.
*
* The battery voltage is also read on the state 1.
*
* - State 1 (first because the emitter is OFF on start):
* -# Save phototranistors sensors (ADC1) from emitter OFF and
* power ON the emitter.
* - State 2:
* -# Start the phototranistors sensors (ADC1) read.
* - State 3:
* -# Save phototranistors sensors (ADC1) from emitter ON and
* power OFF the emitter.
* - State 4:
* -# Start the phototranistors sensors (ADC1) read.
* @brief Get sensors values with emitter on and off.
*/
static void sm_emitter_adc(void)
void get_sensors_raw(uint16_t *off, uint16_t *on)
{
static uint8_t emitter_status = 1;
static uint8_t sensor_index = SENSOR_SIDE_LEFT_ID;
uint8_t i = 0;

switch (emitter_status) {
case 1:
sensors_off[sensor_index] =
adc_read_injected(ADC1, (sensor_index + 1));
set_emitter_on(sensor_index);
emitter_status = 2;
break;
case 2:
adc_start_conversion_injected(ADC1);
emitter_status = 3;
break;
case 3:
sensors_on[sensor_index] =
adc_read_injected(ADC1, (sensor_index + 1));
set_emitter_off(sensor_index);
emitter_status = 4;
break;
case 4:
adc_start_conversion_injected(ADC1);
emitter_status = 1;
if (sensor_index == (NUM_SENSOR - 1))
sensor_index = 0;
else
sensor_index++;
break;
default:
break;
for (i = 0; i < NUM_SENSOR; i++) {
off[i] = sensors_off[i];
on[i] = sensors_on[i];
}
}

/**
* @brief TIM1 interruption routine.
*
* - Manage the update event interruption flag.
* - Trigger state machine to manage sensors.
* @brief Start and wait for complete injection of sensor readings.
*/
void tim1_up_isr(void)
static void inject_readings(void)
{
if (timer_get_flag(TIM1, TIM_SR_UIF)) {
timer_clear_flag(TIM1, TIM_SR_UIF);
sm_emitter_adc();
}
adc_start_conversion_injected(ADC1);
while (!(adc_eoc_injected(ADC1)))
;
// Clear injected end of conversion
ADC_SR(ADC1) &= ~ADC_SR_JEOC;
}

/**
* @brief Get sensors values with emitter on and off.
* @brief Update the sensors raw readings.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expand the description

*/
void get_sensors_raw(uint16_t *off, uint16_t *on)
static void update_raw_readings(void)
{
uint8_t i = 0;

for (i = 0; i < NUM_SENSOR; i++) {
off[i] = sensors_off[i];
on[i] = sensors_on[i];
inject_readings();
sensors_off[i] = adc_read_injected(ADC1, (i + 1));
}
for (i = 0; i < NUM_SENSOR; i++) {
inject_readings();
sensors_off[i] = adc_read_injected(ADC1, (i + 1));
}

for (i = 0; i < NUM_SENSOR; i++) {
set_emitter_on(i);
sleep_us(10);
inject_readings();
sensors_on[i] = adc_read_injected(ADC1, (i + 1));
set_emitter_off(i);
}
}

Expand Down Expand Up @@ -305,6 +270,7 @@ void update_distance_readings(void)
{
uint8_t i = 0;

update_raw_readings();
for (i = 0; i < NUM_SENSOR; i++) {
distance[i] = (sensors_calibration_a[i] /
raw_log(sensors_on[i], sensors_off[i]) -
Expand Down Expand Up @@ -447,7 +413,7 @@ void side_sensors_calibration(void)
for (i = 0; i < SIDE_CALIBRATION_READINGS; i++) {
left_temp += distance[SENSOR_SIDE_LEFT_ID];
right_temp += distance[SENSOR_SIDE_RIGHT_ID];
sleep_ticks(SENSORS_SM_TICKS);
sleep_ticks(2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you change it to 2? Coudl you add an explicative macro?

Copy link
Member Author

@Peque Peque Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you call it? It is just some small delay in between readings, it could be any other number really.

I could create a SIDE_CALIBRATION_READINGS_DELAY_TICKS but looks huge just for one use and it really is not important. Does it hurt too much in your eyes? 😂

}
calibration_factor[SENSOR_SIDE_LEFT_ID] +=
(left_temp / SIDE_CALIBRATION_READINGS) - MIDDLE_MAZE_DISTANCE;
Expand Down