// to use only with values up to a couple seconds void sleep_ms(int millisec) { sleep_ns(millisec * EXP_6); }
int bitbang_io(const bitbang_handle_st *hdl, bitbang_io_st *io) { int rc = 0; uint32_t clk = hdl->bbh_half_clk; const struct { bitbang_pin_value_en value; bitbang_clk_edge_en edge; } clks[] = { {BITBANG_PIN_HIGH, BITBANG_CLK_EDGE_FALLING}, {BITBANG_PIN_LOW, BITBANG_CLK_EDGE_RISING}, }; int clk_idx; int n_clk = 0; int n_bits = 0; const uint8_t *dout = io->bbio_dout; uint8_t *din = io->bbio_din; int bit_pos = 7; bitbang_pin_func pin_f = hdl->bbh_init.bbi_pin_f; void *context = hdl->bbh_init.bbi_context; if ((io->bbio_in_bits == 0 && io->bbio_din) || (io->bbio_in_bits > 0 && !io->bbio_din)) { rc = EINVAL; LOG_ERR(rc, "Incorrect in bits and in buffer"); goto out; } if ((io->bbio_out_bits == 0 && io->bbio_dout) || (io->bbio_out_bits > 0 && !io->bbio_dout)) { rc = EINVAL; LOG_ERR(rc, "Incorrect out bits and out buffer"); goto out; } if (io->bbio_in_bits == 0 && io->bbio_out_bits == 0) { rc = EINVAL; LOG_ERR(rc, "Both in and out bits are 0"); goto out; } if (hdl->bbh_init.bbi_clk_start == BITBANG_PIN_HIGH) { clk_idx = 0; } else { clk_idx = 1; } /* set the CLK pin start position */ pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context); /* clear the first byte of din */ if (din && io->bbio_in_bits) { memset(din, 0, (io->bbio_in_bits + 7) / 8); } do { if ((rc = sleep_ns(clk))) { goto out; } /* output first */ if (hdl->bbh_init.bbi_data_out == clks[clk_idx].edge) { if (dout && n_bits < io->bbio_out_bits) { pin_f(BITBANG_DATA_OUT, (*dout >> bit_pos) & 0x1, context); } } /* then, input */ if (hdl->bbh_init.bbi_data_in == clks[clk_idx].edge) { if (din && n_bits < io->bbio_in_bits) { *din |= (pin_f(BITBANG_DATA_IN, 0, context) & 0x1) << bit_pos; } } if (++n_clk % 2 == 0) { /* one bit for every 2 half clks */ n_bits ++; if (bit_pos == 0) { if (dout) { dout++; } if (din) { din++; } bit_pos = 7; } else { bit_pos --; } } clk_idx = 1 - clk_idx; pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context); } while (n_bits < MAX(io->bbio_in_bits, io->bbio_out_bits));
void sleep_us(int microsec) { sleep_ns(microsec * EXP_3); }
static void sleep_ms(int msecs) { sleep_ns(msecs*1000000); }