From 127212aa96e42aa5bdcf8725300fc4d37d594d92 Mon Sep 17 00:00:00 2001 From: chayrai <heriniainaraissa.andrianirintsoa@polytech-lille.net> Date: Mon, 11 Dec 2023 09:10:15 +0000 Subject: [PATCH] ajout des tests sur carte SD et ordonnanceur --- Ordonnanceur/.ordonnanceur.c.swp | Bin 0 -> 24576 bytes Ordonnanceur/eeprom.hex | 1 + Ordonnanceur/ordonnanceur.c | 2 +- Ordonnanceur/ordonne.elf | Bin 0 -> 8016 bytes Ordonnanceur/ordonne.hex | 68 +++++ SD/Makefile | 34 +++ SD/Sd2Card.c | 456 +++++++++++++++++++++++++++++++ SD/Sd2Card.h | 75 +++++ SD/SdInfo.h | 160 +++++++++++ SD/serial.c | 44 +++ SD/serial.h | 6 + SD/spi.c | 26 ++ SD/spi.h | 15 + SD/test.c | 60 ++++ 14 files changed, 946 insertions(+), 1 deletion(-) create mode 100644 Ordonnanceur/.ordonnanceur.c.swp create mode 100644 Ordonnanceur/eeprom.hex create mode 100755 Ordonnanceur/ordonne.elf create mode 100644 Ordonnanceur/ordonne.hex create mode 100644 SD/Makefile create mode 100644 SD/Sd2Card.c create mode 100644 SD/Sd2Card.h create mode 100644 SD/SdInfo.h create mode 100644 SD/serial.c create mode 100644 SD/serial.h create mode 100644 SD/spi.c create mode 100644 SD/spi.h create mode 100644 SD/test.c diff --git a/Ordonnanceur/.ordonnanceur.c.swp b/Ordonnanceur/.ordonnanceur.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..cdfdffdc3dd96ca046712632fbb00d56b3f730cb GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/Ordonnanceur/eeprom.hex b/Ordonnanceur/eeprom.hex new file mode 100644 index 0000000..1996e8f --- /dev/null +++ b/Ordonnanceur/eeprom.hex @@ -0,0 +1 @@ +:00000001FF diff --git a/Ordonnanceur/ordonnanceur.c b/Ordonnanceur/ordonnanceur.c index 3d533c5..9efd8cf 100644 --- a/Ordonnanceur/ordonnanceur.c +++ b/Ordonnanceur/ordonnanceur.c @@ -1,7 +1,7 @@ #include <avr/io.h> // for the input/output register #include <avr/interrupt.h> -#define NB_TICK 1250 +#define NB_TICK 312 //sauver le contexte #define SAVE_REGISTER() \ diff --git a/Ordonnanceur/ordonne.elf b/Ordonnanceur/ordonne.elf new file mode 100755 index 0000000000000000000000000000000000000000..385e9a9d3a0f3654aa0471f91a23de9a9ec55123 GIT binary patch literal 8016 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 ZWIhShCgOy}8C3ra2?ho|SYRO83jlg1zj^=w literal 0 HcmV?d00001 diff --git a/Ordonnanceur/ordonne.hex b/Ordonnanceur/ordonne.hex new file mode 100644 index 0000000..12d8421 --- /dev/null +++ b/Ordonnanceur/ordonne.hex @@ -0,0 +1,68 @@ +:100000000C9434000C9451000C9451000C94510049 +:100010000C9451000C9451000C9451000C9451001C +:100020000C9451000C9451000C9451000C94050157 +:100030000C9451000C9451000C9451000C945100FC +:100040000C9451000C9451000C9451000C945100EC +:100050000C9451000C9451000C9451000C945100DC +:100060000C9451000C94510011241FBECFEFD8E026 +:10007000DEBFCDBF11E0A0E0B1E0EEE1F4E002C0F0 +:1000800005900D92AC30B107D9F721E0ACE0B1E0BA +:1000900001C01D92AD30B207E1F70E94EA010C9455 +:1000A0000D020C940000CF93DF93CDB7DEB787E24B +:1000B00090E027E230E0F9012081422F20910001F9 +:1000C00030910101242BFC01208388E290E028E29A +:1000D00030E0F9012081FC0120830000DF91CF9105 +:1000E0000895CF93DF93CDB7DEB788E290E028E2A2 +:1000F00030E0F9012081422F20910001309101016F +:100100002427FC0120830000DF91CF910895CF9335 +:10011000DF93CDB7DEB787E290E027E230E0F90168 +:100120002081422F2091020130910301242BFC01F8 +:10013000208388E290E028E230E0F9012081FC0190 +:1001400020830000DF91CF910895CF93DF93CDB747 +:10015000DEB788E290E028E230E0F9012081422F0A +:1001600020910201309103012427FC01208300002B +:10017000DF91CF910895CF93DF93CDB7DEB781E8BC +:1001800090E021E830E0F90120812860FC01208323 +:1001900081E890E021E830E0F90120812460FC0151 +:1001A000208381E890E021E830E0F901208121609E +:1001B000FC01208388E890E028E331E0FC013183F2 +:1001C00020838FE690E02FE630E0F9012081226065 +:1001D000FC0120830000DF91CF910895CF93DF933E +:1001E000CDB7DEB780910C01882F90E00196817029 +:1001F0009078992324F401978E6F9F6F01968093D6 +:100200000C010000DF91CF9108950F920FB60F926D +:100210001F922F923F924F925F926F927F928F9296 +:100220009F92AF92BF92CF92DF92EF92FF920F9385 +:100230001F932F933F934F935F936F937F938F936E +:100240009F93AF93BF93CF93DF93EF93FF938091EF +:100250000C01882F90E02DE530E0F90120813181FB +:10026000880F991F880F991F8C5F9E4FFC01318367 +:1002700020830E94EE008DE590E020910C01222F5A +:1002800030E0220F331F220F331F2C5F3E4FF90146 +:1002900020813181FC0131832083FF91EF91DF9137 +:1002A000CF91BF91AF919F918F917F916F915F910E +:1002B0004F913F912F911F910F91FF90EF90DF9001 +:1002C000CF90BF90AF909F908F907F906F905F90F6 +:1002D0004F903F902F901F900F900FBE0F9018954A +:1002E0000000CF93DF9300D000D000D0CDB7DEB7B1 +:1002F0009E838D838DE590E0FC01808191819A83BE +:1003000089838DE590E02D813E81220F331F220FDE +:10031000331F2C5F3E4FF90120813181FC01318375 +:1003200020838D819E81880F991F880F991F8A5F76 +:100330009E4FFC01808191819C838B838B819C816A +:1003400099278F938B819C81892F99278F930F9267 +:100350000FB60F921F922F923F924F925F926F9221 +:100360007F928F929F92AF92BF92CF92DF92EF9245 +:10037000FF920F931F932F933F934F935F936F932E +:100380007F938F939F93AF93BF93CF93DF93EF931D +:10039000FF938DE590E0FC01208131818D819E816C +:1003A000880F991F880F991F8C5F9E4FFC01318326 +:1003B00020838DE590E029813A81FC0131832083FF +:1003C000000026960FB6F894DEBF0FBECDBFDF91BA +:1003D000CF910895CF93DF9300D0CDB7DEB70E94C1 +:1003E00087000E9453000E94BB001A82198209C034 +:1003F00089819A810E94710189819A8101969A83EB +:10040000898389819A8102979CF37894809106016F +:0E04100090910701FC010995FFCFF894FFCFF2 +:0C041E00080001000005A50000067100A8 +:00000001FF diff --git a/SD/Makefile b/SD/Makefile new file mode 100644 index 0000000..ab15086 --- /dev/null +++ b/SD/Makefile @@ -0,0 +1,34 @@ +MCU = atmega328p +FCPU = 16000000 + +CC = avr-gcc +LD = avr-gcc +FLAGS = -mmcu=$(MCU) +CFLAGS = -Wall $(FLAGS) -DF_CPU=$(FCPU) -Os -DDEBUG -DTEST_WRITE -DTEST_READ +LDFLAGS = $(FLAGS) + +DUDE = avrdude +PROTOCOL = stk500v1 # stk500 / stk500v1 +SPEED = 115200 # 57600 / 115200 +SERIAL = /dev/ttyUSB0 # ttyUSB0 / ttyACM0 + +TARGET = test +SOURCES = $(wildcard *.c) +OBJECTS = $(SOURCES:.c=.o) + +all: $(TARGET).hex + +clean: + rm -f *.o $(TARGET).hex $(TARGET) + +$(TARGET): $(OBJECTS) + +$(TARGET).hex: $(TARGET) + avr-objcopy -j .text -j .data -O ihex $(TARGET) $(TARGET).hex + +upload: $(TARGET).hex + stty -F $(SERIAL) hupcl + $(DUDE) -F -v -p $(MCU) -c $(PROTOCOL) -b $(SPEED) -P $(SERIAL) -U flash:w:$(TARGET).hex + +size: $(TARGET) + avr-size --format=avr --mcu=$(MCU) $(TARGET) diff --git a/SD/Sd2Card.c b/SD/Sd2Card.c new file mode 100644 index 0000000..12bd914 --- /dev/null +++ b/SD/Sd2Card.c @@ -0,0 +1,456 @@ +/** Bibliotheque pour les cartes SD (adaptation de la bibliotheque Arduino) **/ + +#include "stdio.h" +#include "string.h" +#include "avr/io.h" +#include "util/delay.h" + +#include "spi.h" +#include "SdInfo.h" +#include "Sd2Card.h" + +#define true 1 +#define false 0 + +//------------------------------------------------------------------------------ +// wait for card to go not busy +static uint8_t waitNotBusy(uint16_t timeoutMillis) { +int i; +for(i=0;i<timeoutMillis;i++){ + if(spi_exch(0xff)==0xff) return true; + _delay_ms(1); + } +return false; +} + +//------------------------------------------------------------------------------ +/** Skip remaining data in a block when in partial block read mode. */ +void readEnd(SD_info *info) { +if(info->inBlock_){ + while(info->offset_++<514) spi_exch(0xff); + chipSelectHigh(); + info->inBlock_=0; + } +} + +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +static uint8_t cardCommand(SD_info *info, uint8_t cmd, uint32_t arg) { +readEnd(info); // end read if in partialBlockRead mode +chipSelectLow(); // select card +waitNotBusy(30); // wait up to 300 ms if busy +spi_exch(cmd|0x40); // send command +int8_t s; // send argument +for(s=24;s>=0;s -= 8) spi_exch(arg >> s); +uint8_t crc=0xff; // send CRC +if(cmd==CMD0) crc=0x95; // correct crc for CMD0 with arg 0 +if(cmd==CMD8) crc=0x87; // correct crc for CMD8 with arg 0X1AA +spi_exch(crc); +uint8_t i; // wait for response +for(i=0;((info->status_=spi_exch(0xff)) & 0x80) && i!=0xff;i++); +return info->status_; +} + +//------------------------------------------------------------------------------ +static uint8_t waitStartBlock(SD_info *info){ +int cpt=0; +while((info->status_=spi_exch(0xff))==0xff){ + if(cpt>SD_READ_TIMEOUT){ + error(info, SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + cpt++; + } +if(info->status_!=DATA_START_BLOCK){ + error(info, SD_CARD_ERROR_READ); + goto fail; + } +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +uint8_t readRegister(SD_info *info, uint8_t cmd, void* buf) { +uint8_t* dst=buf; +if(cardCommand(info, cmd, 0)){ + error(info, SD_CARD_ERROR_READ_REG); + goto fail; + } +if(!waitStartBlock(info)) goto fail; +// transfer data +uint16_t i; +for(i=0;i<16;i++) dst[i]=spi_exch(0xff); +spi_exch(0xff); // get first crc byte +spi_exch(0xff); // get second crc byte +chipSelectHigh(); +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +inline uint8_t readCID(SD_info *info, cid_t *cid){ return readRegister(info, CMD10, cid); } +inline uint8_t readCSD(SD_info *info, csd_t *csd){ return readRegister(info, CMD9, csd); } + +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t cardSize(SD_info *info){ +csd_t csd; +if(!readCSD(info, &csd)) return 0; +if(csd.v1.csd_ver==0){ + uint8_t read_bl_len=csd.v1.read_bl_len; + uint16_t c_size=(csd.v1.c_size_high << 10) + |(csd.v1.c_size_mid << 2)|csd.v1.c_size_low; + uint8_t c_size_mult=(csd.v1.c_size_mult_high << 1) + |csd.v1.c_size_mult_low; + return (uint32_t)(c_size+1) << (c_size_mult+read_bl_len-7); + } +else if(csd.v2.csd_ver==1){ + uint32_t c_size=((uint32_t)csd.v2.c_size_high << 16) + |(csd.v2.c_size_mid << 8)|csd.v2.c_size_low; + return (c_size+1) << 10; + } +else{ + error(info, SD_CARD_ERROR_BAD_CSD); + return 0; + } +} + +//------------------------------------------------------------------------------ +/** Determine if card supports single block erase. + * + * \return The value one, true, is returned if single block erase is supported. + * The value zero, false, is returned if single block erase is not supported. + */ +uint8_t eraseSingleBlockEnable(SD_info *info) { +csd_t csd; +return readCSD(info, &csd)?csd.v1.erase_blk_en:0; +} + +//------------------------------------------------------------------------------ +/** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t erase(SD_info *info, uint32_t firstBlock, uint32_t lastBlock) { +if(!eraseSingleBlockEnable(info)){ + error(info, SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + goto fail; + } +if(info->type_!=SD_CARD_TYPE_SDHC){ + firstBlock <<= 9; + lastBlock <<= 9; + } +if(cardCommand(info, CMD32, firstBlock) + || cardCommand(info, CMD33, lastBlock) + || cardCommand(info, CMD38, 0)) { + error(info, SD_CARD_ERROR_ERASE); + goto fail; + } +if(!waitNotBusy(SD_ERASE_TIMEOUT)){ + error(info, SD_CARD_ERROR_ERASE_TIMEOUT); + goto fail; + } +chipSelectHigh(); +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +static uint8_t cardAcmd(SD_info *info, uint8_t cmd, uint32_t arg) { +cardCommand(info, CMD55, 0); +return cardCommand(info, cmd, arg); +} + +//------------------------------------------------------------------------------ +/** + * Initialize an SD flash memory card. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. The reason for failure + * can be determined by calling errorCode() and errorData(). + */ +uint8_t sd_init(SD_info *info){ +memset(info,0,sizeof(SD_info)); + +// Initialize CS +chipSelectInit(); +chipSelectHigh(); + +// must supply min of 74 clock cycles with CS high. +uint8_t i; +for(i=0;i<10;i++) spi_exch(0xff); +chipSelectLow(); + +// command to go idle in SPI mode +int cpt=0; +while((info->status_=cardCommand(info, CMD0, 0))!=R1_IDLE_STATE){ + if(cpt>SD_INIT_TIMEOUT){ + error(info, SD_CARD_ERROR_CMD0); + goto fail; + } + _delay_ms(1); + cpt++; + } + +// check SD version +if((cardCommand(info, CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)){ + type(info, SD_CARD_TYPE_SD1); + } +else{ + // only need last byte of r7 response + uint8_t i; + for(i=0;i<4;i++) info->status_=spi_exch(0xff); + if(info->status_!=0xaa) { + error(info, SD_CARD_ERROR_CMD8); + goto fail; + } + type(info, SD_CARD_TYPE_SD2); + } +// initialize card and send host supports SDHC if SD2 +uint32_t arg; +arg=(info->type_==SD_CARD_TYPE_SD2)?0x40000000:0; + +while((info->status_=cardAcmd(info, ACMD41, arg))!=R1_READY_STATE){ + // check for timeout + if(cpt>SD_INIT_TIMEOUT){ + error(info, SD_CARD_ERROR_ACMD41); + goto fail; + } + _delay_ms(1); + cpt++; + } +// if SD2 read OCR register to check for SDHC card +if(info->type_==SD_CARD_TYPE_SD2){ + if(cardCommand(info, CMD58, 0)){ + error(info, SD_CARD_ERROR_CMD58); + goto fail; + } + if((spi_exch(0xff) & 0xc0) == 0xc0) type(info, SD_CARD_TYPE_SDHC); + // discard rest of ocr - contains allowed voltage range + uint8_t i; + for(i=0;i<3;i++) spi_exch(0xff); + } +chipSelectHigh(); +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +/** + * Enable or disable partial block reads. + * + * Enabling partial block reads improves performance by allowing a block + * to be read over the SPI bus as several sub-blocks. Errors may occur + * if the time between reads is too long since the SD card may timeout. + * The SPI SS line will be held low until the entire block is read or + * readEnd() is called. + * + * Use this for applications like the Adafruit Wave Shield. + * + * \param[in] value The value TRUE (non-zero) or FALSE (zero).) + */ +void partialBlockRead(SD_info *info, uint8_t value) { +readEnd(info); +info->partialBlockRead_ = value; +} + +//------------------------------------------------------------------------------ +/** + * Read part of a 512 byte block from an SD card. + * + * \param[in] block Logical block to be read. + * \param[in] offset Number of bytes to skip at start of block + * \param[out] dst Pointer to the location that will receive the data. + * \param[in] count Number of bytes to read + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t readData(SD_info *info, uint32_t block, uint16_t offset, uint16_t count, uint8_t* dst) { +if(count==0) return true; +if((count+offset)>512){ goto fail; } +if(!info->inBlock_||block!=info->block_||offset<info->offset_){ + info->block_=block; + // use address if not SDHC card + if(info->type_!=SD_CARD_TYPE_SDHC) block <<= 9; + if(cardCommand(info, CMD17, block)){ + error(info, SD_CARD_ERROR_CMD17); + goto fail; + } + if(!waitStartBlock(info)){ goto fail; } + info->offset_=0; + info->inBlock_=1; + } + +// skip data before offset +for(;info->offset_<offset;info->offset_++) spi_exch(0xff); +// transfer data +uint16_t i; +for(i=0;i<count;i++) dst[i]=spi_exch(0xff); + +info->offset_ += count; +if(!info->partialBlockRead_||info->offset_>=512){ + // read rest of data, checksum and set chip select high + readEnd(info); + } +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card device. + * + * \param[in] block Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t readBlock(SD_info *info, uint32_t block, uint8_t* dst) { +return readData(info, block, 0, 512, dst); +} + +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +static uint8_t writeData_(SD_info *info, uint8_t token, const uint8_t* src) { +spi_exch(token); +uint16_t i; +for(i=0;i<512;i++) spi_exch(src[i]); +spi_exch(0xff); // dummy crc +spi_exch(0xff); // dummy crc +info->status_=spi_exch(0xff); +if((info->status_&DATA_RES_MASK)!=DATA_RES_ACCEPTED){ + error(info, SD_CARD_ERROR_WRITE); + chipSelectHigh(); + return false; + } +return true; +} + +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence */ +uint8_t writeData(SD_info *info, const uint8_t* src){ +// wait for previous write to finish +if(!waitNotBusy(SD_WRITE_TIMEOUT)){ + error(info, SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; + } +return writeData_(info, WRITE_MULTIPLE_TOKEN, src); +} + +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t writeBlock(SD_info *info, uint32_t blockNumber, const uint8_t* src) { +// use address if not SDHC card +if(info->type_!=SD_CARD_TYPE_SDHC) blockNumber <<= 9; +if(cardCommand(info, CMD24, blockNumber)){ + error(info, SD_CARD_ERROR_CMD24); + goto fail; + } +if(!writeData_(info, DATA_START_BLOCK, src)) goto fail; + +// wait for flash programming to complete +if(!waitNotBusy(SD_WRITE_TIMEOUT)){ + error(info, SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } +// response is r2 so get and check two bytes for nonzero +if(cardCommand(info, CMD13, 0) || spi_exch(0xff)){ + error(info,SD_CARD_ERROR_WRITE_PROGRAMMING); + goto fail; + } +chipSelectHigh(); +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t writeStart(SD_info *info, uint32_t blockNumber, uint32_t eraseCount) { +// send pre-erase count +if(cardAcmd(info, ACMD23, eraseCount)){ + error(info, SD_CARD_ERROR_ACMD23); + goto fail; + } +// use address if not SDHC card +if(info->type_!=SD_CARD_TYPE_SDHC) blockNumber <<= 9; +if(cardCommand(info, CMD25, blockNumber)){ + error(info, SD_CARD_ERROR_CMD25); + goto fail; + } +return true; + +fail: +chipSelectHigh(); +return false; +} + +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +uint8_t writeStop(SD_info *info) { +if(!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; +spi_exch(STOP_TRAN_TOKEN); +if(!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; +chipSelectHigh(); +return true; + +fail: +error(info, SD_CARD_ERROR_STOP_TRAN); +chipSelectHigh(); +return false; +} diff --git a/SD/Sd2Card.h b/SD/Sd2Card.h new file mode 100644 index 0000000..03cf0cf --- /dev/null +++ b/SD/Sd2Card.h @@ -0,0 +1,75 @@ +/** Definitions pour les cartes SD (adaptation de la bibliotheque Arduino) **/ + +/* Constantes */ + +#define SD_DDR DDRB +#define SD_PORT PORTB +#define SD_PIN 2 + +#define SD_PROTECT_BLOCK_ZERO 1 /* Protect block zero from write if nonzero */ +#define SD_INIT_TIMEOUT 300 /* init timeout ms */ +#define SD_ERASE_TIMEOUT 10000 /* erase timeout ms */ +#define SD_READ_TIMEOUT 300 /* read timeout ms */ +#define SD_WRITE_TIMEOUT 600 /* write time out ms */ + +#define SD_CARD_ERROR_CMD0 0x01 /* timeout error for command CMD0 */ +#define SD_CARD_ERROR_CMD8 0x02 /* CMD8 was not accepted - not a valid SD card*/ +#define SD_CARD_ERROR_CMD17 0x03 /* card returned an error response for CMD17 (read block) */ +#define SD_CARD_ERROR_CMD24 0x04 /* card returned an error response for CMD24 (write block) */ +#define SD_CARD_ERROR_CMD25 0x05 /* WRITE_MULTIPLE_BLOCKS command failed */ +#define SD_CARD_ERROR_CMD58 0x06 /* card returned an error response for CMD58 (read OCR) */ +#define SD_CARD_ERROR_ACMD23 0x07 /* SET_WR_BLK_ERASE_COUNT failed */ +#define SD_CARD_ERROR_ACMD41 0x08 /* card's ACMD41 initialization process timeout */ +#define SD_CARD_ERROR_BAD_CSD 0x09 /* card returned a bad CSR version field */ +#define SD_CARD_ERROR_ERASE 0x0a /* erase block group command failed */ +#define SD_CARD_ERROR_ERASE_SINGLE_BLOCK 0x0b /* card not capable of single block erase */ +#define SD_CARD_ERROR_ERASE_TIMEOUT 0x0c /* Erase sequence timed out */ +#define SD_CARD_ERROR_READ 0x0d /* card returned an error token instead of read data */ +#define SD_CARD_ERROR_READ_REG 0x0e /* read CID or CSD failed */ +#define SD_CARD_ERROR_READ_TIMEOUT 0x0f /* timeout while waiting for start of read data */ +#define SD_CARD_ERROR_STOP_TRAN 0x10 /* card did not accept STOP_TRAN_TOKEN */ +#define SD_CARD_ERROR_WRITE 0x11 /* card returned an error token as a response to a write */ +#define SD_CARD_ERROR_WRITE_BLOCK_ZERO 0x12 /* attempt to write protected block zero */ +#define SD_CARD_ERROR_WRITE_MULTIPLE 0x13 /* card did not go ready for a multiple block write */ +#define SD_CARD_ERROR_WRITE_PROGRAMMING 0x14 /* card returned error to a CMD13 status check after write */ +#define SD_CARD_ERROR_WRITE_TIMEOUT 0x15 /* timeout occurred during write programming */ +#define SD_CARD_ERROR_SCK_RATE 0x16 /* incorrect rate selected */ + +#define SD_CARD_TYPE_SD1 1 /* Standard capacity V1 SD card */ +#define SD_CARD_TYPE_SD2 2 /* Standard capacity V2 SD card */ +#define SD_CARD_TYPE_SDHC 3 /* High Capacity SD card */ + +/* Macros */ + +#define chipSelectInit() SD_DDR |= (1<<SD_PIN) +#define chipSelectHigh() SD_PORT |= (1<<SD_PIN) +#define chipSelectLow() SD_PORT &= ~(1<<SD_PIN) +#define error(info,code) {info->errorCode_ = code;} +#define type(info,type) {info->type_ = type;} + +/* Structures */ + +typedef struct{ + uint32_t block_; + uint8_t errorCode_; + uint8_t inBlock_; + uint16_t offset_; + uint8_t partialBlockRead_; + uint8_t status_; + uint8_t type_; + } SD_info; + +/* Prototypes */ + +void readEnd(SD_info *info); +uint32_t cardSize(SD_info *info); +uint8_t eraseSingleBlockEnable(SD_info *info); +uint8_t erase(SD_info *info, uint32_t firstBlock, uint32_t lastBlock); +uint8_t sd_init(SD_info *info); +void partialBlockRead(SD_info *info, uint8_t value); +uint8_t readData(SD_info *info, uint32_t block, uint16_t offset, uint16_t count, uint8_t* dst); +uint8_t readBlock(SD_info *info, uint32_t block, uint8_t* dst); +uint8_t writeData(SD_info *info, const uint8_t* src); +uint8_t writeBlock(SD_info *info, uint32_t blockNumber, const uint8_t* src); +uint8_t writeStart(SD_info *info, uint32_t blockNumber, uint32_t eraseCount); +uint8_t writeStop(SD_info *info); diff --git a/SD/SdInfo.h b/SD/SdInfo.h new file mode 100644 index 0000000..a44312c --- /dev/null +++ b/SD/SdInfo.h @@ -0,0 +1,160 @@ +/** Definitions pour les cartes SD (adaptation de la bibliotheque Arduino) **/ + +/* Constantes */ + +/** GO_IDLE_STATE - init card in spi mode if CS low */ +#define CMD0 0x00 +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +#define CMD8 0x08 +/** SEND_CSD - read the Card Specific Data (CSD register) */ +#define CMD9 0x09 +/** SEND_CID - read the card identification information (CID register) */ +#define CMD10 0x0a +/** SEND_STATUS - read the card status register */ +#define CMD13 0x0d +/** READ_BLOCK - read a single data block from the card */ +#define CMD17 0x11 +/** WRITE_BLOCK - write a single data block to the card */ +#define CMD24 0x18 +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +#define CMD25 0x19 +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +#define CMD32 0x20 +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +#define CMD33 0x21 +/** ERASE - erase all previously selected blocks */ +#define CMD38 0x26 +/** APP_CMD - escape for application specific command */ +#define CMD55 0x37 +/** READ_OCR - read the OCR register of a card */ +#define CMD58 0x3a +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +#define ACMD23 0x17 +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +#define ACMD41 0x29 + +/** status for card in the ready state */ +#define R1_READY_STATE 0x00 +/** status for card in the idle state */ +#define R1_IDLE_STATE 0x01 +/** status bit for illegal command */ +#define R1_ILLEGAL_COMMAND 0x04 +/** start data token for read or write single block*/ +#define DATA_START_BLOCK 0xfe +/** stop token for write multiple blocks*/ +#define STOP_TRAN_TOKEN 0xfd +/** start data token for write multiple blocks*/ +#define WRITE_MULTIPLE_TOKEN 0xfc +/** mask for data response tokens after a write block operation */ +#define DATA_RES_MASK 0x1f +/** write data accepted token */ +#define DATA_RES_ACCEPTED 0x05 + +/* Structures */ + +typedef struct{ + uint8_t mid; // Manufacturer ID + char oid[2]; // OEM/Application ID + char pnm[5]; // Product name + unsigned prv_m : 4; // Product revision n.m + unsigned prv_n : 4; + uint32_t psn; // Product serial number + unsigned mdt_year_high : 4; // Manufacturing date + unsigned reserved : 4; + unsigned mdt_month : 4; + unsigned mdt_year_low :4; + unsigned always1 : 1; + unsigned crc : 7; + } cid_t; + +typedef struct{ + unsigned reserved1 : 6; + unsigned csd_ver : 2; + uint8_t taac; + uint8_t nsac; + uint8_t tran_speed; + uint8_t ccc_high; + unsigned read_bl_len : 4; + unsigned ccc_low : 4; + unsigned c_size_high : 2; + unsigned reserved2 : 2; + unsigned dsr_imp : 1; + unsigned read_blk_misalign :1; + unsigned write_blk_misalign : 1; + unsigned read_bl_partial : 1; + uint8_t c_size_mid; + unsigned vdd_r_curr_max : 3; + unsigned vdd_r_curr_min : 3; + unsigned c_size_low :2; + unsigned c_size_mult_high : 2; + unsigned vdd_w_cur_max : 3; + unsigned vdd_w_curr_min : 3; + unsigned sector_size_high : 6; + unsigned erase_blk_en : 1; + unsigned c_size_mult_low : 1; + unsigned wp_grp_size : 7; + unsigned sector_size_low : 1; + unsigned write_bl_len_high : 2; + unsigned r2w_factor : 3; + unsigned reserved3 : 2; + unsigned wp_grp_enable : 1; + unsigned reserved4 : 5; + unsigned write_partial : 1; + unsigned write_bl_len_low : 2; + unsigned reserved5: 2; + unsigned file_format : 2; + unsigned tmp_write_protect : 1; + unsigned perm_write_protect : 1; + unsigned copy : 1; + unsigned file_format_grp : 1; + unsigned always1 : 1; + unsigned crc : 7; + } csd1_t; + +typedef struct{ + unsigned reserved1 : 6; + unsigned csd_ver : 2; + uint8_t taac; + uint8_t nsac; + uint8_t tran_speed; + uint8_t ccc_high; + unsigned read_bl_len : 4; + unsigned ccc_low : 4; + unsigned reserved2 : 4; + unsigned dsr_imp : 1; + unsigned read_blk_misalign :1; + unsigned write_blk_misalign : 1; + unsigned read_bl_partial : 1; + unsigned reserved3 : 2; + unsigned c_size_high : 6; + uint8_t c_size_mid; + uint8_t c_size_low; + unsigned sector_size_high : 6; + unsigned erase_blk_en : 1; + unsigned reserved4 : 1; + unsigned wp_grp_size : 7; + unsigned sector_size_low : 1; + unsigned write_bl_len_high : 2; + unsigned r2w_factor : 3; + unsigned reserved5 : 2; + unsigned wp_grp_enable : 1; + unsigned reserved6 : 5; + unsigned write_partial : 1; + unsigned write_bl_len_low : 2; + unsigned reserved7: 2; + unsigned file_format : 2; + unsigned tmp_write_protect : 1; + unsigned perm_write_protect : 1; + unsigned copy : 1; + unsigned file_format_grp : 1; + unsigned always1 : 1; + unsigned crc : 7; + } csd2_t; + +typedef union { + csd1_t v1; + csd2_t v2; + } csd_t; diff --git a/SD/serial.c b/SD/serial.c new file mode 100644 index 0000000..b2e4ed0 --- /dev/null +++ b/SD/serial.c @@ -0,0 +1,44 @@ +/** Functions for serial port **/ + +#include <avr/io.h> +#include <stdio.h> + +#include "serial.h" + +static int send_serial_printf(char c,FILE *stream); +static FILE mystdout=FDEV_SETUP_STREAM(send_serial_printf,NULL,_FDEV_SETUP_WRITE); + +void init_serial(int speed){ +/* Set baud rate */ +UBRR0 = F_CPU/(((unsigned long int)speed)<<4)-1; + +/* Enable transmitter & receiver */ +UCSR0B = (1<<TXEN0 | 1<<RXEN0); + +/* Set 8 bits character and 1 stop bit */ +UCSR0C = (1<<UCSZ01 | 1<<UCSZ00); + +/* Set off UART baud doubler */ +UCSR0A &= ~(1 << U2X0); +} + +void send_serial(char c){ +loop_until_bit_is_set(UCSR0A, UDRE0); +UDR0 = c; +} + +char get_serial(void){ +loop_until_bit_is_set(UCSR0A, RXC0); +return UDR0; +} + +void init_printf(void){ +init_serial(9600); +stdout=&mystdout; +} + +static int send_serial_printf(char c,FILE *stream){ +if(c=='\n') send_serial('\r'); +send_serial(c); +return 0; +} diff --git a/SD/serial.h b/SD/serial.h new file mode 100644 index 0000000..fcababf --- /dev/null +++ b/SD/serial.h @@ -0,0 +1,6 @@ +/** Definitions for serial port **/ + +void init_serial(int speed); +void send_serial(char c); +char get_serial(void); +void init_printf(void); diff --git a/SD/spi.c b/SD/spi.c new file mode 100644 index 0000000..3fc8e79 --- /dev/null +++ b/SD/spi.c @@ -0,0 +1,26 @@ +/************************ +* SPI minimal library * +************************/ + +#include <stdint.h> +#include <avr/io.h> +#include <avr/interrupt.h> + +#include "spi.h" + +// Initialisation of SPI bus +void spi_init(void) +{ +SPI_DDR |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS); +SPI_PORT |= (1<<SPI_SS); +SPCR = (1<<SPE)|(1<<MSTR); +} + +// Send byte on SPI bus +uint8_t spi_exch(uint8_t output) +{ +SPDR = output; +while(!(SPSR & (1<<SPIF))); +return SPDR; +} + diff --git a/SD/spi.h b/SD/spi.h new file mode 100644 index 0000000..d60cef0 --- /dev/null +++ b/SD/spi.h @@ -0,0 +1,15 @@ +/******************************************* +* SPI minimal library public definitions * +********************************************/ + +#pragma once + +#define SPI_DDR DDRB +#define SPI_PORT PORTB +#define SPI_SS 2 +#define SPI_MOSI 3 +#define SPI_MISO 4 +#define SPI_SCK 5 + +void spi_init(void); +uint8_t spi_exch(uint8_t output); diff --git a/SD/test.c b/SD/test.c new file mode 100644 index 0000000..4a57873 --- /dev/null +++ b/SD/test.c @@ -0,0 +1,60 @@ +#ifdef DEBUG +#include <stdio.h> +#endif +#include <avr/io.h> +#include <stdio.h> + +#ifdef DEBUG +#include "serial.h" +#endif + +#include "spi.h" +#include "SdInfo.h" +#include "Sd2Card.h" + +#define BLOC_NO 16 +#define BLOC_TAILLE 512 + +int main(void) +{ + #ifdef TEST_WRITE + uint8_t blocW[BLOC_TAILLE]={0xab,0xcb,0xac}; + #endif + #ifdef TEST_READ + uint8_t blocR[BLOC_TAILLE]; + #endif + #ifdef DEBUG + init_printf(); + #endif + SD_info sd; + spi_init(); + uint8_t result=sd_init(&sd); + #ifdef DEBUG + printf("result=%x\n",result); + printf("status=%x\n",sd.status_); + printf("erreur=%x\n",sd.errorCode_); + printf("type=%x\n",sd.type_); + uint32_t size=cardSize(&sd); + printf("taille=%ld\n",size); + #endif + + #ifdef TEST_WRITE + int statutWrite=writeBlock(&sd,BLOC_NO,blocW); //écriture dans bloc 16 + #endif + #ifdef DEBUG + printf("statutWrite=%x\n",statutWrite); + #endif + + + #ifdef TEST_READ + int statutRead=readBlock(&sd,BLOC_NO,blocR); + #endif + #ifdef DEBUG + printf("statutRead=%x\n",statutRead); + int i; + for(i=0;i<3;i++) printf("blocR[%d]=%x ",i,blocR[i]); + printf("\n"); + #endif + + return 0; +} -- GitLab