Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test quinns patch #105

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
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
19 changes: 10 additions & 9 deletions lib_i2c/src/i2c_master.xc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ static const unsigned inline compute_bus_off_ticks(
static void release_clock_and_wait(
port p_scl,
unsigned &fall_time,
unsigned delay)
unsigned delay,
static const unsigned kbits_per_second)
{
p_scl when pinseq(1) :> void;

Expand All @@ -68,7 +69,8 @@ static void release_clock_and_wait(
// executing then the clock needs to be adjusted
const int wake_up_ticks = 10;
if (time > fall_time + delay + wake_up_ticks) {
fall_time = time - delay - wake_up_ticks;
fall_time = time - compute_low_period_ticks(kbits_per_second) - wake_up_ticks;
tmr when timerafter(fall_time + delay) :> void;
}
}

Expand All @@ -89,7 +91,7 @@ static int inline high_pulse_sample(
timer tmr;
p_sda :> int _;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
release_clock_and_wait(p_scl, fall_time, (bit_time * 3) / 4);
release_clock_and_wait(p_scl, fall_time, (bit_time * 3) / 4, kbits_per_second);
p_sda :> sample_value;
fall_time = fall_time + bit_time;
tmr when timerafter(fall_time) :> void;
Expand All @@ -111,13 +113,13 @@ static void inline high_pulse(

timer tmr;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
release_clock_and_wait(p_scl, fall_time, (bit_time * 3) / 4);
release_clock_and_wait(p_scl, fall_time, (bit_time * 3) / 4, kbits_per_second);
fall_time = fall_time + bit_time;
tmr when timerafter(fall_time) :> void;
p_scl <: 0;
}

/** Output a start bit. The function returns the 'fall time' i.e. the
/** Output a start bit. The function returns/updates the 'last SCL falling edge time' i.e. the
* reference clock time when the SCL line transitions to low.
*/
static void start_bit(
Expand All @@ -132,9 +134,8 @@ static void start_bit(
timer tmr;

if (!stopped) {
fall_time += compute_low_period_ticks(kbits_per_second);
tmr when timerafter(fall_time) :> fall_time;
release_clock_and_wait(p_scl, fall_time, compute_bus_off_ticks(kbits_per_second));
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
release_clock_and_wait(p_scl, fall_time, bit_time, kbits_per_second);
}

// Drive SDA low
Expand All @@ -160,7 +161,7 @@ static void stop_bit(
timer tmr;
p_sda <: 0;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
release_clock_and_wait(p_scl, fall_time, bit_time);
release_clock_and_wait(p_scl, fall_time, bit_time, kbits_per_second);
p_sda :> void;
delay_ticks(compute_bus_off_ticks(kbits_per_second));
}
Expand Down
23 changes: 12 additions & 11 deletions lib_i2c/src/i2c_master_single_port.xc
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ static const unsigned inline compute_bus_off_ticks(
/** Reads back the SCL line, waiting until it goes high (in
* case the slave is clock stretching). It is assumed that the clock
* line has been release (driven high) before calling this function.
* Since the line going high may be delayed, the fall_time value may
* need to be adjusted
* Since the line going high may be delayed, the fall_time
* value may need to be adjusted
*/
static void wait_for_clock_high(
port p_i2c,
static const unsigned scl_bit_position,
unsigned &fall_time,
unsigned delay)
unsigned delay,
static const unsigned kbits_per_second)
{
const unsigned SCL_HIGH = BIT_MASK(scl_bit_position);

Expand All @@ -81,7 +82,8 @@ static void wait_for_clock_high(
// executing then the clock needs to be adjusted
const int wake_up_ticks = 10;
if (time > fall_time + delay + wake_up_ticks) {
fall_time = time - delay - wake_up_ticks;
fall_time = time - compute_low_period_ticks(kbits_per_second) - wake_up_ticks;
tmr when timerafter(fall_time + delay) :> void;
}
}

Expand All @@ -103,7 +105,7 @@ static void high_pulse_drive(
p_i2c <: SCL_LOW | sdaValue | other_bits_mask;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
p_i2c <: SCL_HIGH | sdaValue | other_bits_mask;
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4);
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4, kbits_per_second);
fall_time = fall_time + bit_time;
tmr when timerafter(fall_time) :> void;
p_i2c <: SCL_LOW | sdaValue | other_bits_mask;
Expand All @@ -126,7 +128,7 @@ static int high_pulse_sample(
p_i2c <: SCL_LOW | SDA_HIGH | other_bits_mask;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
p_i2c <: SCL_HIGH | SDA_HIGH | other_bits_mask;
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4);
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4, kbits_per_second);

int sample_value = peek(p_i2c);
if (sample_value & SDA_HIGH)
Expand Down Expand Up @@ -157,10 +159,9 @@ static void start_bit(
timer tmr;

if (!stopped) {
fall_time += compute_low_period_ticks(kbits_per_second);
tmr when timerafter(fall_time) :> fall_time;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
p_i2c <: SCL_HIGH | SDA_HIGH | other_bits_mask;
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, compute_bus_off_ticks(kbits_per_second));
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, bit_time, kbits_per_second);
}

p_i2c <: SCL_HIGH | SDA_LOW | other_bits_mask;
Expand All @@ -186,7 +187,7 @@ static void stop_bit(
p_i2c <: SCL_LOW | SDA_LOW | other_bits_mask;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
p_i2c <: SCL_HIGH | SDA_LOW | other_bits_mask;
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, bit_time);
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, bit_time, kbits_per_second);
p_i2c <: SCL_HIGH | SDA_HIGH | other_bits_mask;
delay_ticks(compute_bus_off_ticks(kbits_per_second));
}
Expand Down Expand Up @@ -256,7 +257,7 @@ void i2c_master_single_port(
p_i2c <: SCL_LOW | sda | other_bits_mask;
tmr when timerafter(fall_time + compute_low_period_ticks(kbits_per_second)) :> void;
p_i2c <: SCL_HIGH | sda | other_bits_mask;
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4);
wait_for_clock_high(p_i2c, scl_bit_position, fall_time, (bit_time * 3) / 4, kbits_per_second);
fall_time = fall_time + bit_time;
tmr when timerafter(fall_time) :> void;

Expand Down