Add SD library

trunk
alexis 5 months ago
parent 6814cb57dd
commit 14d026d81d

@ -0,0 +1,7 @@
intellectual property is bullshit. be gay, do crime
some of this code comes from people who like licenses. if you care about that
kinda shit see the accompanying license files. i'm supposed to mention them
here:
sd-spi/: Wade Penson, 2015, Apache 2.0

@ -1,14 +1,16 @@
project('poly1', 'cpp', default_options: ['optimization=s', 'cpp_std=c++17'])
project('poly1', ['cpp', 'c'], default_options: ['optimization=s', 'cpp_std=c++17'])
atpack_zip = 'Microchip.AVR-Dx_DFP.2.1.152.atpack'
dependencies = []
local_headers = ['.', 'etl/include']
local_headers = ['.', 'etl/include', 'sd-spi']
sources = [
'main.cpp',
'board.cpp',
'midix.cpp',
'sd-spi/sd_spi.c',
'sd-spi/sd_spi_platform_dependencies.c',
]
_includes = local_headers

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,2 @@
From https://github.com/wpenson/sd-spi-communications-library
See LICENSE

File diff suppressed because it is too large Load Diff

@ -0,0 +1,530 @@
/******************************************************************************/
/**
@file sd_spi.h
@author Wade Penson
@date June, 2015
@brief SD RAW library header.
@details This library supports MMC, SD1, SD2, and SDHC/SDXC type cards.
By defining SD_BUFFER, the library also implements a 512 byte buffer
for reading and writing.
@copyright Copyright 2015 Wade Penson
@license Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
@todo Support for AVR and SAMX AVR without using the Arduino SPI library.
@todo Support for using Software SPI (bit banging).
@todo Use CMD6 during initialization to switch card to high speed mode if
it supports it. This will be helpful for the due since the SPI
speed can be up to 84MHz.
@todo Allow setting CS high when card is in busy state for operations
instead of waiting. However, if an error is thrown for the
operation, the host will get that error on the next command it
sends.
@todo Send_status should be sent after all busy signals
(look at ch 4.3.7).
@todo Send stop_transmission if there was an error during
write continuous (and read continuous??).
@todo Get the number of well written blocks for sequential writing just in
case if there was an error.
@todo Card reads take up to 100ms and writes take up to 500ms. Make
timeouts reflect this.
@todo Reduce the number of error codes.
*/
/******************************************************************************/
#if !defined(SD_SPI_H_)
#define SD_SPI_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include <string.h>
#include <stdint.h>
#include "sd_spi_info.h"
#include "sd_spi_commands.h"
/** Define to enable the block buffer. */
#define SD_SPI_BUFFER
/** State variables used by the SD raw library. */
typedef struct sd_spi_card {
/** Digital pin for setting CS high or low. */
uint8_t chip_select_pin: 8;
/** The speed of the SPI bus. Use 0 for 25KHz and 1 for 25MHz. */
uint8_t spi_speed: 3;
/** Determines if the card is MMC, SD1, SD2, or SDHC/SDXC. */
uint8_t card_type: 3;
/** Flag to see if CS has already been set to high or low. */
uint8_t is_chip_select_high: 1;
/** True if currently reading continually and false otherwise. */
uint8_t is_read_write_continuous: 1;
/** True if currently writing continually and false otherwise. */
uint8_t is_write_continuous: 1;
/** If the card is being read or written to continually, this keeps track
of the block being read or written to. */
uint32_t continuous_block_address;
#if defined(SD_SPI_BUFFER)
/** Buffer for SD blocks. */
uint8_t sd_spi_buffer[512];
/** The address of the block currently being buffered. */
uint32_t buffered_block_address;
/** Keeps track of the consistency of the buffer for reading. */
uint8_t is_buffer_current: 1;
/** Keeps track if the buffer has been flushed or not. */
uint8_t is_buffer_written: 1;
#endif
} sd_spi_card_t;
/**
@defgroup sd_spi_timeouts SD Timeouts
@brief Timeouts are used so that the SD does not freeze on
a task if a failure occurs.
@{
*/
#define SD_INIT_TIMEOUT 5000
#define SD_WRITE_TIMEOUT 5000
#define SD_READ_TIMEOUT 5000
#define SD_ERASE_TIMEOUT 500000
/** @} End of group sd_spi_timeouts */
/**
@defgroup sd_spi_card_types SD/MMC Card Types
@brief Types of cards.
@{
*/
#define SD_CARD_TYPE_UNKNOWN 0
#define SD_CARD_TYPE_SD1 1
#define SD_CARD_TYPE_SD2 2
#define SD_CARD_TYPE_SDHC 3
#define SD_CARD_TYPE_MMC 4
/** @} End of group sd_spi_card_types */
/**
@defgroup sd_spi_error_codes SD Error Codes
@brief Error codes for the SD library.
@{
*/
#define SD_ERR_OK 0
#define SD_ERR_ALREADY_INITIALIZED 1
#define SD_ERR_NOT_INITIALIZED 2
#define SD_ERR_UNKNOWN_CARD_TYPE 3
#define SD_ERR_INIT_TIMEOUT 4
#define SD_ERR_COMMAND_TIMEOUT 5
#define SD_ERR_OUTSIDE_VOLTAGE_RANGE 6
#define SD_ERR_SEND_IF_COND_WRONG_TEST_PATTERN 7
#define SD_ERR_OCR_REGISTER 8
#define SD_ERR_SETTING_BLOCK_LENGTH 9
#define SD_ERR_ILLEGAL_COMMAND 10
#define SD_ERR_COMMUNICATION_CRC 11
#define SD_ERR_ILLEGAL_ADDRESS 12
#define SD_ERR_ILLEGAL_PARAMETER 13
#define SD_ERR_CARD_IS_LOCKED 14
#define SD_ERR_CARD_CONTROLLER 15
#define SD_ERR_CARD_ECC_FAILURE 16
#define SD_ERR_ARGUMENT_OUT_OF_RANGE 17
#define SD_ERR_GENERAL 18
#define SD_ERR_WRITE_FAILURE 19
#define SD_ERR_WRITE_TIMEOUT 20
#define SD_ERR_WRITE_OUTSIDE_OF_BLOCK 21
#define SD_ERR_WRITE_DATA_REJECTED 22
#define SD_ERR_WRITE_DATA_CRC_REJECTED 23
#define SD_ERR_WRITE_PRE_ERASE 24
#define SD_ERR_WRITE_PROTECTION_VIOLATION 25
#define SD_ERR_READ_FAILURE 26
#define SD_ERR_READ_TIMEOUT 27
#define SD_ERR_READ_OUTSIDE_OF_BLOCK 28
#define SD_ERR_READ_WRITE_CONTINUOUS 29
#define SD_ERR_ERASE_FAILURE 30
#define SD_ERR_ERASE_TIMEOUT 31
#define SD_ERR_ERASE_RESET 32
#define SD_ERR_WRITE_PROTECTION_ERASE_SKIP 33
#define SD_ERR_ERASE_PARAMETER 34
#define SD_ERR_ERASE_SEQUENCE 35
#define SD_ERR_READ_REGISTER 36
/** @} End of group sd_spi_error_codes */
/* R1 token responses */
#define SD_IN_IDLE_STATE 0x01
#define SD_ERASE_RESET 0x02
#define SD_ILLEGAL_COMMAND 0x04
#define SD_COMMUNICATION_CRC_ERR 0x08
#define SD_ERASE_SEQUENCE_ERR 0x10
#define SD_ADDRESS_ERR 0x20
#define SD_PARAMETER_ERR 0x40
/* R2 token responses */
#define SD_CARD_IS_LOCKED 0x01
#define SD_WP_ERASE_SKIP 0x02
#define SD_GENERAL_ERR 0x04
#define SD_CC_ERR 0x08
#define SD_CARD_ECC_FAILURE 0x10
#define SD_WP_VIOLATION 0x20
#define SD_ERASE_PARAM 0x40
#define SD_OUT_OF_RANGE 0x80
/* Reading and writing tokens */
#define SD_TOKEN_START_BLOCK 0xFE
#define SD_TOKEN_MULTIPLE_WRITE_START_BLOCK 0xFC
#define SD_TOKEN_MULTIPLE_WRITE_STOP_TRANSFER 0xFD
#define SD_TOKEN_DATA_ACCEPTED 0x05
#define SD_TOKEN_DATA_REJECTED_CRC 0x0B
#define SD_TOKEN_DATA_REJECTED_WRITE_ERR 0x0D
/**
@brief Initializes the card with the given chip select pin.
@details The card is put into a state where it can be sent read, write, and
other commands.
@param chip_select_pin The digital pin connected to the CS on the card.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_init(
uint8_t chip_select_pin
);
/**
@brief Writes data to a block on the card.
@details If buffering is enabled, the card will read the block on the card
into the buffer. The passed in data will then be stored in
the buffer. The data will be only written out to the card when a
different block is written to, read is called, write is called,
erase is called, or sd_spi_flush() is explicitly called.
If buffering is not enabled, the card will write out the data and
pad the rest of the block with zeros if number_of_bytes is less
than 512.
@param block_address The address of the block on the card.
@param[in] data An array of data / an address to the data in
memory.
@param number_of_bytes The size of the data in bytes.
@param byte_offset The byte offset of where to start writing in the
block.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write(
uint32_t block_address,
void *data,
uint16_t number_of_bytes,
uint16_t byte_offset
);
/**
@brief Writes a block of data to a block on the card.
@details When buffering is enabled, this is faster than using sd_spi_write
since it does not buffer in the block from the card.
@param block_address The address of the block on the card.
@param[in] data An array of data / an address to the data in
memory.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write_block(
uint32_t block_address,
void *data
);
/**
@brief Writes out the data in the buffer to the card if it has not been
flushed already. If writing continually, this will also advance to
the next block in the sequence.
@details This is to be used in conjunction with sd_spi_write or
sd_spi_continuous_write.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_flush(
void
);
/**
@brief Notifies the card to prepare for sequential writing starting at the
specified block address.
@details A sequential write must be stopped by calling
sd_spi_write_continuous_stop(). When buffering is enabled, use
sd_spi_write_continuous() in conjunction with sd_spi_write_next().
If buffering is disabled, use sd_spi_write_continuous() to write out
the data and it will advance to the next block in the sequence
automatically.
@param start_block_address The address of the first block in the
sequence.
@param num_blocks_pre_erase (Optional) The number of block to pre-erase
to potentially speed up writing. It can be
set to 0 if the number if the number of
blocks is unknown or an estimate can be
given since it does not have to be exact.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write_continuous_start(
uint32_t start_block_address,
uint32_t num_blocks_pre_erase
);
/**
@brief Writes data to the current block in the sequence on the card.
@details If buffering is enabled, the data will be stored in the buffer which
has been cleared with zeros (current data in the block on the card
is not pre-buffered). The data will be only written out to the card
when sd_spi_write_continuous_next() or sd_spi_flush() is explicitly
called. If the buffering is not enabled, the card will write out the
data and advance to the next block in the sequence. If the number of
bytes given is less than 512, the rest of the block will be padded
with zeros.
@param[in] data An array of data / an address to the data in
memory.
@param number_of_bytes The size of the data in bytes.
@param byte_offset The byte offset of where to start writing in the
block.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write_continuous(
void *data,
uint16_t number_of_bytes,
uint16_t byte_offset
);
/**
@brief Used only when buffering is enabled to write out the data in the
buffer to the card for continuous writing and advancing to the
next block in the sequence.
@details If buffering is not enabled, only use sd_spi_write_continuous().
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write_continuous_next(
void
);
/**
@brief Notifies the card to stop sequential writing and flushes the buffer
to the card if buffering is enabled.
@details This may take some time since it waits for the card to complete the
write.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_write_continuous_stop(
void
);
/**
@brief Reads data from a block on the card.
@details If buffering is enabled, this will write in the block to the buffer.
Otherwise, the device will have to read in the data from the card
on every call (it has to read a 512 byte block only the relevant
data will be kept).
@param block_address The address of the block on the card.
@param[out] data_buffer A location in memory to write the data to.
@param number_of_bytes The number of bytes to read.
@param byte_offset The byte offset of where to start reading in the
block.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read(
uint32_t block_address,
void *data_buffer,
uint16_t number_of_bytes,
uint16_t byte_offset
);
/**
@brief Notifies the card to prepare for sequential reading starting at the
specified block address.
@details A sequential read must be stopped by calling
sd_spi_read_continuous_stop(). When buffering is enabled, use
sd_spi_read_continuous() in conjunction with sd_spi_read_next().
If buffering is disabled, use sd_spi_read_block() to read in data
and advance to the next block in the sequence.
@param start_block_address The address of the first block in the
sequence.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_continuous_start(
uint32_t start_block_address
);
/**
@brief Reads in data from the current block in the sequence on the card.
@details If buffering is enabled, the block will be stored in the buffer.
To advance to the next block, sd_spi_read_continuous_next() must
be explicitly called. If the buffering is not enabled, the card will
read in the data and advance to the next block in the sequence.
@param[out] data_buffer A location in memory to write the data to.
@param number_of_bytes The number of bytes to read.
@param byte_offset The byte offset of where to start reading in the
block.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_continuous(
void *data_buffer,
uint16_t number_of_bytes,
uint16_t byte_offset
);
/**
@brief Used only when buffering is enabled to advancing to the
next block in the sequence.
@details If buffering is not enabled, only use sd_spi_read_continuous().
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_continuous_next(
void
);
/**
@brief Notifies the card to stop sequential reading.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_continuous_stop(
void
);
/**
@brief Erases all the blocks on the card.
@details All of the bits will be set with the default value of 0 or 1
HC depending on the card.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_erase_all(
void
);
/**
@brief Erases the given sequence of blocks on the card.
@details All of the bits will be set with the default value of 0 or 1
depending on the card.
@param start_block_address The address of the first block in the
sequence.
@param end_block_address The address of the last block in the
sequence.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_erase_blocks(
uint32_t start_block_address,
uint32_t end_block_address
);
/**
@brief Gets the number of blocks the card has. Blocks are 512 bytes.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
uint32_t
sd_spi_card_size(
void
);
/**
@brief Gets the type of the card. 1 = SD1, 2 = SD2, 3 = SDHC, and 4 = MMC.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
uint8_t
sd_spi_card_type(
void
);
/**
@brief Reads the Card Identification (CID) register on the card.
@details Information is stored in the sd_spi_cid_t structure. The details of
the structure can be found in sd_spi_info.h.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_cid_register(
sd_spi_cid_t *cid
);
/**
@brief Reads the Card Specific Data (CSD) register on the card.
@details Information is stored in the sd_spi_csd_t structure. The details of
the structure can be found in sd_spi_info.h.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_read_csd_register(
sd_spi_csd_t *csd
);
/**
@brief Returns the first error code (if any) found in the R2 response on
from the card.
@return An error code as defined by one of the SD_ERR_* definitions.
*/
int8_t
sd_spi_card_status(
void
);
/**
@brief Getter for the address of the block that is currently buffered.
@return Current buffered block address.
*/
uint32_t
sd_spi_current_buffered_block(
void
);
#if defined(__cplusplus)
}
#endif
#endif /* SD_SPI_H_ */

@ -0,0 +1,280 @@
/******************************************************************************/
/**
@file sd_spi_commands.h
@author Wade Penson
@date June, 2015
@brief SPI bus commands for SD/MMC.
@details The set of commands can be found in the simplified physical
SD specifications from the SD Association.
@copyright Copyright 2015 Wade Penson
@license Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*/
/******************************************************************************/
#if !defined(SD_SPI_COMMANDS_H_)
#define SD_SPI_COMMANDS_H_
#if defined(__cplusplus)
extern "C" {
#endif
/**
@brief CMD0: Resets card.
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_CMD_GO_IDLE_STATE 0x00
/**
@brief CMD1: Host sends HCS (Host Capacity Support) information. The card then
initializes.
@param [31] Zero bit
@param [30] HCS
@param [29:0] Zero bits
@return Register R1
*/
#define SD_CMD_SEND_OP_COND 0x01
/**
@brief CMD8: Host sends supply voltage and card replies with whether the card
can operate based on the voltage or not.
@param [31:12] Zero bits
@param [11:8] Supply voltage range
@param [7:0] Check pattern
@return Register R7
*/
#define SD_CMD_SEND_IF_COND 0x08
/**
@brief CMD9: Get the card specific data (CSD).
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_CMD_SEND_CSD 0x09
/**
@brief CMD10: Get the card identification (CID).
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_CMD_SEND_CID 0x0A
/**
@brief CMD12: Stops the transmission for the multiple block read operation.
@param [31:0] Stuff bits
@return Register R1b (R1 with busy signal after)
*/
#define SD_CMD_STOP_TRANSMISSION 0x0C
/**
@brief CMD13: Get status from status register.
@param [31:0] Stuff bits
@return Register R2
*/
#define SD_CMD_SEND_STATUS 0x0D
/**
@brief CMD16: Sets the block length, in bytes, for read and write commands of a
standard capacity card. However, the standard capacity cards usually
only support this command for the read commands. SDHC and SHXC only
support reading and writing blocks of size 512 bytes.
@param [31:0] Block length
@return Register R1
*/
#define SD_CMD_SET_BLOCKLEN 0x10
/**
@brief CMD17: Read a single block. The size can be set using CMD_SET_BLOCKLEN
for standard capacity cards.
@param [31:0] Data address. The address is determined by bytes for standard sd
cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_READ_SINGLE_BLOCK 0x11
/**
@brief CMD18: Read blocks continuously and end transmission by sending
CMD_STOP_TRANSMISSION.
@param [31:0] Data address. The address is determined by bytes for standard
sd cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_READ_MULTIPLE_BLOCK 0x12
/**
@brief CMD24: Write a single block.
@param [31:0] Data address. The address is determined by bytes for standard
sd cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_SET_WRITE_BLOCK 0x18
/**
@brief CMD25: Write blocks continuously and end transmission by sending
STOP_TRAN_TOKEN.
@param [31:0] Data address. The address is determined by bytes for standard
sd cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_WRITE_MULTIPLE_BLOCK 0x19
/**
@brief CMD27: Program the programmable bits of the CSD. These include being
able to write multiple times to the TMP_WRITE_PROTECT and CRC fields
and writing a single time to the FILE_FORMAT_GRP, COPY,
PERM_WRITE_PROTECT, and FILE_FORMAT fields.
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_CMD_PROGRAM_CSD 0x1B
/**
@brief CMD28: Sets write protection for the addressed group for standard
capacity cards that support write protected features. WP_GRP_ENABLE
in the CSD register can be used to determine if this command is
supported and WP_GROUP_SIZE determines the size of a group.
@param [31:0] Data address
@return Register R1b (R1 with busy signal after)
*/
#define SD_CMD_SET_WRITE_PROT 0x1C
/**
@brief CMD29: Clears write protection for the addressed group for standard
capacity cards that support write protected features. WP_GRP_ENABLE
in the CSD register can be used to determine if this command is
supported and WP_GROUP_SIZE determines the size of a group.
@param [31:0] Data address
@return Register R1b (R1 with busy signal after)
*/
#define SD_CMD_CLR_WRITE_PROT 0x1D
/**
@brief CMD30: Send status of the addressed group for standard capacity cards
that support write protected features. WP_GRP_ENABLE in the CSD register
can be used to determine if this command is supported and WP_GROUP_SIZE
determines the size of a group.
@param [31:0] Data address
@return Register R1
*/
#define SD_CMD_SEND_WRITE_PROT 0x1E
/**
@brief CMD32: Sets the address of the first block for writing to be erased.
@param [31:0] Data address. The address is determined by bytes for standard
sd cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_ERASE_WR_BLK_START 0x20
/**
@brief CMD33: Sets the address of the last block for writing to be erased.
@param [31:0] Data address. The address is determined by bytes for standard
sd cards and by blocks (512 bytes) for SDHC and SHXC cards.
@return Register R1
*/
#define SD_CMD_ERASE_WR_BLK_END 0x21
/**
@brief CMD38: Erase the blocks selected by CMD_ERASE_WR_BLK_START and
CMD_ERASE_WR_BLK_END.
@param [31:0] Stuff bits
@return Register R1b (R1 with busy signal after)
*/
#define SD_CMD_ERASE 0x26
/**
@brief CMD58: Reads OCR register. CCS bit is assigned to OCR[30].
@param [31:0] Stuff bits
@return Register R3
*/
#define SD_CMD_READ_OCR 0x3A
/**
@brief CMD59: Turns CRC on or off.
@param [31:1] Stuff bits
@param [0:0] A '1' to turn CRC on and '0' to turn CRC off
@return Register R1
*/
#define SD_CMD_CRC_ON_OFF 0x3B
/**
@brief CMD55: Tells the card that the next command is an application specific
command (ACMD).
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_CMD_APP 0x37
/**
@brief CMD56: For application specific commands, transfer a datablock to or
from the card.
@param [31:1] Stuff bits
@param [0:0] A '1' for reading data and '0' for writing data
@return Register R1
*/
#define SD_CMD_GEN 0x38
/**
@brief ACMD13: Get the SD status.
@param [31:0] Stuff bits
@return Register R2
*/
#define SD_ACMD_STATUS 0x0D
/**
@brief ACMD22: Get the number of blocks that were written without errors.
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_ACMD_SEND_NUM_WR_BLOCKS 0x16
/**
@brief ACMD23: Set the number of blocks to be erased before writing.
@param [31:23] Stuff bits
@param [22:0] Number of blocks
@return Register R1
*/
#define SD_ACMD_SET_WR_BLK_ERASE_COUNT 0x17
/**
@brief ACMD41: Host sends HCS (Host Capacity Support) information. The card
then initializes.
@param [31] Zero bit
@param [30] HCS
@param [29:0] Zero bits
@return Register R1
*/
#define SD_ACMD_SEND_OP_COND 0x29
/**
@brief ACMD42: Connects or disconnects the pull-up resistor on the CS pin of
the card. May be used for card detection.
@param [31:1] Stuff bits
@param [0:0] A '1' to connect pull-up and '0' to disconnect pull-up
@return Register R1
*/
#define SD_ACMD_SET_CLR_CARD_DETECT 0x2A
/**
@brief ACMD51: Reads SCR (SD configuration) register.
@param [31:0] Stuff bits
@return Register R1
*/
#define SD_ACMD_SEND_SCR 0x33
#if defined(__cplusplus)
}
#endif
#endif /* SD_SPI_COMMANDS_H_ */

@ -0,0 +1,201 @@
/******************************************************************************/
/**
@file sd_spi_info.h
@author Wade Penson
@date June, 2015
@brief Structures to store information from CID (Card Identification)
and CSD (Card Specific Data) registers for SD cards.
@details Information about the fields can be found in the simplified
physical SD specifications from the SD Association.
@copyright Copyright 2015 Wade Penson
@license Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*/
/******************************************************************************/
#if !defined(SD_SPI_INFO_H_)
#define SD_SPI_INFO_H_
#if defined(__cplusplus)
extern "C" {
#endif
/**
@brief CID register information
*/
typedef struct sd_spi_cid
{
/** Manufacturer ID. */
unsigned int mid: 8;
/** OEM/Application ID. Composed of 2 characters. */
char oid[2];
/** Product name. Composed of 5 characters. */
char pnm[5];
/** n part of the product revision number, which is in the form of n.m */
unsigned int prv_n: 4;
/** m part of the product revision number, which is in the form of n.m */
unsigned int prv_m: 4;
/** Bits [31:24] of the 4 byte product serial number. */
unsigned int psn_high: 8;
/** Bits [23:16] of the 4 byte product serial number. */
unsigned int psn_mid_high: 8;
/** Bits [15:8] of the 4 byte product serial number. */
unsigned int psn_mid_low: 8;
/** Bits [7:0] of the 4 byte product serial number. */
unsigned int psn_low: 8;
/** Year manufactured. */
unsigned int mdt_year: 8;
/** Month manufactured. */
unsigned int mdt_month: 4;
/* Bitfield padding */
unsigned int: 4;
/** Checksum for the CID. */
unsigned int crc: 7;
/* Bitfield padding */
unsigned int: 1;
} sd_spi_cid_t;
/**
@brief Information exclusive to CSD register version 1.
@details The following formula is used to compute the card's size:<br><br>
Card size in MB = Number of blocks * 512 / 1000000<br>
Number of blocks = ((c_size + 1) * 2<SUP>c_size_mult + 2</SUP>) *
(2<SUP>max_read_bl_len</SUP> / 512)<br>
*/
typedef struct sd_spi_csd_v1
{
/** Low bits of c_size. Used to compute the card's size. */
unsigned int c_size_low: 8;
/** High bits of c_size. Used to compute the card's size. */
unsigned int c_size_high: 4;
/** Max read current for minimal supply voltage. */
unsigned int vdd_r_curr_min: 3;
/* Bitfield padding */
unsigned int: 1;
/** Max read current for max supply voltage. */
unsigned int vdd_r_curr_max: 3;
/** Max write current for minimal supply voltage. */
unsigned int vdd_w_curr_min: 3;
/* Bitfield padding */
unsigned int: 2;
/** Max write current for max supply voltage. */
unsigned int vdd_w_curr_max: 3;
/** Multiplier used to compute the card's size. */
unsigned int c_size_mult: 3;
/* Bitfield padding */
unsigned int: 2;
} sd_spi_csd_v1_t;
/**
@brief Information exclusive to CSD register version 2
@details The card size is computed as follows:<br><br>
Card size in MB = (c_size + 1) * 512 / 1000
*/
typedef struct sd_spi_csd_v2
{
/** Low bits of c_size. Used to compute the card's size. */
unsigned int c_size_low: 8;
/** Mid bits of c_size. Used to compute the card's size. */
unsigned int c_size_mid: 8;
/** High bits of c_size. Used to compute the card's size. */
unsigned int c_size_high: 6;
/* Bitfield padding */
unsigned int: 2;
} sd_spi_csd_v2_t;
/**
@brief The CSD register is either version 1 or version 2. Space is saved by
unioning the specific version information for version 1 and 2. The
csd_v1 structure is for version 1 and the csd_v2 is for version 2.
*/
typedef union sd_spi_csd_v_info
{
sd_spi_csd_v1_t v1;
sd_spi_csd_v2_t v2;
} sd_spi_csd_v_info_t;
/**
@brief CSD register information
@details The CSD version is determined by the csd_structure value. If the
value is 0, the CSD is version 1 so the csvi will contain the
v1 type specific information. Otherwise, the CSD is version 2 so
the csvi will contain the v2 type specific information. Further
details about the fields can be found in the SD specifications.
*/
typedef struct sd_spi_csd
{
/** Union of the CSD version specific info. */
sd_spi_csd_v_info_t cvsi;
/** CSD version. */
unsigned int csd_structure: 2;
/** The file format of the card. */
unsigned int file_format: 2;
/* Bitfield padding */
unsigned int: 4;
/** Asynchronous part of data access time. Table of the corresponding
values are found in the SD specifications. */
unsigned int taac: 8;
/** Worst case for the clock dependent factor of the data access time.*/
unsigned int nsac: 8;
/** Max data transfer speed for a single data line. */
unsigned int tran_speed: 8;
/** Low bits of the ccc; the command class of the card. */
unsigned int ccc_low: 8;
/** High bits of the ccc; the command class of the card. */
unsigned int ccc_high: 4;
/** Max block length. */
unsigned int max_read_bl_len: 4;
/** Defines if the card can read partial blocks. */
unsigned int read_bl_partial: 1;
/** Defines if a data block can be spanned over a block boundary when
written. */
unsigned int write_bl_misalign: 1;
/** Defines if a data can be read over block boundaries. */
unsigned int read_bl_misalign: 1;
/** Defines if the configurable driver stage is implemented in the card. */
unsigned int dsr_imp: 1;
/** Defines the unit size of data being erased. */
unsigned int erase_bl_en: 1;
/** Ratio of read to write time. */
unsigned int r2w_factor: 3;
/** The size of an erasable sector. */
unsigned int erase_sector_size: 7;
/** Defines if write group protection is possible. */
unsigned int wp_grp_enable: 1;
/** The size of a write protected group. */
unsigned int wp_grp_size: 7;
/** Defines if the card can write partial blocks. */
unsigned int write_bl_partial: 1;
/** The max write block length. */
unsigned int write_bl_len: 4;
/** The file format group of the card. */
unsigned int file_format_grp: 1;
/** Defines if the cards content is original or is a copy. */
unsigned int copy: 1;
/** Determines if the card is permanently write protected or not. */
unsigned int perm_write_protect: 1;
/** Determines if the card is temporarily write protected or not. */
unsigned int tmp_write_protect: 1;
/** Checksum for the CSD. */
unsigned int crc: 7;
/* Bitfield padding */
unsigned int: 1;
} sd_spi_csd_t;
#if defined(__cplusplus)
}
#endif
#endif /* SD_SPI_INFO_H_ */

@ -0,0 +1,67 @@
#include "sd_spi_platform_dependencies.h"
void
sd_spi_pin_mode(
uint8_t pin,
uint8_t mode
)
{
}
void
sd_spi_digital_write(
uint8_t pin,
uint8_t state
)
{
}
uint32_t
sd_spi_millis(
void
)
{
}
void
sd_spi_begin(
void
)
{
}
void
sd_spi_begin_transaction(
uint32_t transfer_speed_hz
)
{
}
void
sd_spi_end_transaction(
void
)
{
}
void
sd_spi_send_byte(
uint8_t b
)
{
}
uint8_t
sd_spi_receive_byte(
void
)
{
}

@ -0,0 +1,94 @@
/******************************************************************************/
/**
@file sd_spi_platform_dependencies.cpp
@author Wade Penson
@date June, 2015
@brief Interface for the dependencies needed by the SD SPI library.
@copyright Copyright 2015 Wade Penson
@license Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*/
/******************************************************************************/
#if !defined(SD_SPI_PLATFORM_DEPENDENCIES_H_)
#define SD_SPI_PLATFORM_DEPENDENCIES_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdint.h>
#if !defined(INPUT)
#define INPUT 0
#endif
#if !defined(OUTPUT)
#define OUTPUT 1
#endif
#if !defined(LOW)
#define LOW 0
#endif
#if !defined(HIGH)
#define HIGH 1
#endif
void
sd_spi_pin_mode(
uint8_t pin,
uint8_t mode
);
void
sd_spi_digital_write(
uint8_t pin,
uint8_t state
);
uint32_t
sd_spi_millis(
void
);
void
sd_spi_begin(
void
);
void
sd_spi_begin_transaction(
uint32_t transfer_speed_hz
);
void
sd_spi_end_transaction(
void
);
void
sd_spi_send_byte(
uint8_t b
);
uint8_t
sd_spi_receive_byte(
void
);
#if defined(__cplusplus)
}
#endif
#endif /* SD_SPI_PLATFORM_DEPENDENCIES_H_ */
Loading…
Cancel
Save