Sd2Card.cpp

Sat, 07 Nov 2015 13:23:07 +0100

author
mbayer
date
Sat, 07 Nov 2015 13:23:07 +0100
changeset 0
2c8ba1964db7
permissions
-rw-r--r--

Initial code from reprappro Marlin repository

0
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
1 /* Arduino Sd2Card Library
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
2 * Copyright (C) 2009 by William Greiman
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
3 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
4 * This file is part of the Arduino Sd2Card Library
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
5 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
6 * This Library is free software: you can redistribute it and/or modify
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
8 * the Free Software Foundation, either version 3 of the License, or
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
9 * (at your option) any later version.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
10 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
11 * This Library is distributed in the hope that it will be useful,
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
14 * GNU General Public License for more details.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
15 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
16 * You should have received a copy of the GNU General Public License
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
17 * along with the Arduino Sd2Card Library. If not, see
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
18 * <http://www.gnu.org/licenses/>.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
19 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
20 #include "Marlin.h"
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
21
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
22 #ifdef SDSUPPORT
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
23 #include "Sd2Card.h"
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
24 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
25 #ifndef SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
26 // functions for hardware SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
27 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
28 // make sure SPCR rate is in expected bits
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
29 #if (SPR0 != 0 || SPR1 != 1)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
30 #error unexpected SPCR bits
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
31 #endif
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
32 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
33 * Initialize hardware SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
34 * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
35 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
36 static void spiInit(uint8_t spiRate) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
37 // See avr processor documentation
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
38 SPCR = (1 << SPE) | (1 << MSTR) | (spiRate >> 1);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
39 SPSR = spiRate & 1 || spiRate == 6 ? 0 : 1 << SPI2X;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
40 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
41 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
42 /** SPI receive a byte */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
43 static uint8_t spiRec() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
44 SPDR = 0XFF;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
45 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
46 return SPDR;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
47 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
48 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
49 /** SPI read data - only one call so force inline */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
50 static inline __attribute__((always_inline))
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
51 void spiRead(uint8_t* buf, uint16_t nbyte) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
52 if (nbyte-- == 0) return;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
53 SPDR = 0XFF;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
54 for (uint16_t i = 0; i < nbyte; i++) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
55 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
56 buf[i] = SPDR;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
57 SPDR = 0XFF;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
58 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
59 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
60 buf[nbyte] = SPDR;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
61 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
62 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
63 /** SPI send a byte */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
64 static void spiSend(uint8_t b) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
65 SPDR = b;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
66 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
67 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
68 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
69 /** SPI send block - only one call so force inline */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
70 static inline __attribute__((always_inline))
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
71 void spiSendBlock(uint8_t token, const uint8_t* buf) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
72 SPDR = token;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
73 for (uint16_t i = 0; i < 512; i += 2) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
74 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
75 SPDR = buf[i];
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
76 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
77 SPDR = buf[i + 1];
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
78 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
79 while (!(SPSR & (1 << SPIF)));
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
80 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
81 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
82 #else // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
83 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
84 /** nop to tune soft SPI timing */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
85 #define nop asm volatile ("nop\n\t")
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
86 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
87 /** Soft SPI receive byte */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
88 static uint8_t spiRec() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
89 uint8_t data = 0;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
90 // no interrupts during byte receive - about 8 us
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
91 cli();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
92 // output pin high - like sending 0XFF
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
93 fastDigitalWrite(SPI_MOSI_PIN, HIGH);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
94
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
95 for (uint8_t i = 0; i < 8; i++) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
96 fastDigitalWrite(SPI_SCK_PIN, HIGH);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
97
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
98 // adjust so SCK is nice
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
99 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
100 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
101
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
102 data <<= 1;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
103
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
104 if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
105
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
106 fastDigitalWrite(SPI_SCK_PIN, LOW);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
107 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
108 // enable interrupts
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
109 sei();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
110 return data;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
111 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
112 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
113 /** Soft SPI read data */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
114 static void spiRead(uint8_t* buf, uint16_t nbyte) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
115 for (uint16_t i = 0; i < nbyte; i++) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
116 buf[i] = spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
117 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
118 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
119 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
120 /** Soft SPI send byte */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
121 static void spiSend(uint8_t data) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
122 // no interrupts during byte send - about 8 us
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
123 cli();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
124 for (uint8_t i = 0; i < 8; i++) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
125 fastDigitalWrite(SPI_SCK_PIN, LOW);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
126
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
127 fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
128
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
129 data <<= 1;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
130
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
131 fastDigitalWrite(SPI_SCK_PIN, HIGH);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
132 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
133 // hold SCK high for a few ns
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
134 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
135 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
136 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
137 nop;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
138
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
139 fastDigitalWrite(SPI_SCK_PIN, LOW);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
140 // enable interrupts
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
141 sei();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
142 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
143 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
144 /** Soft SPI send block */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
145 void spiSendBlock(uint8_t token, const uint8_t* buf) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
146 spiSend(token);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
147 for (uint16_t i = 0; i < 512; i++) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
148 spiSend(buf[i]);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
149 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
150 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
151 #endif // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
152 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
153 // send command and return error code. Return zero for OK
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
154 uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
155 // select card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
156 chipSelectLow();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
157
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
158 // wait up to 300 ms if busy
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
159 waitNotBusy(300);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
160
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
161 // send command
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
162 spiSend(cmd | 0x40);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
163
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
164 // send argument
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
165 for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
166
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
167 // send CRC
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
168 uint8_t crc = 0XFF;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
169 if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
170 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
171 spiSend(crc);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
172
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
173 // skip stuff byte for stop read
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
174 if (cmd == CMD12) spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
175
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
176 // wait for response
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
177 for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
178 return status_;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
179 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
180 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
181 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
182 * Determine the size of an SD flash memory card.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
183 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
184 * \return The number of 512 byte data blocks in the card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
185 * or zero if an error occurs.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
186 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
187 uint32_t Sd2Card::cardSize() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
188 csd_t csd;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
189 if (!readCSD(&csd)) return 0;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
190 if (csd.v1.csd_ver == 0) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
191 uint8_t read_bl_len = csd.v1.read_bl_len;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
192 uint16_t c_size = (csd.v1.c_size_high << 10)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
193 | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
194 uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
195 | csd.v1.c_size_mult_low;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
196 return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
197 } else if (csd.v2.csd_ver == 1) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
198 uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
199 | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
200 return (c_size + 1) << 10;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
201 } else {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
202 error(SD_CARD_ERROR_BAD_CSD);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
203 return 0;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
204 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
205 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
206 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
207 void Sd2Card::chipSelectHigh() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
208 digitalWrite(chipSelectPin_, HIGH);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
209 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
210 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
211 void Sd2Card::chipSelectLow() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
212 #ifndef SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
213 spiInit(spiRate_);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
214 #endif // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
215 digitalWrite(chipSelectPin_, LOW);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
216 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
217 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
218 /** Erase a range of blocks.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
219 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
220 * \param[in] firstBlock The address of the first block in the range.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
221 * \param[in] lastBlock The address of the last block in the range.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
222 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
223 * \note This function requests the SD card to do a flash erase for a
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
224 * range of blocks. The data on the card after an erase operation is
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
225 * either 0 or 1, depends on the card vendor. The card must support
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
226 * single block erase.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
227 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
228 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
229 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
230 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
231 bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
232 csd_t csd;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
233 if (!readCSD(&csd)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
234 // check for single block erase
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
235 if (!csd.v1.erase_blk_en) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
236 // erase size mask
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
237 uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
238 if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
239 // error card can't erase specified area
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
240 error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
241 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
242 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
243 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
244 if (type_ != SD_CARD_TYPE_SDHC) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
245 firstBlock <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
246 lastBlock <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
247 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
248 if (cardCommand(CMD32, firstBlock)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
249 || cardCommand(CMD33, lastBlock)
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
250 || cardCommand(CMD38, 0)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
251 error(SD_CARD_ERROR_ERASE);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
252 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
253 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
254 if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
255 error(SD_CARD_ERROR_ERASE_TIMEOUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
256 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
257 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
258 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
259 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
260
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
261 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
262 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
263 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
264 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
265 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
266 /** Determine if card supports single block erase.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
267 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
268 * \return The value one, true, is returned if single block erase is supported.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
269 * The value zero, false, is returned if single block erase is not supported.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
270 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
271 bool Sd2Card::eraseSingleBlockEnable() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
272 csd_t csd;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
273 return readCSD(&csd) ? csd.v1.erase_blk_en : false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
274 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
275 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
276 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
277 * Initialize an SD flash memory card.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
278 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
279 * \param[in] sckRateID SPI clock rate selector. See setSckRate().
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
280 * \param[in] chipSelectPin SD chip select pin number.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
281 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
282 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
283 * the value zero, false, is returned for failure. The reason for failure
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
284 * can be determined by calling errorCode() and errorData().
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
285 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
286 bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
287 errorCode_ = type_ = 0;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
288 chipSelectPin_ = chipSelectPin;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
289 // 16-bit init start time allows over a minute
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
290 uint16_t t0 = (uint16_t)millis();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
291 uint32_t arg;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
292
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
293 // set pin modes
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
294 pinMode(chipSelectPin_, OUTPUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
295 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
296 pinMode(SPI_MISO_PIN, INPUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
297 pinMode(SPI_MOSI_PIN, OUTPUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
298 pinMode(SPI_SCK_PIN, OUTPUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
299
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
300 #ifndef SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
301 // SS must be in output mode even it is not chip select
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
302 pinMode(SS_PIN, OUTPUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
303 // set SS high - may be chip select for another SPI device
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
304 #if SET_SPI_SS_HIGH
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
305 digitalWrite(SS_PIN, HIGH);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
306 #endif // SET_SPI_SS_HIGH
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
307 // set SCK rate for initialization commands
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
308 spiRate_ = SPI_SD_INIT_RATE;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
309 spiInit(spiRate_);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
310 #endif // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
311
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
312 // must supply min of 74 clock cycles with CS high.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
313 for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
314
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
315 // command to go idle in SPI mode
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
316 while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
317 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
318 error(SD_CARD_ERROR_CMD0);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
319 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
320 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
321 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
322 // check SD version
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
323 if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
324 type(SD_CARD_TYPE_SD1);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
325 } else {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
326 // only need last byte of r7 response
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
327 for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
328 if (status_ != 0XAA) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
329 error(SD_CARD_ERROR_CMD8);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
330 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
331 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
332 type(SD_CARD_TYPE_SD2);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
333 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
334 // initialize card and send host supports SDHC if SD2
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
335 arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
336
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
337 while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
338 // check for timeout
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
339 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
340 error(SD_CARD_ERROR_ACMD41);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
341 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
342 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
343 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
344 // if SD2 read OCR register to check for SDHC card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
345 if (type() == SD_CARD_TYPE_SD2) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
346 if (cardCommand(CMD58, 0)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
347 error(SD_CARD_ERROR_CMD58);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
348 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
349 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
350 if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
351 // discard rest of ocr - contains allowed voltage range
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
352 for (uint8_t i = 0; i < 3; i++) spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
353 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
354 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
355
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
356 #ifndef SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
357 return setSckRate(sckRateID);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
358 #else // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
359 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
360 #endif // SOFTWARE_SPI
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
361
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
362 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
363 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
364 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
365 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
366 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
367 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
368 * Read a 512 byte block from an SD card.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
369 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
370 * \param[in] blockNumber Logical block to be read.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
371 * \param[out] dst Pointer to the location that will receive the data.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
372
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
373 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
374 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
375 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
376 bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
377 // use address if not SDHC card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
378 if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
379 if (cardCommand(CMD17, blockNumber)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
380 error(SD_CARD_ERROR_CMD17);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
381 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
382 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
383 return readData(dst, 512);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
384
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
385 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
386 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
387 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
388 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
389 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
390 /** Read one data block in a multiple block read sequence
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
391 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
392 * \param[in] dst Pointer to the location for the data to be read.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
393 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
394 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
395 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
396 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
397 bool Sd2Card::readData(uint8_t *dst) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
398 chipSelectLow();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
399 return readData(dst, 512);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
400 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
401 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
402 bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
403 // wait for start block token
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
404 uint16_t t0 = millis();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
405 while ((status_ = spiRec()) == 0XFF) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
406 if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
407 error(SD_CARD_ERROR_READ_TIMEOUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
408 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
409 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
410 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
411 if (status_ != DATA_START_BLOCK) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
412 error(SD_CARD_ERROR_READ);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
413 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
414 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
415 // transfer data
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
416 spiRead(dst, count);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
417
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
418 // discard CRC
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
419 spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
420 spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
421 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
422 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
423
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
424 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
425 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
426 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
427 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
428 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
429 /** read CID or CSR register */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
430 bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
431 uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
432 if (cardCommand(cmd, 0)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
433 error(SD_CARD_ERROR_READ_REG);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
434 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
435 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
436 return readData(dst, 16);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
437
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
438 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
439 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
440 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
441 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
442 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
443 /** Start a read multiple blocks sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
444 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
445 * \param[in] blockNumber Address of first block in sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
446 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
447 * \note This function is used with readData() and readStop() for optimized
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
448 * multiple block reads. SPI chipSelect must be low for the entire sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
449 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
450 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
451 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
452 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
453 bool Sd2Card::readStart(uint32_t blockNumber) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
454 if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
455 if (cardCommand(CMD18, blockNumber)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
456 error(SD_CARD_ERROR_CMD18);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
457 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
458 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
459 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
460 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
461
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
462 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
463 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
464 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
465 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
466 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
467 /** End a read multiple blocks sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
468 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
469 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
470 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
471 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
472 bool Sd2Card::readStop() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
473 chipSelectLow();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
474 if (cardCommand(CMD12, 0)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
475 error(SD_CARD_ERROR_CMD12);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
476 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
477 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
478 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
479 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
480
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
481 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
482 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
483 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
484 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
485 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
486 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
487 * Set the SPI clock rate.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
488 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
489 * \param[in] sckRateID A value in the range [0, 6].
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
490 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
491 * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
492 * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
493 * for \a scsRateID = 6.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
494 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
495 * \return The value one, true, is returned for success and the value zero,
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
496 * false, is returned for an invalid value of \a sckRateID.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
497 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
498 bool Sd2Card::setSckRate(uint8_t sckRateID) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
499 if (sckRateID > 6) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
500 error(SD_CARD_ERROR_SCK_RATE);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
501 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
502 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
503 spiRate_ = sckRateID;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
504 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
505 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
506 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
507 // wait for card to go not busy
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
508 bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
509 uint16_t t0 = millis();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
510 while (spiRec() != 0XFF) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
511 if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
512 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
513 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
514
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
515 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
516 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
517 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
518 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
519 /**
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
520 * Writes a 512 byte block to an SD card.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
521 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
522 * \param[in] blockNumber Logical block to be written.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
523 * \param[in] src Pointer to the location of the data to be written.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
524 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
525 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
526 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
527 bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
528 // use address if not SDHC card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
529 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
530 if (cardCommand(CMD24, blockNumber)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
531 error(SD_CARD_ERROR_CMD24);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
532 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
533 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
534 if (!writeData(DATA_START_BLOCK, src)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
535
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
536 // wait for flash programming to complete
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
537 if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
538 error(SD_CARD_ERROR_WRITE_TIMEOUT);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
539 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
540 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
541 // response is r2 so get and check two bytes for nonzero
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
542 if (cardCommand(CMD13, 0) || spiRec()) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
543 error(SD_CARD_ERROR_WRITE_PROGRAMMING);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
544 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
545 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
546 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
547 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
548
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
549 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
550 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
551 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
552 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
553 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
554 /** Write one data block in a multiple block write sequence
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
555 * \param[in] src Pointer to the location of the data to be written.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
556 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
557 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
558 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
559 bool Sd2Card::writeData(const uint8_t* src) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
560 chipSelectLow();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
561 // wait for previous write to finish
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
562 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
563 if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
564 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
565 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
566
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
567 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
568 error(SD_CARD_ERROR_WRITE_MULTIPLE);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
569 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
570 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
571 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
572 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
573 // send one block of data for write block or write multiple blocks
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
574 bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
575 spiSendBlock(token, src);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
576
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
577 spiSend(0xff); // dummy crc
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
578 spiSend(0xff); // dummy crc
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
579
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
580 status_ = spiRec();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
581 if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
582 error(SD_CARD_ERROR_WRITE);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
583 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
584 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
585 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
586
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
587 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
588 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
589 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
590 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
591 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
592 /** Start a write multiple blocks sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
593 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
594 * \param[in] blockNumber Address of first block in sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
595 * \param[in] eraseCount The number of blocks to be pre-erased.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
596 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
597 * \note This function is used with writeData() and writeStop()
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
598 * for optimized multiple block writes.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
599 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
600 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
601 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
602 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
603 bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
604 // send pre-erase count
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
605 if (cardAcmd(ACMD23, eraseCount)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
606 error(SD_CARD_ERROR_ACMD23);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
607 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
608 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
609 // use address if not SDHC card
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
610 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
611 if (cardCommand(CMD25, blockNumber)) {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
612 error(SD_CARD_ERROR_CMD25);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
613 goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
614 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
615 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
616 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
617
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
618 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
619 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
620 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
621 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
622 //------------------------------------------------------------------------------
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
623 /** End a write multiple blocks sequence.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
624 *
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
625 * \return The value one, true, is returned for success and
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
626 * the value zero, false, is returned for failure.
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
627 */
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
628 bool Sd2Card::writeStop() {
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
629 chipSelectLow();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
630 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
631 spiSend(STOP_TRAN_TOKEN);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
632 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
633 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
634 return true;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
635
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
636 fail:
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
637 error(SD_CARD_ERROR_STOP_TRAN);
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
638 chipSelectHigh();
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
639 return false;
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
640 }
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
641
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
642
2c8ba1964db7 Initial code from reprappro Marlin repository
mbayer
parents:
diff changeset
643 #endif

mercurial