1 | void main(void)
|
2 | {
|
3 | short i,f;
|
4 |
|
5 | // Configure Oscillator to operate the device at 80MHz
|
6 | // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
|
7 | // Fosc= 4M*80(2*2)=80Mhz for 4M input clock
|
8 | // RM_FJ
|
9 |
|
10 | CLKDIV = 0; // Teilung durch 1
|
11 | OSCTUN = 0; // Tune FRC oscillator, if FRC is used
|
12 |
|
13 | Delay(10);
|
14 | // OSCCONbits.NOSC = 1; // Switch to PLL mode
|
15 | asm ("mov #0x01, w3");
|
16 | asm ("mov #0x78, w0");
|
17 | asm ("mov #0x9A, w1");
|
18 | asm ("mov #_OSCCON+1, w2");
|
19 | asm ("mov.b w0, [w2]");
|
20 | asm ("mov.b w1, [w2]");
|
21 | asm ("mov.b w3, [w2]");
|
22 |
|
23 | asm ("mov #0x46, w0");
|
24 | asm ("mov #0x57, w1");
|
25 | asm ("mov #_OSCCON, w2");
|
26 | asm ("mov.b w0, [w2]");
|
27 | asm ("mov.b w1, [w2]");
|
28 | asm ("mov.b w3, [w2]");
|
29 |
|
30 | while(OSCCONbits.OSWEN) {}; // Wait for PLL to lock
|
31 |
|
32 | RCONbits.WDTO = 0; // Reset Watch Dog Timer Timeout Flag
|
33 | RCONbits.SWDTEN = 1; // Enable SW controlled Watch Dog Timer
|
34 |
|
35 | // SDO1 SDKARTE
|
36 | // Pin 29-32 SPI1
|
37 | // Pin 29 ist CS: Output RB14
|
38 |
|
39 | // Pin 30 ist SDO SPI1 Data out also RP29 RPOR14 high auf 7 einstellen
|
40 | RPOR14 = 0x0700; // RP29 Pin 30
|
41 |
|
42 | // Pin 31 ist SDA also RP10 auf INPUT SPI1 einstellen
|
43 | // vorher: //RPINR19 = 0x000A;//10; // UART2 RX : RP10 für U2RX gewählt ist Pin 31
|
44 | RPINR20 = 10; // RP10 ist SDI1 ist Pin 31
|
45 | // Pin 32 ist SCL also RP17 RPnR auf 8 einstellen
|
46 | RPOR8 = 0x0800; // SPI1 Clock: Pins RP17=Pin32
|
47 |
|
48 |
|
49 | AD1PCFG = 0xFFFF; //Analoge Ports alle deaktiviert
|
50 |
|
51 | TRISB = 0;
|
52 |
|
53 | mmc_init();
|
54 |
|
55 |
|
56 | for(;;)
|
57 | {
|
58 | //CModulSDCard_sdGlue_PERM();
|
59 | }
|
60 |
|
61 | // if code, behind this line, is executed, something went wrong ...
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | int mmc_init()
|
68 | {
|
69 | int i;
|
70 |
|
71 |
|
72 | //SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
|
73 |
|
74 | //*0x94 |= 0x40; // set CKE = 1 - clock idle low
|
75 | //*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
|
76 | SPI1CON1 = 0x00;
|
77 |
|
78 | SPI1CON1bits.SMP = 0;
|
79 | SPI1CON1bits.CKE = 1;
|
80 | SPI1CON1bits.MSTEN = 1;
|
81 | SPI1CON1bits.CKP = 0;
|
82 |
|
83 | SPI1CON1bits.SPRE2=1;
|
84 | SPI1CON1bits.SPRE1=0;
|
85 | SPI1CON1bits.SPRE0=0;
|
86 |
|
87 | SPI1CON1bits.PPRE1 = 1;
|
88 | SPI1CON1bits.PPRE0 = 1;
|
89 |
|
90 | SPI1STATbits.SPIEN = 1;
|
91 |
|
92 |
|
93 |
|
94 | //OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
|
95 | SDCS = 1; // MMC deaktiviert
|
96 |
|
97 |
|
98 |
|
99 | for(i=0;i<10;i++) // initialise the MMC card into SPI mode by sending clks on
|
100 | {
|
101 | SPI_WRITE(0xFF);
|
102 | }
|
103 |
|
104 |
|
105 | //OUTPUT_LOW(PIN_C2); // set SS = 0 (on) tells card to go to spi mode when it receives reset
|
106 | SDCS = 0; // MMC aktiviert
|
107 |
|
108 |
|
109 | SPI_WRITE(0x40); // send reset command
|
110 | SPI_WRITE(0x00); // all the arguments are 0x00 for the reset command
|
111 | SPI_WRITE(0x00);
|
112 | SPI_WRITE(0x00);
|
113 | SPI_WRITE(0x00);
|
114 | SPI_WRITE(0x95); // precalculated checksum as we are still in MMC mode
|
115 |
|
116 |
|
117 | //puts("Sent go to SPI\n\r");
|
118 |
|
119 | if(mmc_response(0x01)==1) return 1; // if = 1 then there was a timeout waiting for 0x01 from the mmc
|
120 |
|
121 | //puts("Got response from MMC\n\r");
|
122 |
|
123 |
|
124 | i = 0;
|
125 |
|
126 | while((i < 255) && (mmc_response(0x00)==1)) // must keep sending command if response
|
127 | {
|
128 | SPI_WRITE(0x41); // send mmc command one to bring out of idle state
|
129 | SPI_WRITE(0x00); // all the arguments are 0x00 for command one
|
130 | SPI_WRITE(0x00);
|
131 | SPI_WRITE(0x00);
|
132 | SPI_WRITE(0x00);
|
133 | SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
|
134 | i++;
|
135 | }
|
136 |
|
137 | if(i >= 254)
|
138 | return 1; // if >= 254 then there was a timeout waiting for 0x00 from the mmc
|
139 |
|
140 | //puts("Got out of idle response from MMC\n\r");
|
141 |
|
142 |
|
143 | //OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
|
144 | SDCS = 1; // MMC deaktiviert
|
145 |
|
146 | SPI_WRITE(0xFF); // extra clocks to allow mmc to finish off what it is doing
|
147 |
|
148 | //OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
|
149 | SDCS = 0; // MMC aktiviert
|
150 |
|
151 |
|
152 | SPI_WRITE(0x50); // send mmc command one to bring out of idle state
|
153 | SPI_WRITE(0x00);
|
154 | SPI_WRITE(0x00);
|
155 | SPI_WRITE(0x02); // high block length bits - 512 bytes
|
156 | SPI_WRITE(0x00); // low block length bits
|
157 | SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
|
158 |
|
159 | if((mmc_response(0x00))==1) return 1;
|
160 |
|
161 | //OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
|
162 | SDCS = 1; // MMC deaktiviert
|
163 |
|
164 | //puts("Got set block length response from MMC\n\r");
|
165 | return 0;
|
166 | }
|