Project

General

Profile

Revision 660

stop.c actually does what the folder title implies
It only looks at the homing data and the contact stuff and sends it to the robot

View differences:

branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/USI_TWI_Master.c
1
/*****************************************************************************
2
*
3
* Atmel Corporation
4
*
5
* File              : USI_TWI_Master.c
6
* Compiler          : IAR EWAAVR 2.28a/3.10a
7
* Revision          : $Revision: 1.11 $
8
* Date              : $Date: Tuesday, September 13, 2005 09:09:36 UTC $
9
* Updated by        : $Author: jtyssoe $
10
*
11
* Support mail      : avr@atmel.com
12
*
13
* Supported devices : All device with USI module can be used.
14
*                     The example is written for the ATmega169, ATtiny26 and ATtiny2313
15
*
16
* AppNote           : AVR310 - Using the USI module as a TWI Master
17
*
18
* Description       : This is an implementation of an TWI master using
19
*                     the USI module as basis. The implementation assumes the AVR to
20
*                     be the only TWI master in the system and can therefore not be
21
*                     used in a multi-master system.
22
* Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise() 
23
*                     function. Hence messages/data are transceived on the bus using
24
*                     the USI_TWI_Transceive() function. The transceive function 
25
*                     returns a status byte, which can be used to evaluate the 
26
*                     success of the transmission.
27
*
28
****************************************************************************/
29
#ifndef _USI_TWI_MASTER_H
30
#define _USI_TWI_MASTER_H
31

  
32
#include <util/delay.h>
33
#include <avr/io.h>
34
#include <avr/interrupt.h>
35
#include "USI_TWI_Master.h"
36

  
37
unsigned char USI_TWI_Master_Transfer( unsigned char );
38
unsigned char USI_TWI_Master_Stop( void );
39

  
40
union  USI_TWI_state
41
{
42
  unsigned char errorState;         // Can reuse the TWI_state for error states due to that it will not be need if there exists an error.
43
  struct
44
  {
45
    unsigned char addressMode         : 1;
46
    unsigned char masterWriteDataMode : 1;
47
    unsigned char unused              : 6;
48
  }; 
49
}   USI_TWI_state;
50

  
51
/*---------------------------------------------------------------
52
 USI TWI single master initialization function
53
---------------------------------------------------------------*/
54
void USI_TWI_Master_Initialise( void )
55
{
56
  PORT_USI |= (1<<PIN_USI_SDA);           // Enable pullup on SDA, to set high as released state.
57
  PORT_USI |= (1<<PIN_USI_SCL);           // Enable pullup on SCL, to set high as released state.
58
  
59
  DDR_USI  |= (1<<PIN_USI_SCL);           // Enable SCL as output.
60
  DDR_USI  |= (1<<PIN_USI_SDA);           // Enable SDA as output.
61
  
62
  USIDR    =  0xFF;                       // Preload dataregister with "released level" data.
63
  USICR    =  (0<<USISIE)|(0<<USIOIE)|                            // Disable Interrupts.
64
              (1<<USIWM1)|(0<<USIWM0)|                            // Set USI in Two-wire mode.
65
              (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|                // Software stobe as counter clock source
66
              (0<<USITC);
67
  USISR   =   (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Clear flags,
68
              (0x0<<USICNT0);                                     // and reset counter.
69
}
70

  
71
/*---------------------------------------------------------------
72
Use this function to get hold of the error message from the last transmission
73
---------------------------------------------------------------*/
74
unsigned char USI_TWI_Get_State_Info( void )
75
{
76
  return ( USI_TWI_state.errorState );                            // Return error state.
77
}
78

  
79
/*---------------------------------------------------------------
80
 USI Transmit and receive function. LSB of first byte in data 
81
 indicates if a read or write cycles is performed. If set a read
82
 operation is performed.
83

  
84
 Function generates (Repeated) Start Condition, sends address and
85
 R/W, Reads/Writes Data, and verifies/sends ACK.
86
 
87
 Success or error code is returned. Error codes are defined in 
88
 USI_TWI_Master.h
89
---------------------------------------------------------------*/
90
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
91
{
92
  unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
93
                                 (0x0<<USICNT0);                                     // set USI to shift 8 bits i.e. count 16 clock edges.
94
  unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Prepare register value to: Clear flags, and
95
                                 (0xE<<USICNT0);                                     // set USI to shift 1 bit i.e. count 2 clock edges.
96

  
97
  USI_TWI_state.errorState = 0;
98
  USI_TWI_state.addressMode = TRUE;
99

  
100

  
101

  
102
  if ( !(*msg & (1<<TWI_READ_BIT)) )                // The LSB in the address byte determines if is a masterRead or masterWrite operation.
103
  {
104
    USI_TWI_state.masterWriteDataMode = TRUE;
105
  }
106

  
107
/* Release SCL to ensure that (repeated) Start can be performed */
108
  PORT_USI |= (1<<PIN_USI_SCL);                     // Release SCL.
109
  while( !(PORT_USI & (1<<PIN_USI_SCL)) );          // Verify that SCL becomes high.
110

  
111
  _delay_loop_1(T2_TWI);
112
  //_delay_us(T4_TWI);
113
  //__delay_cycles( T2_TWI );                         // Delay for T2TWI if TWI_STANDARD_MODE
114

  
115

  
116
/* Generate Start Condition */
117
  PORT_USI &= ~(1<<PIN_USI_SDA);                    // Force SDA LOW.
118
  _delay_loop_1(T4_TWI);
119
  //_delay_us(T4_TWI);
120
  //__delay_cycles( T4_TWI );                         
121
  PORT_USI &= ~(1<<PIN_USI_SCL);                    // Pull SCL LOW.
122
  PORT_USI |= (1<<PIN_USI_SDA);                     // Release SDA.
123

  
124
//Start
125
PORTA |= _BV(PA3);
126

  
127

  
128
/*Write address and Read/Write data */
129
  do
130
  {
131
    /* If masterWrite cycle (or inital address tranmission)*/
132
    if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)
133
    {
134
       PORTA |= _BV(PA4);
135
      /* Write a byte */
136
      PORT_USI &= ~(1<<PIN_USI_SCL);                // Pull SCL LOW.
137
      USIDR     = *(msg++);                        // Setup data.
138
      USI_TWI_Master_Transfer( tempUSISR_8bit );    // Send 8 bits on bus.
139
      
140
      /* Clock and verify (N)ACK from slave */
141
      DDR_USI  &= ~(1<<PIN_USI_SDA);                // Enable SDA as input.
142
      
143
      PORTA |= _BV(PA5);
144
      
145
      if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) ) 
146
      {
147
        //Shit
148
        PORTA |= _BV(PA3) | _BV(PA4) | _BV(PA5) | _BV(PA6) | _BV(PA7);
149
        
150
        if ( USI_TWI_state.addressMode )
151
          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
152
        else
153
          USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
154
        return (FALSE);
155
      }
156
      USI_TWI_state.addressMode = FALSE;            // Only perform address transmission once.
157
      
158
      
159
      PORTA &= (~_BV(PA4) | ~_BV(PA5));
160
    }
161
    /* Else masterRead cycle*/
162
    else
163
    {
164
      /* Read a data byte */
165
      DDR_USI   &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
166
      *(msg++)  = USI_TWI_Master_Transfer( tempUSISR_8bit );
167

  
168
      /* Prepare to generate ACK (or NACK in case of End Of Transmission) */
169
      if( msgSize == 1)                            // If transmission of last byte was performed.
170
      {
171
        USIDR = 0xFF;                              // Load NACK to confirm End Of Transmission.
172
      }
173
      else
174
      {
175
        USIDR = 0x00;                              // Load ACK. Set data register bit 7 (output for SDA) low.
176
      }
177
      USI_TWI_Master_Transfer( tempUSISR_1bit );   // Generate ACK/NACK.
178
    }
179
  }while( --msgSize) ;                             // Until all data sent/received.
180
  
181
  
182
  PORTA |= _BV(PA6);
183
  
184
  USI_TWI_Master_Stop();                           // Send a STOP condition on the TWI bus.
185

  
186
/* Transmission successfully completed*/
187
  return (TRUE);
188
}
189

  
190
/*---------------------------------------------------------------
191
 Core function for shifting data in and out from the USI.
192
 Data to be sent has to be placed into the USIDR prior to calling
193
 this function. Data read, will be return'ed from the function.
194
---------------------------------------------------------------*/
195
unsigned char USI_TWI_Master_Transfer( unsigned char temp )
196
{
197
  USISR = temp;                                     // Set USISR according to temp.
198
                                                    // Prepare clocking.
199
  temp  =  (0<<USISIE)|(0<<USIOIE)|                 // Interrupts disabled
200
           (1<<USIWM1)|(0<<USIWM0)|                 // Set USI in Two-wire mode.
201
           (1<<USICS1)|(0<<USICS0)|(1<<USICLK)|     // Software clock strobe as source.
202
           (1<<USITC);                              // Toggle Clock Port.
203
  do
204
  {
205
    //__delay_cycles( T2_TWI );              
206
    _delay_loop_1(T2_TWI);
207
    //_delay_us(T2_TWI);
208
    USICR = temp;                          // Generate positve SCL edge.
209
    while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.
210
    _delay_loop_1(T4_TWI);
211
    //__delay_cycles( T4_TWI );              
212
   // _delay_us(T4_TWI);
213
    USICR = temp;                          // Generate negative SCL edge.
214
  }while( !(USISR & (1<<USIOIF)) );        // Check for transfer complete.
215
  _delay_loop_1(T2_TWI);
216
  //_delay_us(T2_TWI);
217
  //__delay_cycles( T2_TWI );                
218
  temp  = USIDR;                           // Read out data.
219
  USIDR = 0xFF;                            // Release SDA.
220
  DDR_USI |= (1<<PIN_USI_SDA);             // Enable SDA as output.
221

  
222
  return temp;                             // Return the data from the USIDR
223
}
224

  
225
/*---------------------------------------------------------------
226
 Function for generating a TWI Stop Condition. Used to release 
227
 the TWI bus.
228
---------------------------------------------------------------*/
229
unsigned char USI_TWI_Master_Stop( void )
230
{
231
  PORT_USI &= ~(1<<PIN_USI_SDA);           // Pull SDA low.
232
  PORT_USI |= (1<<PIN_USI_SCL);            // Release SCL.
233
  while( !(PIN_USI & (1<<PIN_USI_SCL)) );  // Wait for SCL to go high.
234
  _delay_loop_1(T4_TWI);
235
  //_delay_us(T4_TWI);
236
  //__delay_cycles( T4_TWI );               
237
  PORT_USI |= (1<<PIN_USI_SDA);            // Release SDA.
238
  _delay_loop_1(T2_TWI);
239
  //_delay_us(T2_TWI);
240
  //__delay_cycles( T2_TWI );                
241
  
242
#ifdef SIGNAL_VERIFY
243
  if( !(USISR & (1<<USIPF)) )
244
  {
245
    USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;    
246
    return (FALSE);
247
  }
248
#endif
249

  
250
  return (TRUE);
251
}
252

  
253
#endif
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/USI_TWI_Slave.h
1
// This file has been prepared for Doxygen automatic documentation generation.
2
/*! \file ********************************************************************
3
*
4
* Atmel Corporation
5
*
6
* File              : USI_TWI_Slave.h
7
* Compiler          : IAR EWAAVR 4.11A
8
* Revision          : $Revision: 1.14 $
9
* Date              : $Date: Friday, December 09, 2005 17:25:38 UTC $
10
* Updated by        : $Author: jtyssoe $
11
*
12
* Support mail      : avr@atmel.com
13
*
14
* Supported devices : All device with USI module can be used.
15
*                     The example is written for the ATmega169, ATtiny26 & ATtiny2313
16
*
17
* AppNote           : AVR312 - Using the USI module as a TWI slave
18
*
19
* Description       : Header file for USI_TWI driver
20
*
21
*
22
*
23
****************************************************************************/
24

  
25

  
26

  
27
//! Prototypes
28
void          USI_TWI_Slave_Initialise( unsigned char );
29
void          USI_TWI_Transmit_Byte( unsigned char );
30
unsigned char USI_TWI_Receive_Byte( void );
31
unsigned char USI_TWI_Data_In_Receive_Buffer( void );
32
void          Timer_Init(void);
33

  
34
#define TRUE                1
35
#define FALSE               0
36

  
37
typedef     unsigned char       uint8_t;
38

  
39
//////////////////////////////////////////////////////////////////
40
///////////////// Driver Buffer Definitions //////////////////////
41
//////////////////////////////////////////////////////////////////
42
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
43

  
44
#define TWI_RX_BUFFER_SIZE  (16)
45
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
46

  
47
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
48
        #error TWI RX buffer size is not a power of 2
49
#endif
50

  
51
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
52

  
53
#define TWI_TX_BUFFER_SIZE  (16)
54
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
55

  
56
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
57
        #error TWI TX buffer size is not a power of 2
58
#endif
59

  
60

  
61

  
62
#define USI_SLAVE_CHECK_ADDRESS                (0x00)
63
#define USI_SLAVE_SEND_DATA                    (0x01)
64
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
65
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA   (0x03)
66
#define USI_SLAVE_REQUEST_DATA                 (0x04)
67
#define USI_SLAVE_GET_DATA_AND_SEND_ACK        (0x05)
68

  
69
#define DDR_USI             DDRB
70
#define PORT_USI            PORTB
71
#define PIN_USI             PINB
72
#define PORT_USI_SDA        PORTB0
73
#define PORT_USI_SCL        PORTB2
74
#define PIN_USI_SDA         PINB0
75
#define PIN_USI_SCL         PINB2
76
#define USI_START_COND_INT  USISIF
77
#define USI_START_VECTOR    USI_START_vect
78
#define USI_OVERFLOW_VECTOR USI_OVF_vect
79

  
80

  
81
//! Functions implemented as macros
82
#define SET_USI_TO_SEND_ACK()                                                                                 \
83
{                                                                                                             \
84
        USIDR    =  0;                                              /* Prepare ACK                         */ \
85
        DDR_USI |=  (1<<PORT_USI_SDA);                              /* Set SDA as output                   */ \
86
        USISR    =  (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|  /* Clear all flags, except Start Cond  */ \
87
                    (0x0E<<USICNT0);                                /* set USI counter to shift 1 bit. */ \
88
}
89

  
90
#define SET_USI_TO_READ_ACK()                                                                                 \
91
{                                                                                                             \
92
        DDR_USI &=  ~(1<<PORT_USI_SDA);                             /* Set SDA as intput */                   \
93
        USIDR    =  0;                                              /* Prepare ACK        */                  \
94
        USISR    =  (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|  /* Clear all flags, except Start Cond  */ \
95
                    (0x0E<<USICNT0);                                /* set USI counter to shift 1 bit. */ \
96
}
97

  
98
#define SET_USI_TO_TWI_START_CONDITION_MODE()                                                                                     \
99
{                                                                                                                                 \
100
  USICR    =  (1<<USISIE)|(0<<USIOIE)|                        /* Enable Start Condition Interrupt. Disable Overflow Interrupt.*/  \
101
              (1<<USIWM1)|(0<<USIWM0)|                        /* Set USI in Two-wire mode. No USI Counter overflow hold.      */  \
102
              (1<<USICS1)|(0<<USICS0)|(0<<USICLK)|            /* Shift Register Clock Source = External, positive edge        */  \
103
              (0<<USITC);                                                                                                         \
104
  USISR    =  (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|  /* Clear all flags, except Start Cond                            */ \
105
              (0x0<<USICNT0);                                                                                                     \
106
}
107

  
108
#define SET_USI_TO_SEND_DATA()                                                                               \
109
{                                                                                                            \
110
    DDR_USI |=  (1<<PORT_USI_SDA);                                  /* Set SDA as output                  */ \
111
    USISR    =  (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      /* Clear all flags, except Start Cond */ \
112
                (0x0<<USICNT0);                                     /* set USI to shift out 8 bits        */ \
113
}
114

  
115
#define SET_USI_TO_READ_DATA()                                                                               \
116
{                                                                                                            \
117
    DDR_USI &= ~(1<<PORT_USI_SDA);                                  /* Set SDA as input                   */ \
118
    USISR    =  (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      /* Clear all flags, except Start Cond */ \
119
                (0x0<<USICNT0);                                     /* set USI to shift out 8 bits        */ \
120
}
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/i2c.h
1
/* i2c.h
2
    
3
        constants and stuff
4
*/
5
#ifndef _I2C_H_
6
#define _I2C_H_
7

  
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <util/delay.h>
11

  
12
#include "USI_TWI_Master.c"
13
#include "USI_TWI_Slave.c" 
14
#include "i2c.c"
15

  
16
void i2c_init(void);
17
void i2c_putpacket(char addr, char *data, char data_size);
18
int i2c_getpacket(char *c);
19
void i2c_test(void);
20
void delay_ms(int ms);
21

  
22
#endif
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/USI_TWI_Master.h
1

  
2

  
3

  
4
/*****************************************************************************
5
*
6
* Atmel Corporation
7
*
8
* File              : USI_TWI_Master.h
9
* Compiler          : IAR EWAAVR 2.28a/3.10a
10
* Revision          : $Revision: 1.11 $
11
* Date              : $Date: Tuesday, September 13, 2005 09:09:36 UTC $
12
* Updated by        : $Author: jtyssoe $
13
*
14
* Support mail      : avr@atmel.com
15
*
16
* Supported devices : All device with USI module can be used.
17
*                     The example is written for the ATmega169, ATtiny26 and ATtiny2313
18
*
19
* AppNote           : AVR310 - Using the USI module as a TWI Master
20
*
21
* Description       : This is an implementation of an TWI master using
22
*                     the USI module as basis. The implementation assumes the AVR to
23
*                     be the only TWI master in the system and can therefore not be
24
*                     used in a multi-master system.
25
* Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise() 
26
*                     function. Hence messages/data are transceived on the bus using
27
*                     the USI_TWI_Start_Transceiver_With_Data() function. If the transceiver
28
*                     returns with a fail, then use USI_TWI_Get_Status_Info to evaluate the 
29
*                     couse of the failure.
30
*
31
****************************************************************************/
32
    
33
//********** Defines **********//
34

  
35
// Defines controlling timing limits
36
//#define TWI_FAST_MODE
37

  
38
//#define SYS_CLK   4000.0  // [kHz]
39

  
40
//Note, this is only a variable that determines how long to delay between
41
// individual bits of I2C send. This has been tested down to 1MHz and it works.
42
// It is possible that even slower speeds can be obtained.
43
#define SYS_CLK     1.0 // [mHz]
44

  
45
// TWI FAST mode timing limits. SCL = 100-400kHz
46
//#define T2_TWI    ((SYS_CLK *1300) /1000000) +1 // >1,3us
47
//#define T4_TWI    ((SYS_CLK * 600) /1000000) +1 // >0,6us
48
 
49
 
50
//This may or may not make it faster. Uncomfirmed. But it works. 
51
#define T2_TWI 0.000001
52
#define T4_TWI 0.000001
53
 
54
// TWI STANDARD mode timing limits. SCL <= 100kHz
55
//#define T2_TWI    ((SYS_CLK *4700) /1000000) +1 // >4,7us
56
//#define T4_TWI    ((SYS_CLK *4000) /1000000) +1 // >4,0us
57

  
58
//USI_TWI messages and flags and bit masks
59
//#define SUCCESS   7
60
//#define MSG       0
61
/****************************************************************************
62
  Bit and byte definitions
63
****************************************************************************/
64
#define TWI_READ_BIT  0       // Bit position for R/W bit in "address byte".
65
#define TWI_ADR_BITS  1       // Bit position for LSB of the slave address bits in the init byte.
66
#define TWI_NACK_BIT  0       // Bit position for (N)ACK bit.
67

  
68
#define USI_TWI_NO_DATA             0x00  // Transmission buffer is empty
69
#define USI_TWI_DATA_OUT_OF_BOUND   0x01  // Transmission buffer is outside SRAM space
70
#define USI_TWI_UE_START_CON        0x02  // Unexpected Start Condition
71
#define USI_TWI_UE_STOP_CON         0x03  // Unexpected Stop Condition
72
#define USI_TWI_UE_DATA_COL         0x04  // Unexpected Data Collision (arbitration)
73
#define USI_TWI_NO_ACK_ON_DATA      0x05  // The slave did not acknowledge  all data
74
#define USI_TWI_NO_ACK_ON_ADDRESS   0x06  // The slave did not acknowledge  the address
75
#define USI_TWI_MISSING_START_CON   0x07  // Generated Start Condition not detected on bus
76
#define USI_TWI_MISSING_STOP_CON    0x08  // Generated Stop Condition not detected on bus
77

  
78
// Device dependant defines
79
#define DDR_USI             DDRB
80
#define PORT_USI            PORTB
81
#define PIN_USI             PINB
82
#define PORT_USI_SDA        PORTB0
83
#define PORT_USI_SCL        PORTB2
84
#define PIN_USI_SDA         PINB0
85
#define PIN_USI_SCL         PINB2
86

  
87
// General defines
88
#define TRUE  1
89
#define FALSE 0
90

  
91
//********** Prototypes **********//
92

  
93
void USI_TWI_Master_Initialise( void );
94
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char * , unsigned char );
95
unsigned char USI_TWI_Get_State_Info( void );
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/stop.c
1 1
#include<avr/io.h>
2
#include <avr/interrupt.h>
2 3
#include "i2c.h"
3 4

  
4 5
#define LED1 PB4 //Green
5 6
#define LED2 PB5 //Red
6 7

  
8
// for i2c_byte coming from charge board
9
//I2C Message Codes
10
#define I2C_MSG_ACKNOWLEDGE       'A'
11
#define I2C_MSG_BATTERY_CHARGING  'C'
12
#define I2C_MSG_DATA              'D'
13
#define I2C_MSG_CONTACT_ERROR     'E'
14
#define I2C_MSG_BATTERY_FULL      'F'
15
#define I2C_MSG_NO_CONTACT        'N'
16
#define I2C_MSG_REQUEST_DATA      'R'
17
#define I2C_MSG_GO_TO_SLEEP       'Y'
18
#define I2C_MSG_ENTERING_SLEEP    'Z'
19
#define I2C_MSG_HOMING            'H'
20

  
21

  
22
#define SW0 PA6
23
#define HOMING_PIN PA7
24

  
25
uint8_t read_homing(void)
26
{
27
    uint8_t ret = PINA & _BV(HOMING_PIN);
28
    if(ret)
29
        PORTA |= _BV(PA3);
30
    else
31
        PORTA &= ~_BV(PA3);
32
    return ret;
33
}
34

  
35
uint8_t get_delay(void)
36
{
37
    uint8_t count = 0;
38
    
39
	PORTB|=_BV(LED2);
40
    while(read_homing())
41
    {
42
        delay_ms(1);
43
        count++;
44
        
45
        if (count >= 100)
46
            return 1;
47
    } //wait a beacon cycle to make sure we aren't starting the count in the middle of one
48
	PORTB&=~_BV(LED2);
49
    count = 0;
50
    PORTB|=_BV(LED1);
51
    while(!read_homing())
52
    {
53
        delay_ms(1);
54
        count++;
55
        if(count==255)
56
          return 2;
57
    }
58
    PORTB&=~_BV(LED1);
59
	
60
  /*RECH_PUTS("\n\rCount: ");
61
	RECH_PUTI(count);
62
	RECH_PUTC('.');*/
63
	
64
    return count;
65
}
66

  
7 67
int main( void )
8 68
{
9 69
	DDRB = _BV(PB0) | _BV(PB5) | _BV(PB4);
......
34 94
      }
35 95
      else
36 96
      {
37
        data[1]=I2C_MSG_NO_CONTACT;
38
        i2c_putpacket(0x01, data, 2);
97
        data[0]=I2C_MSG_NO_CONTACT;
98
        
99
        get_delay(); //reject the first reading //homing import stuff, uncomment this!!!!!!
100
		data[1]=I2C_MSG_HOMING;
101
		data[2]=get_delay();
102
        i2c_putpacket(0x01, data, 3);
39 103
      }
40 104
    }
41 105
    
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/USI_TWI_Slave.c
1
// This file has been prepared for Doxygen automatic documentation generation.
2
/*! \file ********************************************************************
3
*
4
* Atmel Corporation
5
*
6
* File              : USI_TWI_Slave.c
7
* Compiler          : IAR EWAAVR 4.11A
8
* Revision          : $Revision: 1.14 $
9
* Date              : $Date: Friday, December 09, 2005 17:25:38 UTC $
10
* Updated by        : $Author: jtyssoe $
11
*
12
* Support mail      : avr@atmel.com
13
*
14
* Supported devices : All device with USI module can be used.
15
*
16
* AppNote           : AVR312 - Using the USI module as a I2C slave
17
*
18
* Description       : Functions for USI_TWI_receiver and USI_TWI_transmitter.
19
*
20
*
21
****************************************************************************/
22

  
23
#ifndef _USI_TWI_SLAVE_H
24
#define _USI_TWI_SLAVE_H
25

  
26
#include <avr/io.h>
27
#include <avr/interrupt.h>
28
#include "USI_TWI_Slave.h"
29

  
30
/*! Static Variables */
31

  
32
static unsigned char TWI_slaveAddress;
33
static volatile unsigned char USI_TWI_Overflow_State;
34

  
35
/*! Local variables */
36
static uint8_t TWI_RxBuf[TWI_RX_BUFFER_SIZE];
37
static volatile uint8_t TWI_RxHead;
38
static volatile uint8_t TWI_RxTail;
39

  
40
static uint8_t TWI_TxBuf[TWI_TX_BUFFER_SIZE];
41
static volatile uint8_t TWI_TxHead;
42
static volatile uint8_t TWI_TxTail;
43

  
44
/*! \brief Flushes the TWI buffers
45
 */
46
void Flush_TWI_Buffers(void)
47
{
48
    TWI_RxTail = 0;
49
    TWI_RxHead = 0;
50
    TWI_TxTail = 0;
51
    TWI_TxHead = 0;
52
}
53

  
54
//********** USI_TWI functions **********//
55

  
56
/*! \brief
57
 * Initialise USI for TWI Slave mode.
58
 */
59
void USI_TWI_Slave_Initialise( unsigned char TWI_ownAddress )
60
{
61
  Flush_TWI_Buffers();
62

  
63
  TWI_slaveAddress = TWI_ownAddress;
64

  
65
  PORT_USI |=  (1<<PORT_USI_SCL);                                 // Set SCL high
66
  PORT_USI |=  (1<<PORT_USI_SDA);                                 // Set SDA high
67
  DDR_USI  |=  (1<<PORT_USI_SCL);                                 // Set SCL as output
68
  DDR_USI  &= ~(1<<PORT_USI_SDA);                                 // Set SDA as input
69
  USICR    =  (1<<USISIE)|(0<<USIOIE)|                            // Enable Start Condition Interrupt. Disable Overflow Interrupt.
70
              (1<<USIWM1)|(0<<USIWM0)|                            // Set USI in Two-wire mode. No USI Counter overflow prior
71
                                                                  // to first Start Condition (potentail failure)
72
              (1<<USICS1)|(0<<USICS0)|(0<<USICLK)|                // Shift Register Clock Source = External, positive edge
73
              (0<<USITC);
74
  USISR    = 0xF0;                                                // Clear all flags and reset overflow counter
75
}
76

  
77

  
78
/*! \brief Puts data in the transmission buffer, Waits if buffer is full.
79
*/
80
void USI_TWI_Transmit_Byte( unsigned char data )
81
{
82
    unsigned char tmphead;
83

  
84
    tmphead = ( TWI_TxHead + 1 ) & TWI_TX_BUFFER_MASK;         // Calculate buffer index.
85
    while ( tmphead == TWI_TxTail );                           // Wait for free space in buffer.
86
    TWI_TxBuf[tmphead] = data;                                 // Store data in buffer.
87
    TWI_TxHead = tmphead;                                      // Store new index.
88
}
89

  
90
/*! \brief Returns a byte from the receive buffer. Waits if buffer is empty.
91
 */
92
unsigned char USI_TWI_Receive_Byte( void )
93
{
94
    unsigned char tmptail;
95
    unsigned char tmpRxTail;                                  // Temporary variable to store volatile
96
    tmpRxTail = TWI_RxTail;                                   // Not necessary, but prevents warnings
97
    while ( TWI_RxHead == tmpRxTail );
98
    tmptail = ( TWI_RxTail + 1 ) & TWI_RX_BUFFER_MASK;        // Calculate buffer index
99
    TWI_RxTail = tmptail;                                     // Store new index
100
    return TWI_RxBuf[tmptail];                                // Return data from the buffer.
101
}
102

  
103
/*! \brief Check if there is data in the receive buffer.
104
 */
105
unsigned char USI_TWI_Data_In_Receive_Buffer( void )
106
{
107
    unsigned char tmpRxTail;                            // Temporary variable to store volatile
108
    tmpRxTail = TWI_RxTail;                             // Not necessary, but prevents warnings
109
    return ( TWI_RxHead != tmpRxTail );                 // Return 0 (FALSE) if the receive buffer is empty.
110
}
111

  
112
/*! \brief Usi start condition ISR
113
 * Detects the USI_TWI Start Condition and intialises the USI
114
 * for reception of the "TWI Address" packet.
115
 */
116
ISR(USI_START_vect) {
117

  
118
    unsigned char tmpUSISR;                                         // Temporary variable to store volatile
119
    tmpUSISR = USISR;                                               // Not necessary, but prevents warnings
120
// Set default starting conditions for new TWI package
121
    USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS;
122
    DDR_USI  &= ~(1<<PORT_USI_SDA);                                 // Set SDA as input
123
    while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) );   // Wait for SCL to go low to ensure the "Start Condition" has completed.
124
                                                                       // If a Stop condition arises then leave the interrupt to prevent waiting forever.
125
    USICR   =   (1<<USISIE)|(1<<USIOIE)|                            // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART)
126
                (1<<USIWM1)|(1<<USIWM0)|                            // Set USI in Two-wire mode.
127
                (1<<USICS1)|(0<<USICS0)|(0<<USICLK)|                // Shift Register Clock Source = External, positive edge
128
                (0<<USITC);
129
    USISR  =    (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|      // Clear flags
130
                (0x0<<USICNT0);                                     // Set USI to sample 8 bits i.e. count 16 external pin toggles.
131
}
132

  
133

  
134
/*! \brief USI counter overflow ISR
135
 * Handels all the comunication. Is disabled only when waiting
136
 * for new Start Condition.
137
 */
138
ISR(USI_OVF_vect) {
139

  
140
  unsigned char tmpTxTail;     // Temporary variables to store volatiles
141
  unsigned char tmpUSIDR;
142

  
143

  
144
  switch (USI_TWI_Overflow_State)
145
  {
146
    // ---------- Address mode ----------
147
    // Check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, else reset USI.
148
    case USI_SLAVE_CHECK_ADDRESS:
149
      if ((USIDR == 0) || (( USIDR>>1 ) == TWI_slaveAddress))
150
      {
151
        if ( USIDR & 0x01 )
152
          USI_TWI_Overflow_State = USI_SLAVE_SEND_DATA;
153
        else
154
          USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
155
          SET_USI_TO_SEND_ACK();
156
      }
157
      else
158
      {
159
        SET_USI_TO_TWI_START_CONDITION_MODE();
160
      }
161
      break;
162

  
163
    // ----- Master write data mode ------
164
    // Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI.
165
    case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
166
      if ( USIDR ) // If NACK, the master does not want more data.
167
      {
168
        SET_USI_TO_TWI_START_CONDITION_MODE();
169
        return;
170
      }
171
      // From here we just drop straight into USI_SLAVE_SEND_DATA if the master sent an ACK
172

  
173
    // Copy data from buffer to USIDR and set USI to shift byte. Next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
174
    case USI_SLAVE_SEND_DATA:
175

  
176
      // Get data from Buffer
177
      tmpTxTail = TWI_TxTail;           // Not necessary, but prevents warnings
178
      if ( TWI_TxHead != tmpTxTail )
179
      {
180
        TWI_TxTail = ( TWI_TxTail + 1 ) & TWI_TX_BUFFER_MASK;
181
        USIDR = TWI_TxBuf[TWI_TxTail];
182
      }
183
      else // If the buffer is empty then:
184
      {
185
          SET_USI_TO_TWI_START_CONDITION_MODE();
186
          return;
187
      }
188
      USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
189
      SET_USI_TO_SEND_DATA();
190
      break;
191

  
192
    // Set USI to sample reply from master. Next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
193
    case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
194
      USI_TWI_Overflow_State = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
195
      SET_USI_TO_READ_ACK();
196
      break;
197

  
198
    // ----- Master read data mode ------
199
    // Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK.
200
    case USI_SLAVE_REQUEST_DATA:
201
      USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
202
      SET_USI_TO_READ_DATA();
203
      break;
204

  
205
    // Copy data from USIDR and send ACK. Next USI_SLAVE_REQUEST_DATA
206
    case USI_SLAVE_GET_DATA_AND_SEND_ACK:
207
      // Put data into Buffer
208
      tmpUSIDR = USIDR;             // Not necessary, but prevents warnings
209
      TWI_RxHead = ( TWI_RxHead + 1 ) & TWI_RX_BUFFER_MASK;
210
      TWI_RxBuf[TWI_RxHead] = tmpUSIDR;
211

  
212
      USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
213
      SET_USI_TO_SEND_ACK();
214
      break;
215
  }
216
}
217

  
218
#endif
branches/autonomous_recharging/code/projects/autonomous_recharging/archs/homing stop/i2c.c
1
/* I2C.c
2

  
3
    I2C Communication
4
    
5
    Problem switching into slave mode. So never run as a slave otherwise you will never be able
6
        to speak again (unless a master tells you to).
7
    
8
*/
9

  
10
#include "i2c.h"
11
/*
12
int main(void) {
13
	i2c_test();
14
}
15
*/
16
//Call this to start I2C up
17
void i2c_init(void) {
18
  //Start off in slave mode so you can catch any data that comes your way
19
  //USI_TWI_Slave_Initialise(0x02);
20
  
21
  //Can't ever be a slave otherwise you will die. Stay as master and never give it up.
22
    USI_TWI_Master_Initialise();
23
 
24
}
25

  
26

  
27
//Call this to send a packet. *data is a char array of data_size. Make sure you put in data_size or we won't send
28
//everything.
29
//Note, mainboard is addr = 0x01.
30
void i2c_putpacket(char addr, char *data, char data_size) {
31
  //The packet that we will transmit over I2C
32
  unsigned char packet[data_size + 1];
33
  
34
  //First byte is the destination address + R/W (R = 1, W = 0)
35
  packet[0] = addr << 1;    //Shift the address over 1 bit, LSB is 0 which means write
36
  
37
  //Put data into packet
38
  for (int i = 0; i < data_size; i++) {
39
    packet[i+1] = data[i];
40
  }
41
  
42
  //Send packet. Will open line, transmit, and close line.
43
  USI_TWI_Start_Transceiver_With_Data(packet, (data_size + 1));
44

  
45
}
46

  
47
int i2c_getpacket(char *c) {
48
  if (USI_TWI_Data_In_Receive_Buffer()) {
49
    *c =  USI_TWI_Receive_Byte();
50
    return 0;
51
  } else{
52
      return -1;
53
  
54
  }
55
}
56

  
57
void delay_ms(int ms) 
58
{
59
	for(; ms > 15; ms-=15)
60
		_delay_ms(15);
61
	_delay_ms(ms);
62
}
63

  
64

  
65
// Note this will fail. You need to fix the switch from slave -> master before it will succeed.
66
void i2c_test(void) {
67
    char datatx[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
68
   char datarx;
69
  
70
  DDRA = _BV(PA3) | _BV(PA4) | _BV(PA5) | _BV(PA6) | _BV(PA7);
71
  PORTA = 0;
72
  PORTA |= _BV(PA3);
73
  
74
  //delay_ms(1000);
75
  
76
  sei();
77
  i2c_init();
78
   
79
    while(1) {
80
	delay_ms(1000);
81
    i2c_putpacket(0x01, datatx, 26);
82
	}
83
  
84
  /*
85
    while(1) {
86
      i2c_getpacket(&datarx);
87
      
88
      switch (datarx) {
89
        case 'a':
90
            PORTA |= _BV(PA4);
91
            break;
92
        case 'b':
93
            PORTA |= _BV(PA5);
94
            break;
95
        case 'c':
96
            PORTA |= _BV(PA6);
97
            break;
98
        case 'd':
99
            PORTA |= _BV(PA7);
100
            break;
101
      }
102
      
103
      if (datarx == 'd')
104
        break;
105
  }
106
  
107
   PORTA = 0;
108
 
109

  
110
  //PORTA |= _BV(PA5);
111
  delay_ms(1000);
112
  i2c_putpacket(0x01, datatx, 26);
113
  */
114
}
115

  

Also available in: Unified diff