1 | /***************************************************************
|
2 | * spi_basis.c *
|
3 | * *
|
4 | * Version: 1.0 *
|
5 | * *
|
6 | * Nach ATMEL Application Note *
|
7 | * http://www.atmel.com/dyn/resources/prod_documents/doc4348.pd *
|
8 | ***************************************************************/
|
9 |
|
10 | /* I N C L U D E S */
|
11 | #include <at89c5131.h>
|
12 | #include <spi_basis.h>
|
13 |
|
14 | char spi_data; // Globale Variable
|
15 | bit transmit_completed= 0;
|
16 |
|
17 | #define SS_Pin P1_1
|
18 |
|
19 | /**
|
20 | * FUNKTION: SPI_init()
|
21 | * Fclk Periph/128 als Baud Rate, Slave Select Pin deaktiviert
|
22 | * FUNCTION_INPUTS: P1.5(MISO) serial input
|
23 | * FUNCTION_OUTPUTS: P1.7(MOSI) serial output
|
24 | */
|
25 | // Bitmuster für SPI-Baudratenteiler
|
26 | #define SP128 0x82
|
27 | #define SP64 0x81
|
28 | #define SP32 0x80
|
29 | #define SP16 0x03
|
30 | #define SP8 0x02
|
31 | #define SP4 0x01
|
32 |
|
33 | // SPCON: SPI Konfiguration, nicht bitadressierbar
|
34 | // Bit 7 6 5 4 3 2 1 0
|
35 | // Name SPR2 SPEN SSDIS MSTR CPOL CPHA SPR1 SPR0
|
36 | // Funktionen Baudrate mit SPR2..0
|
37 | // Baugruppe einschalten mit SPEN
|
38 | // SS-Pin freigeben mit SSDIS
|
39 | // Master Mode mit MSTR
|
40 | // SPI-Mode mit CPOL:CPHA
|
41 | void SPI_init(void)
|
42 | {
|
43 | SPCON |= 0x10; // Master Mode
|
44 | SPCON |= 0x20; // SS-Pin-Umschaltung deaktiveren
|
45 | SS_Pin = 1; // SS-Pin setzen (Slave deaktivieren)
|
46 | SPCON &= 0x74; // Taktrate setzten. Zuerst Bits 7,1,0 löschen
|
47 | SPCON |= SP128; // Bits 7,1,0 setzen (Hier Teiler 128 => 48kBit/s)
|
48 |
|
49 | SPCON &= ~0x08; // CPOL=0; Modus 0 für SD-Karte
|
50 | SPCON &= ~0x04; // CPHA=0;
|
51 | IE1 |= 0x04; // Freigabe SPI Interrupt (IEN1 ist nicht Bitadressierbar)
|
52 | SPCON |= 0x40; // SPI einschalten
|
53 | EA = 1; // Globale Freigabe
|
54 | }
|
55 |
|
56 | /* Auf hohe Geschwindigkeit schalten */
|
57 | void SPI_fullspeed(void)
|
58 | {
|
59 | SPCON &= 0x74; // Taktrate setzten. Zuerst Bits 7,1,0 löschen
|
60 | SPCON |= SP32; // Bits 7,1,0 setzen (Hier Teiler 4 => 1,5 MBit/s)
|
61 | }
|
62 |
|
63 |
|
64 | /**
|
65 | * FUNCTION: SPI_ISR
|
66 | * FUNCTION_INPUTS: void
|
67 | * FUNCTION_OUTPUTS: transmit_complete is software transfert flag
|
68 | */
|
69 | void SPI_ISR(void) interrupt 9 /* interrupt address is 0x004B */
|
70 | {
|
71 | switch( SPSTA ) /* read and clear spi status register */
|
72 | {
|
73 | case 0x80:
|
74 | // Zugriff auf SPDAT löscht den Interrupt
|
75 | spi_data = SPDAT; /* read receive data */
|
76 | transmit_completed = 1; /* set software flag */
|
77 | break;
|
78 | case 0x10:
|
79 | /* put here for mode fault tasking */
|
80 | SPCON &= 0xBF; // SPEN löschen
|
81 | SPCON |= 0x40; // SPEN setzen
|
82 | break;
|
83 | case 0x40:
|
84 | /* put here for overrun tasking */
|
85 | break;
|
86 | }
|
87 | }
|
88 |
|
89 | /**
|
90 | * FUNCTION: SPI_Read_Write
|
91 | * FUNCTION_INPUTS: Sendedaten
|
92 | * FUNCTION_OUTPUTS: Empfangsdaten
|
93 | * Slave wird hier nicht enabled!
|
94 | */
|
95 | char SPI_Read_Write(char daten)
|
96 | {
|
97 | SPDAT = daten; // Daten Senden initialisieren
|
98 | while (!transmit_completed); // warte auf SPI_ISR
|
99 | transmit_completed = 0; // Flag löschen
|
100 | //spi_data = SPDAT; // Daten abholen
|
101 | return spi_data;// globale Variable
|
102 | }
|
103 |
|
104 | /**
|
105 | * FUNCTION: SPI_Write_Byte
|
106 | * FUNCTION_INPUTS: Sendedaten
|
107 | * FUNCTION_OUTPUTS: void
|
108 | */
|
109 | void SPI_Write_Byte(char daten)
|
110 | {
|
111 | SS_Pin = 0; // Slave enable
|
112 | SPI_Read_Write(daten); // nur Daten senden
|
113 | SS_Pin = 1; // Slave disable
|
114 | return;
|
115 | }
|
116 |
|
117 | /**
|
118 | * FUNCTION: SPI_Read_Byte
|
119 | * FUNCTION_INPUTS: void
|
120 | * FUNCTION_OUTPUTS: Empfangsdaten
|
121 | */
|
122 | char SPI_Read_Byte(void)
|
123 | { char daten;
|
124 | SS_Pin = 0; // Slave enable
|
125 | daten = SPI_Read_Write(0x00); // Nulldaten => Takt erzeugen
|
126 | SS_Pin = 1; // Slave disable
|
127 | return daten;
|
128 | }
|