mega.c


1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/wdt.h>
4
//#include <avr/interrupt.h>
5
6
#include "spi.h"
7
8
#define SPI_SPDR_EMPTY  7
9
#define SPI_ACTIVE    6
10
11
#define SPI_BUF_TX_PENDING    0
12
13
14
uint8_t spi_state = (1<<SPI_SPDR_EMPTY);
15
uint8_t spi_buf[3][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
16
uint8_t spi_buf_state[3] = {0,0,0};
17
18
19
20
void spi_main();
21
void spi_testtx( uint8_t data );
22
23
/*################################### MAIN ####################################*/
24
int main( void )
25
{
26
27
  // Debug
28
  DDRB = 0x03;
29
  PORTB = 0xFE;
30
31
32
  // INIT
33
  SPCR  = (1<<SPE) | (1<<MSTR);      // Activate SPI-Module, Mastermode, SPI-Mode 0, f_SCK = f_osc/4
34
35
  DDRB  |= (1<<PB5) | (1<<PB3);      // MOSI & SCK as output
36
  PORTC  = 0x07;      // deselect slaves
37
  DDRC  = 0x01;//0xFF;  // slaveselect- and triggerpins as outputs
38
  
39
40
  uint16_t i = -1;
41
  while (1)
42
  {
43
44
45
    // alive
46
    PORTB ^= (1<<1);
47
    
48
    spi_main();
49
50
    if( i-- == 0 )
51
    {
52
      i = 40000;
53
      spi_testtx( 'X' );
54
      PORTB ^= (1<<0);
55
    }
56
57
  }
58
  return 0;
59
}
60
61
void spi_main()
62
{
63
  // SPI
64
  if( SPSR & (1<<SPIF) )
65
  {
66
    SPSR = (1<<SPIF);
67
    spi_state |= (1<<SPI_SPDR_EMPTY);
68
  }
69
70
  if( spi_state & (1<<SPI_SPDR_EMPTY) ) // SPI ready
71
  {
72
    if( spi_state & (1<<SPI_ACTIVE) ) // carry on active transmition
73
    {
74
      uint8_t slave = ( spi_state & 3 ) >> 4;
75
      uint8_t bytecntr = ( spi_state & 0x0F );
76
77
      if( bytecntr > 0 )      // receive data
78
        spi_buf[ slave ][ bytecntr-1 ] = SPDR;
79
80
      if( bytecntr < 6 )      // transmit data
81
      {
82
        SPDR = spi_buf[ slave ][ bytecntr ];
83
        spi_state &= ~(1<<SPI_SPDR_EMPTY);
84
      }
85
86
      if( bytecntr == 6 )      // transmition complete
87
      {
88
        //  update bufferstate
89
        spi_buf_state[ slave ] = 0;
90
        //  deselect Slave
91
        PORTC |= (1<<slave);
92
        //  reset spi_state
93
        spi_state = (1<<SPI_SPDR_EMPTY);
94
95
        // process_SPI_rx_buffer();
96
      }
97
      else
98
        spi_state ++;  //bytecounter weiterzählen
99
    }
100
    else
101
    {
102
      for( uint8_t slave=0; slave<3; slave++ )  // check for new SPI-jobs
103
      {  
104
        if( spi_buf_state[ slave ] & (1<<SPI_BUF_TX_PENDING) )
105
        {
106
          // select Slave
107
          PORTC &= ~(1<<slave);
108
          spi_state = (1<<SPI_SPDR_EMPTY) | (1<<SPI_ACTIVE) | (slave << 4);
109
          break;
110
        }
111
      }
112
    }
113
  }
114
}
115
116
117
void spi_testtx( uint8_t data )
118
{
119
  uint8_t slave = 0;
120
121
  spi_buf_state[ slave ] = (1<<SPI_BUF_TX_PENDING);
122
  for( uint8_t bytecntr=0; bytecntr<5; bytecntr++ )
123
    spi_buf[ slave ][ bytecntr ] = 0;
124
  spi_buf[ slave ][ 0 ] = data;
125
  spi_buf[ slave ][ 1 ] = 0xAA;
126
  spi_buf[ slave ][ 2 ] = 0xFF;
127
  spi_buf[ slave ][ 3 ] = 0x00;
128
  spi_buf[ slave ][ 4 ] = 0b00111100;
129
  spi_buf[ slave ][ 5 ] = 0 - data;
130
}