Hanna
Sourcecode Batteriemanagementsystem
twi_master_driver.c
gehe zur Dokumentation dieser Datei
1 
68 /*
69  * twi_master_driver.c
70  *
71  * @date 01.09.2013 10:45:50
72  * Author: max
73  *
74  *
75  * Version : $Revision: 351 $
76  * Letzte Ă„nderung: $Date: 2016-03-19 23:27:55 +0100 (Sa, 19 Mrz 2016) $
77  * von : $Author: svn_user $
78  *
79  */
80 
81 #include <stdbool.h>
82 #include <stdio.h>
83 #include <avr/io.h>
84 #include "twi_master_driver.h"
85 
86 #ifndef F_CPU
87 #define F_CPU 32000000
88 #endif
89 
90 #include <util/delay.h>
91 
103 void TWI_MasterInit ( TWI_Master_t *twi, TWI_t *module, TWI_MASTER_INTLVL_t intLevel, uint8_t baudRateRegisterSetting )
104 {
105  twi->interface = module;
106  twi->interface->MASTER.CTRLA = intLevel | TWI_MASTER_RIEN_bm | TWI_MASTER_WIEN_bm | TWI_MASTER_ENABLE_bm;
107  twi->interface->MASTER.BAUD = baudRateRegisterSetting;
108  twi->interface->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
109 }
110 
123 TWI_MASTER_BUSSTATE_t TWI_MasterState ( TWI_Master_t *twi )
124 {
125  TWI_MASTER_BUSSTATE_t twi_status;
126  twi_status = (TWI_MASTER_BUSSTATE_t) (twi->interface->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm);
127  return twi_status;
128 }
129 
141 {
142  bool twi_status = (twi->status & TWIM_STATUS_READY);
143  return twi_status;
144 }
145 
158 bool TWI_MasterWrite ( TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite )
159 {
160  bool twi_status = TWI_MasterWriteRead ( twi, address, writeData, bytesToWrite, 0 );
161  while ( !(twi->status == TWIM_STATUS_READY) )
162  {
163  }
164  return twi_status;
165 }
166 
178 bool TWI_MasterRead ( TWI_Master_t *twi, uint8_t address, uint8_t bytesToRead )
179 {
180  bool twi_status = TWI_MasterWriteRead ( twi, address, 0, 0, bytesToRead );
181  while ( !(twi->status == TWIM_STATUS_READY) )
182  {
183  }
184  return twi_status;
185 }
186 
202 bool TWI_MasterWriteRead ( TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite, uint8_t bytesToRead )
203 {
204  /*Parameter sanity check. */
205  if ( bytesToWrite > TWIM_WRITE_BUFFER_SIZE )
206  {
207  return false;
208  }
209  if ( bytesToRead > TWIM_READ_BUFFER_SIZE )
210  {
211  return false;
212  }
213 
214  /*Initiate transaction if bus is ready. */
215  if ( twi->status == TWIM_STATUS_READY )
216  {
217 
218  twi->status = TWIM_STATUS_BUSY;
219  twi->result = TWIM_RESULT_UNKNOWN;
220 
221  twi->address = address << 1;
222 
223  /* Fill write data buffer. */
224  for ( uint8_t bufferIndex = 0; bufferIndex < bytesToWrite; bufferIndex++ )
225  {
226  twi->writeData[bufferIndex] = writeData[bufferIndex];
227  }
228 
229  twi->bytesToWrite = bytesToWrite;
230  twi->bytesToRead = bytesToRead;
231  twi->bytesWritten = 0;
232  twi->bytesRead = 0;
233 
234  /* If write command, send the START condition + Address +
235  * 'R/_W = 0'
236  */
237  if ( twi->bytesToWrite > 0 )
238  {
239  uint8_t writeAddress = twi->address & ~0x01;
240  twi->interface->MASTER.ADDR = writeAddress;
241  }
242 
243  /* If read command, send the START condition + Address +
244  * 'R/_W = 1'
245  */
246  else if ( twi->bytesToRead > 0 )
247  {
248  uint8_t readAddress = twi->address | 0x01;
249  twi->interface->MASTER.ADDR = readAddress;
250  //TWI_MasterReadHandler(twi);
251  }
252  //TWI_MasterInterruptHandler(twi);
253  return true;
254  }
255  else
256  {
257  //TWI_MasterInterruptHandler(twi);
258  return false;
259  }
260 }
261 
269 {
270  uint8_t currentStatus = twi->interface->MASTER.STATUS;
271 
272  /* If arbitration lost or bus error. */
273  if ( (currentStatus & TWI_MASTER_ARBLOST_bm) || (currentStatus & TWI_MASTER_BUSERR_bm) )
274  {
275 
277  }
278 
279  /* If master write interrupt. */
280  else if ( currentStatus & TWI_MASTER_WIF_bm )
281  {
282  TWI_MasterWriteHandler ( twi );
283  }
284 
285  /* If master read interrupt. */
286  else if ( currentStatus & TWI_MASTER_RIF_bm )
287  {
288  TWI_MasterReadHandler ( twi );
289  }
290 
291  /* If unexpected state. */
292  else
293  {
294  printf ( "\n\rUnexpected State: %x \n\r", currentStatus );
295  //TWI_MasterReadHandler(twi);
296  TWI_MasterTransactionFinished ( twi, TWIM_RESULT_FAIL );
297  }
298 }
299 
307 {
308  uint8_t currentStatus = twi->interface->MASTER.STATUS;
309 
310  /* If bus error. */
311  if ( currentStatus & TWI_MASTER_BUSERR_bm )
312  {
313  twi->result = TWIM_RESULT_BUS_ERROR;
314  }
315  /* If arbitration lost. */
316  else
317  {
318  twi->result = TWIM_RESULT_ARBITRATION_LOST;
319  }
320 
321  /* Clear interrupt flag. */
322  twi->interface->MASTER.STATUS = currentStatus | TWI_MASTER_ARBLOST_bm;
323 
324  twi->status = TWIM_STATUS_READY;
325 }
326 
334 {
335  /* Local variables used in if tests to avoid compiler warning. */
336  uint8_t bytesToWrite = twi->bytesToWrite;
337  uint8_t bytesToRead = twi->bytesToRead;
338 
339  /* If NOT acknowledged (NACK) by slave cancel the transaction. */
340 
341  if ( twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm )
342  {
343  twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
344  twi->result = TWIM_RESULT_NACK_RECEIVED;
345  twi->status = TWIM_STATUS_READY;
346  }
347 
348  /* If more bytes to write, send data. */
349  else if ( twi->bytesWritten < bytesToWrite )
350  {
351  uint8_t data = twi->writeData[twi->bytesWritten];
352  twi->interface->MASTER.DATA = data;
353  ++twi->bytesWritten;
354  }
355 
356  /* If bytes to read, send repeated START condition + Address +
357  * 'R/_W = 1'
358  */
359  else if ( twi->bytesRead < bytesToRead )
360  {
361  uint8_t readAddress = twi->address | 0x01;
362  twi->interface->MASTER.ADDR = readAddress;
363  }
364 
365  /* If transaction finished, send STOP condition and set RESULT OK. */
366  else
367  {
368  twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
369  TWI_MasterTransactionFinished ( twi, TWIM_RESULT_OK );
370  }
371 }
372 
381 {
382  /* Fetch data if bytes to be read. */
383  if ( twi->bytesRead < TWIM_READ_BUFFER_SIZE )
384  {
385  uint8_t data = twi->interface->MASTER.DATA;
386  twi->readData[twi->bytesRead] = data;
387  twi->bytesRead++;
388  }
389 
390  /* If buffer overflow, issue STOP and BUFFER_OVERFLOW condition. */
391  else
392  {
393  twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
394  TWI_MasterTransactionFinished ( twi, TWIM_RESULT_BUFFER_OVERFLOW );
395  }
396 
397  /* Local variable used in if test to avoid compiler warning. */
398  uint8_t bytesToRead = twi->bytesToRead;
399 
400  /* If more bytes to read, issue ACK and start a byte read. */
401  if ( twi->bytesRead < bytesToRead )
402  {
403  twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
404  }
405 
406  /* If transaction finished, issue NACK and STOP condition. */
407  else
408  {
409  twi->interface->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
410  TWI_MasterTransactionFinished ( twi, TWIM_RESULT_OK );
411  }
412 }
413 
421 void TWI_MasterTransactionFinished ( TWI_Master_t *twi, uint8_t result )
422 {
423  twi->result = result;
424  twi->status = TWIM_STATUS_READY;
425 }
426 
register8_t writeData[TWIM_WRITE_BUFFER_SIZE]
register8_t status
void TWI_MasterInit(TWI_Master_t *twi, TWI_t *module, TWI_MASTER_INTLVL_t intLevel, uint8_t baudRateRegisterSetting)
Initialise the TWI module.
register8_t address
register8_t readData[TWIM_READ_BUFFER_SIZE]
register8_t bytesToRead
TWI_MASTER_BUSSTATE_t TWI_MasterState(TWI_Master_t *twi)
Returns the TWI bus state.
void TWI_MasterWriteHandler(TWI_Master_t *twi)
TWI master write interrupt handler.
register8_t bytesToWrite
register8_t result
void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
TWI master arbitration lost and bus error interrupt handler.
XMEGA TWI master driver header file.
bool TWI_MasterWriteRead(TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite, uint8_t bytesToRead)
TWI write and/or read transaction.
register8_t bytesWritten
void TWI_MasterReadHandler(TWI_Master_t *twi)
TWI master read interrupt handler.
bool TWI_MasterReady(TWI_Master_t *twi)
Returns true if transaction is ready.
void TWI_MasterInterruptHandler(TWI_Master_t *twi)
Common TWI master interrupt service routine.
bool TWI_MasterWrite(TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite)
TWI write transaction.
void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result)
TWI transaction finished handler.
TWI master driver struct.
bool TWI_MasterRead(TWI_Master_t *twi, uint8_t address, uint8_t bytesToRead)
TWI read transaction.
register8_t bytesRead
#define TWIM_WRITE_BUFFER_SIZE
#define TWIM_STATUS_READY