diff --git a/lib/flash_sdcard.c b/lib/flash_sdcard.c
new file mode 100644
index 0000000..aa16655
--- /dev/null
+++ b/lib/flash_sdcard.c
@@ -0,0 +1,225 @@
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/** library to communicate with an SD card flash memory using the SPI mode (code)
+ * @file flash_sdcard.c
+ * @author King Kévin
+ * @date 2017
+ * @note peripherals used: SPI @ref flash_sdcard_spi
+ * @warning all calls are blocking
+ * @implements SD Specifications, Part 1, Physical Layer, Simplified Specification, Version 6.00, 10 April 10 2017
+ */
+
+/* standard libraries */
+#include // standard integer types
+#include // general utilities
+
+/* STM32 (including CM3) libraries */
+#include // Cortex M3 utilities
+#include // real-time control clock library
+#include // general purpose input output library
+#include // SPI library
+
+#include "global.h" // global utilities
+#include "flash_sdcard.h" // SD card header and definitions
+
+/** @defgroup flash_sdcard_spi SPI used to communication with SD card
+ * @{
+ */
+#define FLASH_SDCARD_SPI 1 /**< SPI peripheral */
+/** @} */
+
+/** table for CRC-7 calculation for the command messages (see section 4.5)
+ * @note faster than calculating the CRC and doesn't cost a lot of space
+ * @note generated using pycrc --width=7 --poly=0x09 --reflect-in=false --reflect-out=false --xor-in=0x00 --xor-out=0x00 --generate=table
+ */
+static const uint8_t crc7_table[] = {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+};
+
+/** wait one SPI round (one SPI word)
+ */
+static void flash_sdcard_spi_wait(void)
+{
+ spi_send(SPI(FLASH_SDCARD_SPI), 0xffff); // send not command token (i.e. starting with 1)
+}
+
+/** read one SPI word
+ * @return SPI word read
+ */
+static uint16_t flash_sdcard_spi_read(void)
+{
+ spi_send(SPI(FLASH_SDCARD_SPI), 0xffff); // send not command token (i.e. starting with 1)
+ while (!(SPI_SR(SPI(FLASH_SDCARD_SPI))&SPI_SR_TXE)); // wait until Tx buffer is empty before clearing the (previous) RXNE flag
+ SPI_DR(SPI(FLASH_SDCARD_SPI)); // clear RXNE flag (by reading previously received data (not done by spi_read or spi_xref)
+ while (!(SPI_SR(SPI(FLASH_SDCARD_SPI))&SPI_SR_RXNE)); // wait for next data to be available
+ return SPI_DR(SPI(FLASH_SDCARD_SPI)); // return received adat
+}
+
+/** test if card is present
+ * @return if card has been detected
+ * @note this use the SD card detection mechanism (CD/CS is high card is inserted due to the internal 50 kOhm resistor)
+ */
+static bool flash_sdcard_card_detect(void)
+{
+ rcc_periph_clock_enable(RCC_SPI_NSS_PORT(FLASH_SDCARD_SPI)); // enable clock for NSS pin port peripheral for SD card CD signal
+ gpio_set_mode(SPI_NSS_PORT(FLASH_SDCARD_SPI), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SPI_NSS_PIN(FLASH_SDCARD_SPI)); // set NSS pin as input to read CD signal
+ gpio_clear(SPI_NSS_PORT(FLASH_SDCARD_SPI), SPI_NSS_PIN(FLASH_SDCARD_SPI)); // pull pin low to avoid false positive when card in not inserted
+ return (0!=gpio_get(SPI_NSS_PORT(FLASH_SDCARD_SPI), SPI_NSS_PIN(FLASH_SDCARD_SPI))); // read CD signal: is card is present the internal 50 kOhm pull-up resistor will override our 1 MOhm pull-down resistor and set the signal high (see section 6.2)
+}
+
+/** transmit command token
+ * @param[in] index command index
+ * @param[in] argument command argument
+ */
+static void flash_sdcard_send_command(uint8_t index, uint32_t argument)
+{
+ uint8_t command[5] = { 0x40+(index&0x3f), argument>>24, argument>>16, argument>>8, argument>>0 }; // commands are 5 bytes long, plus 1 bytes of CRC (see section 7.3.1.1)
+ uint8_t crc7 = 0x00; // CRC-7 checksum for command message
+ // send command
+ for (uint8_t i=0; i.
+ *
+ */
+/** library to communicate with an SD card flash memory using the SPI mode (API)
+ * @file flash_sdcard.h
+ * @author King Kévin
+ * @date 2017
+ * @note peripherals used: SPI @ref flash_sdcard_spi
+ * @warning all calls are blocking
+ */
+#pragma once
+
+/** setup communication with SD card
+ * @return if card has been initialized correctly
+ */
+bool flash_sdcard_setup(void);