poppy_com  0.1
Poppy2.0 communication library
 All Classes Files Functions Variables Enumerations Enumerator Pages
hal.c
1 #include <util/twi.h>
2 #include <avr/interrupt.h>
3 #include "poppy-com/hal/atmega328p/hal.h"
4 #include "poppy-com/inc/i2c_slave.h"
5 
6 // I2C Master mode
7 
8 // Global variables
9 extern context_t ctx;
10 
15 void hal_init(void) {
16  // I2C settings
17  // SetPrescaler divisor
18  // Set I2C Address
19  // Enable general call
20  // Enable ACK system
21 }
22 
31 unsigned char i2c_transmit(com_state_t type) {
32  switch (type) {
33  case START:
34  // Send start condition
35  break;
36  case DATA:
37  // Send data ACK required
38  break;
39  case DATA_NACK:
40  // Send data no ACK required
41  break;
42  case STOP:
43  // Send stop condition
44  return 0;
45  }
46  // Wait the end of the transmition (here you can manage a timeout)
47  // Manage the end of IRQ
48  // Return the status
49  return (/*status*/);
50 }
51 
61 unsigned char i2cAddr(unsigned char addr, msg_dir_t dir) {
62  unsigned char status;
63  unsigned char n = 0;
64  addr = (addr << 1) | dir;
65  i2c_retry:
66  if (n++ >= MAX_TRIES) return 1;
67  status = i2c_transmit(START);
68  if ((status != TW_START) & (status != TW_REP_START)) {
69  ctx.status.master_write = TRUE;
70  return 1;
71  }
72 
73  // Send addr
74  switch (i2c_transmit(DATA)) {
75  case // ACK received
76  return 0;
77  break;
78  case // NACK received
79  case // Arbitration lost
80  goto i2c_retry;
81  break;
82  default:
83  return 1;
84  break;
85  }
86 }
87 
96 unsigned char i2cWrite(unsigned char data) {
97  if /*hardware ready*/ {
98  // Put data into the dedicated register
99  if (i2c_transmit(DATA) /*== NO_ACK*/) {
100  ctx.status.master_write = TRUE;
101  return 1;
102  }
103  } else {
104  ctx.status.master_write = TRUE;
105  return 1;
106  }
107  return 0;
108 }
109 
119 unsigned char i2cRead(unsigned char ack_enable, unsigned char *data) {
120  if (ack_enable) {
121  if (i2c_transmit(DATA) /*== NO_ACK*/) {
122  ctx.status.master_read = TRUE;
123  return 1;
124  }
125  } else {
126  if (i2c_transmit(DATA_NACK) /*== ACK*/) {
127  ctx.status.master_read = TRUE;
128  return 1;
129  }
130  }
131  *data = /*data register*/;
132  return 0;
133 }
134 
135 // I2C interrupt management
136 ISR(/*vector*/) {
137  // Test if there is really an interrupt
138  if (/*everything's good*/)
139  switch (/*status*/) {
140  // SLAVE TRANSMITTER MODE
141  case //Slave TX
142  ctx.data_cb(TX, &/*data register*/);
143  break;
144 
145  // SLAVE RECEIVER MODE
146  case /*address match*/:
147  case /*general call*/:
148  /*do your needed things*/
149  break;
150 
151  // Data has been received on SLA+W; ACK has been returned.
152  case /*data ACKed*/:
153  ctx.data_cb(RX, &/*data register*/);
154  break;
155 
156  // Data has been received on general call;ACK has been returned.
157  case /*general call data ACKed*/:
158  ctx.data_cb(RXGC, &/*data register*/);
159  break;
160 
161  // OTHER
162  case /*Error*/:
163  ctx.status.unexpected_state = TRUE;
164  ctx.data_cb = idle;
165  break;
166  case /*Stop*/:
167  ctx.data_cb = idle;
168  ctx.data_cb(END, &/*data register*/);
169  default:
170  break;
171  }
172 }
173 
181 void id_update(unsigned char id) {
182  ctx.id = id;
183  /*address register*/ = (ctx.id << 1);
184  // Write your ID on EEprom
185 }
186 
187 
197 unsigned char crc(unsigned char* data, unsigned char size) {
198  unsigned char x;
199  unsigned int crc = 0xFFFF;
200 
201  while (size--) {
202  x = crc >> 8 ^ *data++;
203  x ^= x>>4;
204  crc = (crc << 8) ^ ((unsigned int)(x << 12))
205  ^ ((unsigned int)(x <<5))
206  ^ ((unsigned int)x);
207  }
208  return (unsigned char)crc;
209 }
unsigned char id
Definition: context.h:42
status_t status
Definition: context.h:46
DATA_CB data_cb
Definition: context.h:36
msg_dir_t
Message direction enum.
Definition: poppyNetwork.h:22