Skip to content

Commit

Permalink
ICSP fast read and write functions for slightly better performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
eerimoq committed Sep 8, 2018
1 parent 81e066b commit f696dd7
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 11 deletions.
118 changes: 107 additions & 11 deletions src/drivers/network/icsp_soft.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ static inline int clock_pulse(struct icsp_soft_driver_t *self_p)
return (0);
}

static inline int clock_bit(struct icsp_soft_driver_t *self_p)
{
pin_device_write_low(self_p->pged_p);
clock_pulse(self_p);
clock_pulse(self_p);
clock_pulse(self_p);
clock_pulse(self_p);

return (0);
}

static inline int clock_bit_in(struct icsp_soft_driver_t *self_p)
{
int tdo;
Expand Down Expand Up @@ -209,6 +220,24 @@ static int send_key(struct icsp_soft_driver_t *self_p)
return (0);
}

static void wait_for_pracc_set(struct icsp_soft_driver_t *self_p)
{
int pracc;

move_to_capture_dr_from_idle(self_p);

/* PrACC must be 1 for a successful transfer. */
while (1) {
pracc = clock_bit_in(self_p);

if (pracc == 1) {
break;
}

move_to_capture_dr_from_shift_dr(self_p);
}
}

int icsp_soft_module_init(void)
{
return (0);
Expand Down Expand Up @@ -341,25 +370,92 @@ int icsp_soft_fast_data_transfer(struct icsp_soft_driver_t *self_p,
ASSERTN(self_p != NULL, EINVAL);

int value;
int pracc;

move_to_capture_dr_from_idle(self_p);
wait_for_pracc_set(self_p);

/* PrACC must be 1 for a successful transfer. */
while (1) {
pracc = clock_bit_in(self_p);
/* First read bit in the data transfer. */
value = clock_bit_in(self_p);

if (pracc == 1) {
break;
}
return (transfer(self_p, rxbuf_p, txbuf_p, number_of_bits, value));
}

move_to_capture_dr_from_shift_dr(self_p);
int icsp_soft_fast_data_read(struct icsp_soft_driver_t *self_p,
uint32_t *data_p)
{
ASSERTN(self_p != NULL, EINVAL);

size_t i;

wait_for_pracc_set(self_p);

/* First read bit in the data transfer. */
*data_p = clock_bit_in(self_p);

for (i = 1; i < 32; i++) {
/* TDI. */
clock_pulse(self_p);

/* TMS. */
clock_pulse(self_p);

/* TDO. */
clock_pulse(self_p);

pin_device_set_mode(self_p->pged_p, PIN_INPUT);
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
*data_p |= (pin_device_read(self_p->pged_p) << i);
pin_device_set_mode(self_p->pged_p, PIN_OUTPUT);

clock_pulse(self_p);
}

clock_bit_tms(self_p, 1);

return (move_to_idle_from_shift(self_p));
}

int icsp_soft_fast_data_write(struct icsp_soft_driver_t *self_p,
uint32_t data)
{
ASSERTN(self_p != NULL, EINVAL);

size_t i;

wait_for_pracc_set(self_p);

/* First read bit in the data transfer. */
value = clock_bit_in(self_p);
clock_bit(self_p);

return (transfer(self_p, rxbuf_p, txbuf_p, number_of_bits, value));
for (i = 0; i < 31; i++) {
/* TDI. */
pin_device_write(self_p->pged_p, data & 1);
data >>= 1;
clock_pulse(self_p);

/* TMS. */
pin_device_write_low(self_p->pged_p);
clock_pulse(self_p);

/* TDO. */
clock_pulse(self_p);
clock_pulse(self_p);
}

/* TDI. */
pin_device_write(self_p->pged_p, data & 1);
clock_pulse(self_p);

/* TMS. */
pin_device_write_high(self_p->pged_p);
clock_pulse(self_p);

/* TDO. */
clock_pulse(self_p);
clock_pulse(self_p);

return (move_to_idle_from_shift(self_p));
}

int icsp_soft_make_transition(struct icsp_soft_driver_t *self_p,
Expand Down
22 changes: 22 additions & 0 deletions src/drivers/network/icsp_soft.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ int icsp_soft_fast_data_transfer(struct icsp_soft_driver_t *self_p,
const void *txbuf_p,
size_t number_of_bits);

/**
* Fast read data from given ICSP device.
*
* @param[in] self_p Initialized driver object.
* @param[out] data_p Read data.
*
* @return zero(0) or negative error code.
*/
int icsp_soft_fast_data_read(struct icsp_soft_driver_t *self_p,
uint32_t *data_p);

/**
* Fast write given data to the ICSP device.
*
* @param[in] self_p Initialized driver object.
* @param[in] data Dat ato write.
*
* @return zero(0) or negative error code.
*/
int icsp_soft_fast_data_write(struct icsp_soft_driver_t *self_p,
uint32_t data);

/**
* Make given transition in the ICSP TAP controller state machine.
*
Expand Down

0 comments on commit f696dd7

Please sign in to comment.