1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
| #include "reg_c51.h"
#include <intrins.h>
#include <stdio.h>
#include <string.h>
//////////////////////////////////
// PIN ASSINGMENTS //
//////////////////////////////////
//-------General Peraphirals
sbit SYS_LED = P0^4;
sbit MMC_SPIN = P1^2;
//-----MACROS
#define HIGH 1
#define LOW 0
#define SYS_LED_ON SYS_LED = LOW;
#define SYS_LED_OFF SYS_LED = HIGH;
#define SERIAL_PACKET_SIZE 20
#define BUFERS_SIZE SERIAL_PACKET_SIZE - 2
#define TIMER0_RELOAD_VALUE -0x2e //for 50ms time interval
#define MMC_SEL MMC_SPIN = 0;
#define MMC_DSEL MMC_SPIN = 1;
xdata char sector[512];
void serialTx(unsigned char chr);
//////////////////////////////////////////////
// GLOBAL VERIABLES DECLERATIONS //
//////////////////////////////////////////////
char SpiRcvDat;
char data_example=0x55;
char data_save;
bit transmit_completed= 0;
char x, rs232byt;
/*----------------------------------Interrupts--------------------------------------*/
void serial_interrupt(void) interrupt 4 using 2 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~SERIAL ISR*/
{
if (RI)
{
rs232byt = SBUF;
RI = 0;
}
}
/*------------------------------------------------------------------------------------*/
/*-------------------------------------UDF--------------------------------------------*/
/*------------------------------------------------------------------------------------*/
void delay(unsigned int times)
{
unsigned char i;
while(times-- > 0)
{
i = 255;
while(i-- > 0)
{
i = i;
}
}
}
/******************************************SPI Functions********************************/
void serialTx(unsigned char chr)
{
SBUF= chr;
while (!TI);
TI= 0;
}
char SpiTx(unsigned char txbyte)
{
SPDAT=txbyte; /* send data */
while(!(SPSTA & 0x80));/* wait end of transmition */
//serialTx(SPDAT);
return SPDAT;
}
void uart_puts (char *s) {
// loop until *s != NULL
while (*s) {
serialTx(*s);
s++;
}
}
char Command(char befF, unsigned long Adr, char befH )
{ // sends a command to the MMC.
_nop_();_nop_();
SpiTx(0xFF);
SpiTx(befF);
SpiTx((char)(Adr >> 24));
SpiTx((char)(Adr >> 16));
SpiTx((char)(Adr >> 8));
SpiTx((char)(Adr >> 0));
SpiTx(befH);
SpiTx(0xFF);
return SpiTx(0xFF); // return the last received character
_nop_();_nop_();
}
int MMC_Init(void) { // init SPI
char i;
MMC_DSEL
for(i=0; i < 10; i++) SpiTx(0xFF); // send 10*8=80 clock pulses
MMC_SEL //PORTB &= ~(1 << SPICS); // enable MMC
while (Command(0x40,0x00000000,0x95) != 0x01) {serialTx('_');};// goto mmcerror; // reset MMC
MMC_DSEL
SpiTx(0xFF);
MMC_SEL
st: // if there is no MMC, prg. loops here
if (Command(0x41,0x00000000,0xFF) !=0x00)
{
serialTx('x');
goto st;
}
serialTx('1');
MMC_DSEL
MMC_SEL
Command(0x50, 0x00000400, 0xFF);
MMC_DSEL
return 1;
mmcerror:
serialTx('0');
MMC_DSEL
return 0;
}
void fillram(void) { // fill RAM sector with ASCII characters
int i,c;
char mystring[18] = "Hello World..... ";
c = 0;
for (i=0;i<=512;i++) {
sector[i] = mystring[c];
c++;
if (c > 17) { c = 0; }
}
}
int writeramtommc(unsigned long sectoradd) { // write RAM sector to MMC
int i, retry=0;
char c;
MMC_SEL
// 512 byte-write-mode
if (Command(0x58,sectoradd,0xFF) !=0) {
serialTx('e');//uart_puts("MMC: write error 1 ");
return 1;
}
//SpiTx(0xFF);
SpiTx(0xFF);
SpiTx(0xFE);
// write ram sectors to MMC
for (i=0;i<512;i++) {
SpiTx(sector[i]);
//delay(300);
}
// at the end, send 2 dummy bytes
SpiTx(0xFF);
SpiTx(0xFF);
c = SpiTx(0xFF);
c &= 0x1F; // 0x1F = 0b.0001.1111;
serialTx('+');
serialTx(c);
if (c != 0x05) { // 0x05 = 0b.0000.0101
uart_puts("w");uart_puts("e");//uart_puts("MMC: write error 2 ");
MMC_DSEL
return 1;
}
// wait until MMC is not busy anymore
while(SpiTx(0xFF) != (char)0xFF);
// MMC_DSEL
// SpiTx(0xff); //just spend 8 clock cycle delay before reasserting the CS line
// MMC_SEL //re-asserting the CS line to verify if card is still busy
// while(! SpiTx(0x00)) //wait for SD card to complete writing and get idle
// if(retry++ > 0xfffe){MMC_DSEL; return 1;}
// MMC_DSEL
serialTx('+');
MMC_DSEL
return 0;
}
int sendmmc(unsigned long sectoradd) { // send 512 bytes from the MMC via the serial port
int i, ix, j;
unsigned char r1 = 0;
serialTx('=');
MMC_SEL
r1 = Command(0x51,sectoradd,0xFF);
serialTx(r1);
for (ix = 0; ix < 50000; ix++) {
if (r1 == 0x00) break;
r1 = Command(0x51,sectoradd,0xFF);
r1 = SpiTx(0xFF);
}
if (r1 != 0x00) {
serialTx('R');serialTx('e');//uart_puts("MMC: read error 1 ");
return 1;
}
// wait for 0xFE - start of any transmission
// ATT: typecast (char)0xFE is a must!
MMC_DSEL
MMC_SEL
r1 = SpiTx(0xff);
while(r1 != (char)0xFE){r1 = SpiTx(0x00); serialTx('|'); serialTx(r1); serialTx('|');}
serialTx('(');
for(i=0; i < 512; i++) {
//serialTx(SpiTx(0xFF));
j = SpiTx(0x00);
serialTx(j);
}
// at the end, send 2 dummy bytes
SpiTx(0xFF); // actually this returns the CRC/checksum byte
SpiTx(0xFF);
serialTx(')');
MMC_DSEL
return 0;
}
int main(void)
{
unsigned long addx;
/*--------Bismillah-------*/
/* setup Serial interrupt */
TMOD = TMOD | 0x20; //TIMER1 IN MOD2 (AUTO RELOAD)
TH1 = -3; //BAUD RATE = 9600bps @ 11.0592MHz
TR1 = 1; //RUN TIMER1 FOR SERIAL CLOCK
SCON = 0x52; //8BIT, 1STOPBIT, NO PARITY
RI = 0;
TI = 0;
ES = 1; //ENABLE SERIAL INT
/* setup timer 0 interrupt */
// TR0 = 0;
// TH0 = 0X4B;
// TL0 = 0xFD; // set timer period
// TMOD = TMOD | 0x01; // select mode 1
// TR0 = 1; // start timer 0
/* Ext0 interrupt Settings */
//IT1 = 1; //ext0 neg edge trigger
/*SPI Settings And Interrupt */
SPCON = 0x00;
SPCON = 0x10; /* Master mode */
MMC_DSEL /* Disable slave */
SPCON |= 0x01; /* Fclk Periph/64 */
SPCON |= 0x80; /* Fclk Periph/64 */
//SPCON |= 0x04; /* CPHA=1; transmit mode example */
//SPCON |= 0x08; /* CPOL=1; transmit mode example */
//IEN1 |= 0x04; /* enable spi interrupt */
SPCON |= 0x40; /* run spi */
EA=1; /* enable interrupts */
P0 = 0xff;
SYS_LED = 1;
delay(500);
MMC_Init();
fillram();
addx = 0x00000200;
writeramtommc(addx);
delay(200);
sendmmc(addx);
delay(200);
sendmmc(addx + 0x00000200);
while(1) /* endless */
{
//addx += 0x00000400;
SYS_LED = ~SYS_LED;
delay(100);
}
} |