summaryrefslogtreecommitdiff
path: root/n/avr
diff options
context:
space:
mode:
Diffstat (limited to 'n/avr')
-rw-r--r--n/avr/twi-slave/twi_slave.c75
1 files changed, 66 insertions, 9 deletions
diff --git a/n/avr/twi-slave/twi_slave.c b/n/avr/twi-slave/twi_slave.c
index f95c4c4..4aa03f9 100644
--- a/n/avr/twi-slave/twi_slave.c
+++ b/n/avr/twi-slave/twi_slave.c
@@ -29,17 +29,28 @@
#include <avr/twi.h>
#include <avr/signal.h>
-//TODO acces exclusif au buffer
-
static volatile uint8_t twi_rcpt_tail;
static volatile uint8_t send_idx;
static volatile uint8_t data_ready;
-static volatile uint8_t buf_rcpt[SIZE_BUF_RCPT];
-static volatile uint8_t buf_send[SIZE_BUF_SEND];
+static volatile uint8_t buf_rcpt1[SIZE_BUF_RCPT];
+static volatile uint8_t buf_rcpt2[SIZE_BUF_RCPT];
+static volatile uint8_t buf_send1[SIZE_BUF_SEND];
+static volatile uint8_t buf_send2[SIZE_BUF_SEND];
+static volatile uint8_t *buf_send_sys, *buf_send_user;
+static volatile uint8_t *buf_rcpt_sys, *buf_rcpt_user;
+static volatile int8_t send_switch, rcpt_switch;
+static volatile int8_t state;
void
twi_init (uint8_t addr)
{
+ state = 0;
+ send_switch = 0;
+ rcpt_switch = 0;
+ buf_send_sys = buf_send1;
+ buf_send_user = buf_send2;
+ buf_rcpt_sys = buf_rcpt1;
+ buf_rcpt_user = buf_rcpt2;
TWAR = addr;
TWSR = 0x00;
TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
@@ -55,12 +66,13 @@ SIGNAL (SIG_2WIRE_SERIAL)
/* START + SLA|W + ACK */
case TW_ST_SLA_ACK:
case TW_ST_ARB_LOST_SLA_ACK:
+ state = 1;
rs232_putc ('a');
send_idx = 0;
/* no break */
case TW_ST_DATA_ACK:
rs232_putc ('b');
- TWDR = buf_send[send_idx++];
+ TWDR = buf_send_sys[send_idx++];
if (SIZE_BUF_SEND == send_idx)
TWCR &= ~_BV(TWEA);
break;
@@ -76,6 +88,7 @@ SIGNAL (SIG_2WIRE_SERIAL)
case TW_SR_GCALL_ACK:
case TW_SR_ARB_LOST_GCALL_ACK:
rs232_putc ('z');
+ state = 2;
data_ready = 0;
twi_rcpt_tail = 0;
if (SIZE_BUF_RCPT == 1)
@@ -85,7 +98,7 @@ SIGNAL (SIG_2WIRE_SERIAL)
case TW_SR_DATA_ACK:
case TW_SR_GCALL_DATA_ACK:
rs232_putc ('y');
- buf_rcpt[twi_rcpt_tail++] = TWDR;
+ buf_rcpt_sys[twi_rcpt_tail++] = TWDR;
if (SIZE_BUF_RCPT - twi_rcpt_tail == 1)
TWCR &= ~_BV(TWEA);
break;
@@ -93,12 +106,37 @@ SIGNAL (SIG_2WIRE_SERIAL)
case TW_SR_DATA_NACK:
case TW_SR_GCALL_DATA_NACK:
rs232_putc ('x');
- buf_rcpt[twi_rcpt_tail++] = TWDR;
+ buf_rcpt_sys[twi_rcpt_tail++] = TWDR;
/* no break */
/* STOP */
case TW_SR_STOP:
rs232_putc ('w');
data_ready = 1;
+ if (state == 1) /* send */
+ {
+ if (send_switch == 1)
+ {
+ volatile uint8_t *tmp;
+ /* Thibault paye son coup */
+ tmp = buf_send_user;
+ buf_send_user = buf_send_sys;
+ buf_send_sys = tmp;
+ send_switch = 0;
+ }
+ }
+ else if (state == 2)
+ {
+ if (!rcpt_switch)
+ {
+ volatile uint8_t *tmp;
+ tmp = buf_rcpt_user;
+ buf_rcpt_user = buf_rcpt_sys;
+ buf_rcpt_sys = tmp;
+ }
+ else
+ rcpt_switch = 1;
+ }
+ state = 0;
break;
}
TWCR |= _BV(TWINT);
@@ -109,11 +147,20 @@ SIGNAL (SIG_2WIRE_SERIAL)
uint8_t
twi_poll (uint8_t buf[], uint8_t size)
{
+ if (rcpt_switch)
+ {
+ volatile uint8_t *tmp;
+ tmp = buf_rcpt_user;
+ buf_rcpt_user = buf_rcpt_sys;
+ buf_rcpt_sys = tmp;
+ rcpt_switch = 0;
+ }
if (data_ready)
{
+ rcpt_switch = 1;
data_ready = 0;
while (size --)
- buf[size] = buf_rcpt[size];
+ buf[size] = buf_rcpt_user[size];
TWCR |= _BV (TWEA);
return 1;
}
@@ -124,7 +171,17 @@ twi_poll (uint8_t buf[], uint8_t size)
void
twi_update (uint8_t buf[], uint8_t size)
{
+ volatile uint8_t *tmp;
while (size --)
- buf_send[size] = buf[size];
+ buf_send_user[size] = buf[size];
+ /* si pas occupé on swap les pointeurs */
+ if (!state)
+ {
+ tmp = buf_send_user;
+ buf_send_user = buf_send_sys;
+ buf_send_sys = tmp;
+ }
+ else
+ send_switch = 1;
}