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