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 | }
|