From 6202e4a81edaec3a6a0728a4a09550a67b8e5a3f Mon Sep 17 00:00:00 2001 From: michael_k Date: Thu, 18 Jun 2026 18:19:02 +0300 Subject: [PATCH] a working fs with timestamps added --- IdiBusSlave.cpp | 51 +- IdiBus_Logger.7z | Bin 0 -> 29387 bytes components/SD_Card/fs.c | 1619 +++++++++++++++++++++++++ components/SD_Card/fs.h | 187 +++ components/SD_Card/sd.c | 298 +++++ components/SD_Card/sd.h | 45 + components/SD_Card/spi.c | 43 + components/SD_Card/spi.h | 22 + nbproject/Makefile-default.mk | 154 ++- nbproject/Makefile-genesis.properties | 6 +- 10 files changed, 2362 insertions(+), 63 deletions(-) create mode 100644 IdiBus_Logger.7z create mode 100644 components/SD_Card/fs.c create mode 100644 components/SD_Card/fs.h create mode 100644 components/SD_Card/sd.c create mode 100644 components/SD_Card/sd.h create mode 100644 components/SD_Card/spi.c create mode 100644 components/SD_Card/spi.h diff --git a/IdiBusSlave.cpp b/IdiBusSlave.cpp index 38c539d..8538959 100644 --- a/IdiBusSlave.cpp +++ b/IdiBusSlave.cpp @@ -5,6 +5,9 @@ #include "Serial.h" #include "DS3231.h" #include "time.h" +#include "fs.h" +#include "spi.h" +#include "sd.h" //Structure that holds module's data XXX_NAME_channel_data_t XXX_NAME_channels_data[IDIBUS_XXX_NAME_CH_NUM]; @@ -34,10 +37,56 @@ void SlaveInit() // Intr is ON Debug.begin(57600); Debug.writeln("Program start"); - + initDS3231(); Debug.writeln("Clock RTC Init"); + ds3231SetDate(18); + ds3231SetMonth(DS_JUNE); + ds3231SetYear(26); + spi_init(); + if (!sd_init()) + { + Debug.writeln("SD ready"); + } + else + { + Debug.writeln("SD failed"); + } + + Debug.writeln("Initializing file system... "); + if (!fs_init()) + { + Debug.writeln("FS ready"); + } + else + { + Debug.writeln("FS failed"); + } + + Debug.writeln("file system type: "); + if (fs_type == 1) + { + Debug.writeln("FAT32"); + } + else if (fs_type == 0) + { + Debug.writeln("FAT16"); + } + else Debug.writeln("UNKNOWN"); + + strcpy((char*)buf, "NEWFILE.DAT"); +if (fs_create() != 0) { + // Ошибка создания + Debug.writeln("No create"); +} + +// Записать данные +uint8_t data[] = "Hello, World!"; +if (fs_write(data, sizeof(data) - 1) != 0) { + Debug.writeln("No write"); +} + fs_file.opened = OPENED_NONE; } static int16_t temperature; // For whatever reason... diff --git a/IdiBus_Logger.7z b/IdiBus_Logger.7z new file mode 100644 index 0000000000000000000000000000000000000000..afc20c4c7e309ab1209bfa02bad7379a8e23e627 GIT binary patch literal 29387 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 W0RaVF01yBG41{tD0o+@Zj{pGo>lc*( literal 0 HcmV?d00001 diff --git a/components/SD_Card/fs.c b/components/SD_Card/fs.c new file mode 100644 index 0000000..cef45e6 --- /dev/null +++ b/components/SD_Card/fs.c @@ -0,0 +1,1619 @@ +/* +It is an open source software to implement FAT file system to +small embedded systems. This is a free software and is opened for education, +research and commercial developments under license policy of following trems. + +(C) 2013 vinxru +(C) 2010, ChaN, all right reserved. + +It is a free software and there is NO WARRANTY. +No restriction on use. You can use, modify and redistribute it for +personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +Redistributions of source code must retain the above copyright notice. + +Version 0.99 30-05-2013 + +P.S. goto allows you to save memory! Like other horrors bellow. + +Program size: 3070 words (6140 bytes), 75% of FLASH at ATMega8 !!! +*/ + +/* +Я не стал добавлять контроль на специальные имена +CON,PRN,AUX,CLOCK$,NUL,COM1,COM2,COM3,COM4,LPT1,LPT2,LPT3 +что бы не занимать микроконтроллер. Файлы с такими именами +оставляю на совести программиста. +*/ + +//#include +#include "fs.h" +#include "sd.h" +#include +#include +#include "DS3231.h" + +/* Вспомогательные функции для работы с временем */ + +static uint8_t fs_update_timestamp(void); + +/************************************************************************** +* Упаковка времени в формат FAT * +* Возвращает 16-битное значение: * +* биты 15-11: часы (0-23) * +* биты 10-5: минуты (0-59) * +* биты 4-0: секунды / 2 (0-29) * +**************************************************************************/ +static uint16_t fat_pack_time(void) +{ + uint8_t hour = ds3231GetHour(); + uint8_t min = ds3231GetMinute(); + uint8_t sec = ds3231GetSecond(); + + /* Проверка и коррекция значений */ + if (hour > 23) hour = 0; + if (min > 59) min = 0; + if (sec > 59) sec = 0; + + return (uint16_t)((hour << 11) | (min << 5) | (sec >> 1)); +} + +/************************************************************************** +* Упаковка даты в формат FAT * +* Возвращает 16-битное значение: * +* биты 15-9: год (от 1980, 0-127) * +* биты 8-5: месяц (1-12) * +* биты 4-0: день (1-31) * +**************************************************************************/ +static uint16_t fat_pack_date(void) +{ + uint8_t year = ds3231GetYear(); + uint8_t month = (uint8_t)ds3231GetMonth(); + uint8_t day = ds3231GetDate(); + + /* Проверка и коррекция значений */ + if (year > 99) year = 0; /* 2000-2099 */ + if (month < 1 || month > 12) month = 1; + if (day < 1 || day > 31) day = 1; + + /* Год от 1980: 2000 + year - 1980 = 20 + year */ + uint16_t year_offset = 20 + year; /* Для 2024: 20 + 24 = 44 */ + if (year_offset > 127) year_offset = 0; + + return (uint16_t)((year_offset << 9) | (month << 5) | day); +} + +uint8_t buf[512]; + +/* Для наглядности */ + +#define LD_uint16_t(ptr) (*(uint16_t*)(ptr)) +#define LD_uint32_t(ptr) (*(uint32_t*)(ptr)) + +/* Значения fs_type */ + +#define FS_FAT16 0 +#define FS_FAT32 1 +#define FS_ERROR 2 + +/* Специальные значения кластеров */ + +#define FREE_CLUSTER 0 +#define LAST_CLUSTER 0x0FFFFFFF + +/* Системные переменные. Информация из boot-сектора */ + + + +uint8_t fs_type; /* FS_FAT16, FS_FAT32, FS_ERROR */ +uint32_t fs_fatbase; /* Адрес первой FAT */ +uint32_t fs_fatbase2; /* Адрес второй FAT */ +uint8_t fs_csize; /* Размер кластера в секторах */ +uint16_t fs_n_rootdir; /* Кол-во записей в корневом каталоге (только FAT16) */ +uint32_t fs_n_fatent; /* Кол-во кластеров */ +uint32_t fs_dirbase; /* Корневой каталог (сектор для FAT16, кластер для FAT32) */ +uint32_t fs_database; /* Адрес второго кластера */ + +/* Системные переменные. Остальное */ + +uint8_t lastError; /* Последняя ошибка */ +uint32_t fs_fatoptim; /* Первый свободный кластер */ +uint32_t fs_tmp; /* Используеются для разных целей */ +uint16_t fs_wtotal; /* Используется функциями fs_write_start, fs_write_end*/ + +/* Открытые файлы/папки */ + +File fs_file; + +#ifndef FS_DISABLE_SWAP +File fs_secondFile; +#endif + +/* Структура boot-сектора */ + +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_FATSz16 22 +#define BPB_TotSec32 32 +#define BS_FilSysType 54 +#define BPB_FATSz32 36 +#define BPB_RootClus 44 +#define BS_FilSysType32 82 +#define MBR_Table 446 + +/************************************************************************** +* Чтение сектора в буфер * +**************************************************************************/ + +static uint8_t sd_readBuf(uint32_t sector) +{ + return sd_read(buf, sector, 0, 512); +} + +/************************************************************************** +* Запись буфера в сектор * +**************************************************************************/ + +static uint8_t sd_writeBuf(uint32_t sector) +{ + return sd_write512(buf, sector); +} + +/************************************************************************** +* Инициализация * +**************************************************************************/ + +uint8_t fs_init() +{ + uint32_t bsect, fsize, tsect; + + /* Сбрасываем оптимизацию */ + fs_fatoptim = 2; + + /* Предотвращаем ошибки программиста */ +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#ifndef FS_DISABLE_SWAP + fs_secondFile.opened = OPENED_NONE; +#endif + fs_type = FS_ERROR; +#endif + + /* Инициализация накопителя */ + //if(sd_init()) return 1; + + /* Ищем файловую систему */ + bsect = 0; + while(1) + { + if(sd_readBuf(bsect)) return 1; + if(LD_uint16_t(buf + 510) == 0xAA55) + { + if(LD_uint16_t(buf + BS_FilSysType ) == 0x4146) break; + if(LD_uint16_t(buf + BS_FilSysType32) == 0x4146) break; + /* Возможно это MBR */ + if(bsect == 0 && buf[MBR_Table+4]) + { + bsect = LD_uint32_t(buf + (MBR_Table + 8)); + if(bsect != 0) continue; + } + } +abort_noFS: + lastError = ERR_NO_FILESYSTEM; + return 1; + } + + /* Размер таблицы FAT в секторах */ + fsize = LD_uint16_t(buf + BPB_FATSz16); + if(fsize == 0) fsize = LD_uint32_t(buf + BPB_FATSz32); + + /* Размер файловой системы в секторах */ + tsect = LD_uint16_t( buf + BPB_TotSec16); + if(tsect == 0) tsect = LD_uint32_t(buf + BPB_TotSec32); + + /* Размер корневого каталога (должно быть кратно 16 и для FAT32 должно быть рано нулю) */ + fs_n_rootdir = LD_uint16_t(buf + BPB_RootEntCnt); + + /* Адреса таблиц FAT в секторах */ + fs_fatbase = bsect + LD_uint16_t(buf + BPB_RsvdSecCnt); + fs_fatbase2 = 0; + if(buf[BPB_NumFATs] >= 2) fs_fatbase2 = fs_fatbase + fsize; + + /* Кол-во секторов на кластер */ + fs_csize = buf[BPB_SecPerClus]; + + /* Кол-во кластеров */ + fsize *= buf[BPB_NumFATs]; + fs_n_fatent = (tsect - LD_uint16_t(buf + BPB_RsvdSecCnt) - fsize - fs_n_rootdir / 16) / fs_csize + 2; + + /* Адрес 2-ого кластера */ + fs_database = fs_fatbase + fsize + fs_n_rootdir / 16; + + /* Определение файловой системы */ + + /* FAT 12 */ + if(fs_n_fatent < 0xFF7) goto abort_noFS; + + /* FAT 16 */ + if(fs_n_fatent < 0xFFF7) + { + fs_dirbase = fs_fatbase + fsize; + fs_type = FS_FAT16; + return 0; + } + + /* FAT 32 */ + fs_dirbase = LD_uint32_t(buf + BPB_RootClus); + + /* Сбрасываем счетчик свободного места */ + if(LD_uint16_t(buf + BPB_RsvdSecCnt)>0) + { + bsect++; + if(sd_readBuf(bsect)) return 1; + if(LD_uint32_t(buf) == 0x41615252 && LD_uint32_t(buf + 0x1E4) == 0x61417272 && LD_uint32_t(buf + 0x1FC) == 0xAA550000) + { + LD_uint32_t(buf + 0x1E8) = 0xFFFFFFFF; + LD_uint32_t(buf + 0x1EC) = 0xFFFFFFFF; + if(sd_writeBuf(bsect)) return 1; + } + } + fs_type = FS_FAT32; + + return 0; +} + +/************************************************************************** +* Проверка наличия диска и если нужно, то его инициализация * +**************************************************************************/ + +uint8_t fs_check() +{ + if(!sd_check()) return 0; + return fs_init(); +} + +/************************************************************************** +* Получить кластер из FS_DIRENTRY * +* Функция не портит buf (функции, в которых этого не написано, портят) * +**************************************************************************/ + +static uint32_t fs_getEntryCluster() +{ + uint32_t c = LD_uint16_t(FS_DIRENTRY + DIR_FstClusLO); + if(fs_type != FS_FAT16) c |= ((uint32_t)LD_uint16_t(FS_DIRENTRY + DIR_FstClusHI)) << 16; + return c; +} + +/************************************************************************** +* Получить следующий кластер. * +* Аргумент и результат находятся в fs_tmp. * +**************************************************************************/ + +static uint8_t fs_nextCluster() +{ + if(fs_type == FS_FAT16) + { + if(sd_read((uint8_t*)&fs_tmp, fs_fatbase + fs_tmp / 256, (uint16_t)(uint8_t)fs_tmp * 2, 2)) goto abort; + fs_tmp &= 0xFFFF; + } + else + { + if(sd_read((uint8_t*)&fs_tmp, fs_fatbase + fs_tmp / 128, (uint16_t)((uint8_t)fs_tmp % 128) * 4, 4)) goto abort; + fs_tmp &= 0x0FFFFFFF; + } + /* Для удобства разработки заменяем последний кластер на ноль. */ + if(fs_tmp < 2 || fs_tmp >= fs_n_fatent) + fs_tmp = 0; + return 0; +abort: + return 1; +} + +/************************************************************************** +* Преобразовать номер кластера в номер сектора * +* Аргумент и результат находятся в fs_tmp. * +* Функция не портит buf * +***************************************************************************/ + +static void fs_clust2sect() +{ + fs_tmp = (fs_tmp - 2) * fs_csize + fs_database; +} + +/************************************************************************** +* Получить очередной файл или папку * +* Удаленные файлы, метки тома, последний элемент, LFN показываются * +* * +* Описание работы полностью идентично функции ниже, поэтому здесь не * +* приведено * +* * +* Функция не портит buf[0..MAX_FILENAME-1] * +***************************************************************************/ + +static uint8_t fs_readdirInt() +{ + if(fs_file.entry_able) + { + fs_file.entry_index++; + + /* В папке не может быть больше 65536 файлов, а в корне FAT16 не больше fs_n_rootdir */ + if(fs_file.entry_index == 0 || (fs_file.entry_cluster == 0 && fs_file.entry_index == fs_n_rootdir)) + { + fs_file.entry_index = 0; +retEnd: + FS_DIRENTRY[DIR_Name] = 0; /* Признак последнего файла для пользователя вызывающего fs_dirread */ + fs_file.entry_able = 0; + return 0; + } + + /* Граница сектора */ + if(fs_file.entry_index % 16 == 0) + { + fs_file.entry_sector++; + + /* Граница кластера */ + if(fs_file.entry_cluster != 0 && ((fs_file.entry_index / 16) % fs_csize) == 0) + { + + /* Следующий кластер */ + fs_tmp = fs_file.entry_cluster; + if(fs_nextCluster()) return 1; + if(fs_tmp == 0) goto retEnd; /* Последний кластер, устаналиваем fs_file.entry_able = 0 */ + + /* Сохраняем */ + fs_file.entry_cluster = fs_tmp; + fs_clust2sect(); + fs_file.entry_sector = fs_tmp; + } + } + } + else + { + fs_file.entry_index = 0; + fs_file.entry_able = 1; + fs_tmp = fs_file.entry_start_cluster; + + /* Первый кластер и сектор папки. Этот код не имеет смысла выполнять + для FAT16, но зато код хорошо сжимается. Т.к. этот кусок кода аналогичен + куску выше. */ + fs_file.entry_cluster = fs_tmp; + fs_clust2sect(); + fs_file.entry_sector = fs_tmp; + + /* Корневая папка FS_FAT16 */ + if(fs_file.entry_cluster == 0) fs_file.entry_sector = fs_dirbase; + } + + return sd_read(FS_DIRENTRY, fs_file.entry_sector, (uint16_t)((fs_file.entry_index % 16) * 32), 32); +} + +/************************************************************************** +* Получить очередной файл или папку (удаленные файлы пропускаются) * +* * +* Эта функция вызывается после fs_opendir, которая настраивает все * +* нужные переменные, поэтому вам ничего трогать не надо. Информация * +* ниже приведена для лучшего понимания работы * +* * +* Если на входе entry_able=0, то начинается новый поиск в папке * +* по адресу entry_start_cluster. При этом инициализируются переменные: * +* entry_able, entry_index, entry_sector, entry_cluster. * +* * +* Если на входе fs_file.entry_able=1, то используются эти 4 переменные. * +* * +* На выходе * +* entry_able - если 0 значит достигнут конец каталога * +* entry_sector - сектор описателя * +* entry_cluster - кластер описателя * +* entry_index - номер описателя * +* FS_DIRENTRY - описатель * +* * +* Функция не портит buf[0..MAX_FILENAME-1] * +**************************************************************************/ + +uint8_t fs_readdir_nocheck() +{ + while(!fs_readdirInt()) + { + if(FS_DIRENTRY[DIR_Name] == 0) fs_file.entry_able = 0; + if(fs_file.entry_able == 0) return 0; + if(FS_DIRENTRY[DIR_Name] == 0xE5) continue; /* Может быть еще 0x05 */ + if(FS_DIRENTRY[DIR_Name] == '.') continue; + if((FS_DIRENTRY[DIR_Attr] & AM_VOL) == 0) return 0; + } + return 1; +} + +uint8_t fs_readdir() +{ +#ifndef FS_DISABLE_CHECK + /* Папка должна быть открыта */ + if(fs_file.opened != OPENED_DIR) + { + lastError = ERR_NOT_OPENED; + return 1; + } +#endif + return fs_readdir_nocheck(); +} + +/************************************************************************** +* Сохранить изменения в обе таблицы FAT * +**************************************************************************/ + +static uint8_t fs_saveFatSector(uint32_t sector) +{ + if(fs_fatbase2) if(sd_writeBuf(fs_fatbase2+sector)) return 1; + return sd_writeBuf(fs_fatbase+sector); +} + +/************************************************************************** +* Выделить кластер * +* * +* Найденный кластер сохраняется в fs_tmp * +**************************************************************************/ + +/* Ради функции fs_getfree пришлось усложнить функцию fs_allocCluster. +Если функция не используется, то можно с помощью макроса FS_DISABLE_GETFREESPACE +исключить лишний код */ + +#ifdef FS_DISABLE_GETFREESPACE +#define DIS(X) +#define ALLOCCLUSTER +#else +#define DIS(X) X +#define ALLOCCLUSTER 0 +#endif + +static uint8_t fs_allocCluster(DIS(uint8_t freeSpace)) +{ + uint8_t i; + uint32_t s; + uint8_t *a; + + /* Начинаем поиск с этого кластера */ + fs_tmp = fs_fatoptim; + + /* Последовательно перебираем сектора */ + while(1) + { + /* Сектор и смещение */ + s = fs_tmp / 256, i = (uint8_t)fs_tmp, a = (uint8_t*)((uint16_t*)buf + i); + if(fs_type != FS_FAT16) s = fs_tmp / 128, i |= 128, a = (uint8_t*)((uint32_t*)buf - 128 + i); + + /* Читаем сектор */ + if(sd_readBuf(fs_fatbase + s)) goto abort; + + /* Среди 128/256 чисел в секторе ищем 0 */ + /* Куча проверок внутри цикла не самое быстрое решение, но зато получается очень компактный код. */ + do + { + /* Кластеры кончились */ + if(fs_tmp >= fs_n_fatent) + { + DIS(if(freeSpace) return 0;) lastError = ERR_NO_FREE_SPACE; + goto abort; + } + + /* Ищем свободный кластер и помечаем как последний */ + if(fs_type == FS_FAT16) + { + if(LD_uint16_t(a) == 0) + { + DIS(if(!freeSpace) + { + ) LD_uint16_t(a) = (uint16_t)LAST_CLUSTER; + goto founded; + DIS( + } + fs_file.sector++;) + } + a += 2; + } + else + { + if(LD_uint32_t(a) == 0) + { + DIS(if(!freeSpace) + { + ) LD_uint32_t(a) = LAST_CLUSTER; + goto founded; + DIS( + } + fs_file.sector++;) + } + a += 4; + } + + /* Счетчик */ + ++fs_tmp, ++i; + } + while(i != 0); + } +founded: + /* Оптимизация */ + fs_fatoptim = fs_tmp; + + /* Сохраняем изменения */ + return fs_saveFatSector(s); +abort: + return 1; +} + +#undef DIS + +/************************************************************************** +* Изменение таблицы FAT * +* * +* Если fs_tmp!=0, то FAT[cluster] = fs_tmp * +* Если fs_tmp==0, то swap(FAT[cluster], fs_tmp) * +**************************************************************************/ + +static uint8_t fs_setNextCluster(uint32_t cluster) +{ + uint32_t s, prev; + void* a; + + /* Вычисляем сектор */ + s = cluster / 128; + if(fs_type == FS_FAT16) s = cluster / 256; + + /* Читаем сектор */ + if(sd_readBuf(fs_fatbase + s)) return 1; + + /* Изменяем отдельный кластер */ + if(fs_type == FS_FAT16) + { + a = (uint16_t*)buf + (uint8_t)cluster; + prev = LD_uint16_t(a); + LD_uint16_t(a) = (uint16_t)fs_tmp; + } + else + { + a = (uint32_t*)buf + (uint8_t)cluster % 128; + prev = LD_uint32_t(a); + LD_uint32_t(a) = fs_tmp; + } + + /* Оптимизация поиска свободного кластера. Внезапно if() if() занимает меньше ПЗУ, чем && */ + if(fs_tmp == FREE_CLUSTER) if(cluster < fs_fatoptim) fs_fatoptim = cluster; + + /* Результат */ + if(fs_tmp == LAST_CLUSTER || fs_tmp == FREE_CLUSTER) + fs_tmp = prev; + + /* Сохраняем сектор */ + return fs_saveFatSector(s); +} + +/************************************************************************** +* Установить в описатель кластер * +**************************************************************************/ + +static void fs_setEntryCluster(uint8_t* entry, uint32_t cluster) +{ + LD_uint16_t(entry + DIR_FstClusLO) = (uint16_t)(cluster); + LD_uint16_t(entry + DIR_FstClusHI) = (uint16_t)(cluster >> 16); +} + +/************************************************************************** +* Очистить кластер и буфер * +**************************************************************************/ + +static uint8_t fs_eraseCluster(uint8_t i) +{ + memset(buf, 0, 512); + for(; i < fs_csize; ++i) + if(sd_writeBuf(fs_tmp + i)) return 1; + return 0; +} + +/************************************************************************** +* Выделить описатель в каталоге * +* * +* entry_able должно быть равно 0 * +* entry_start_cluster должен содержать первый кластер папки * +**************************************************************************/ + +static uint8_t* fs_allocEntry() +{ + /* Ищем в папке пустой описатель. */ + while(1) + { + if(fs_readdirInt()) return 0; + + /* Кластеры кончились */ + if(!fs_file.entry_able) break; + + /* Это свободный описатель */ + if(FS_DIRENTRY[0] == 0xE5 || FS_DIRENTRY[0] == 0) /* Может быть еще 0x05 */ + { + + /* Читаем сектор */ + if(sd_readBuf(fs_file.entry_sector)) return 0; + + /* Найденный описатель */ + return buf + (fs_file.entry_index % 16) * 32; + } + } + + /* Ограничение по кол-ву файлов */ + /* Корневой каталог FAT16 так же вернет fs_file.entry_index == 0 */ + if(fs_file.entry_index == 0) + { + lastError = ERR_DIR_FULL; + return 0; + } + + /* Выделить кластер. Результат в fs_tmp */ + if(fs_allocCluster(ALLOCCLUSTER)) return 0; + + /* Добавить еще один кластер к папке. */ + if(fs_setNextCluster(fs_file.entry_cluster)) return 0; /* fs_tmp сохранится, так как он не LAST и не FREE */ + + /* Заполняем ответ */ + fs_file.entry_cluster = fs_tmp; + fs_clust2sect(); + fs_file.entry_sector = fs_tmp; + + /* Очищаем кластер и за одно BUF (используется переменная fs_tmp) */ + fs_eraseCluster(0); + + /* Найденный описатель */ + return buf; +} + +/************************************************************************** +* Открыть/создать файл или папку * +* * +* Имя файла в buf. Оно не должно превышать FS_MAXFILE симолов включая 0 * +* * +* what = OPENED_NONE - Открыть файл или папку * +* what = OPENED_FILE - Создать файл (созданный файл открыт) * +* what = OPENED_DIR - Создать папку (созданная папка не открыта) * +* what | 0x80 - Не создавать файл в папке entry_start_cluster * +* * +* На выходе * +* FS_DIRENTRY - описатель * +* fs_file.entry_able - 0 (если открыт существующий файл/папка) * +* fs_file.entry_sector - сектор описателя * +* fs_file.entry_cluster - кластер описателя * +* fs_file.entry_index - номер описателя * +* fs_file.entry_start_cluster - первый кластер файла или папки * +* fs_parent_dir_cluster - первый кластер папки предка (CREATE) * +* fs_file.ptr - 0 (если открыт файл) * +* fs_file.size - размер файла (если открыт файл) * +* * +* Функция не портит buf[0..MAX_FILENAME-1] * +**************************************************************************/ + +static uint8_t fs_open0_create(uint8_t dir); /* forward */ +static uint8_t* fs_open0_name(uint8_t *p); /* forward */ + +#define FS_DIRFIND (buf + 469) /* 11 байт использующиеся внутри функции fs_open0 */ +#define fs_notrootdir (*(uint8_t*)&fs_file.size) /* Используется fs_open0, в это время переменные fs_file. не содежат нужных значения */ +#define fs_parent_dir_cluster fs_file.sector /* Так же используется fs_file.sector для хранения первого кластера папки предка. */ + +uint8_t fs_open0(uint8_t what) +{ + uint8_t *path; + uint8_t r; + + /* Проверка ошибок программиста */ +#ifndef FS_DISABLE_CHECK + if(fs_type == FS_ERROR) + { + lastError = ERR_NO_FILESYSTEM; + goto abort; + } + fs_file.opened = OPENED_NONE; +#endif + + /* Предотвращение рекурсии */ + r = what & 0x80; + what &= 0x7F; + fs_parent_dir_cluster = fs_file.entry_start_cluster; + + /* Корневой каталог */ + fs_notrootdir = 0; + fs_file.entry_start_cluster = fs_dirbase; + if(fs_type == FS_FAT16) fs_file.entry_start_cluster = 0; + + /* Корневая папка */ + if(buf[0] == 0) + { + if(what) goto abort_noPath; + FS_DIRENTRY[0] = 0; /* Признак корневой папки */ + FS_DIRENTRY[DIR_Attr] = AM_DIR; /* Для упрощения определения файл/папка запишем сюда AM_DIR */ + } + else + { + path = buf; + while(1) + { + /* Получаем очередное имя из path в FS_DIRFIND */ + path = fs_open0_name(path); + if(path == (uint8_t*)1) goto abort_noPath; + /* Ищем имя в папке */ + fs_file.entry_able = 0; + while(1) + { + if(fs_readdir_nocheck()) return 1; + if(fs_file.entry_able == 0) break; + if(!memcmp(FS_DIRENTRY, FS_DIRFIND, 11)) break; + } + /* Последний элементу пути в режиме создания */ + if(what && path == 0) + { + fs_parent_dir_cluster = fs_file.entry_start_cluster; /* Сохраняем в этой переменной результат для фунции fs_move */ + if(fs_type == FS_FAT32 && fs_parent_dir_cluster == fs_dirbase) fs_parent_dir_cluster = 0; + if(fs_file.entry_able == 0) return fs_open0_create(what-1); /* Продолжим там */ + lastError = ERR_FILE_EXISTS; + goto abort; + } + /* Файл/папка не найдена */ + if(fs_file.entry_able == 0) goto abort_noPath; + + /* Что то найдено */ + fs_file.entry_start_cluster = fs_getEntryCluster(); + /* Это был последний элемент пути */ + if(path == 0) break; + /* Это должна быть папка */ + if((FS_DIRENTRY[DIR_Attr] & AM_DIR) == 0) goto abort_noPath; + /* Предотвращаем рекурсию для функции fs_move */ + if(r && fs_file.entry_start_cluster == fs_parent_dir_cluster) goto abort_noPath; + /* Наденная папка уже не будет корневой */ + fs_notrootdir = 1; + } + } + /* Устанавливаем переменные */ + fs_file.entry_able = 0; + fs_file.size = LD_uint32_t(FS_DIRENTRY + DIR_FileSize); + fs_file.ptr = 0; +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_FILE; + if(FS_DIRENTRY[DIR_Attr] & AM_DIR) fs_file.opened = OPENED_DIR; +#endif + + /* Нельзя дважды открывать файл */ +#ifndef FS_DISABLE_CHECK +#ifndef FS_DISABLE_SWAP + if(fs_secondFile.opened==OPENED_FILE && fs_file.opened==OPENED_FILE && fs_secondFile.entry_sector == fs_file.entry_sector && fs_secondFile.entry_index==fs_file.entry_index) + { + fs_file.opened = OPENED_NONE; + lastError = ERR_ALREADY_OPENED; + goto abort; + } +#endif +#endif + + return 0; +abort_noPath: + lastError = ERR_NO_PATH; +abort: + return 1; +} + +static uint8_t exists(const /*flash*/ uint8_t* str, uint8_t c) +{ + while(*str) + if(*str++ == c) + return c; + return 0; +} + +static uint8_t * fs_open0_name(uint8_t *p) +{ + uint8_t c, ni, i; + + memset(FS_DIRFIND, ' ', 11); + i = 0; + ni = 8; + while(1) + { + c = *p++; + if(c == 0) + { + if(i == 0) break; /* Пустое имя файла */ + return 0; + } + if(c == '/') return p; + if(c == '.') + { + if(i == 0) break; /* Пустое имя файла */ +#ifndef FS_DISABLE_CHECK + if(ni != 8) break; /* Вторая точка */ +#endif + i = 8; + ni = 11; + continue; + } + /* Слишком длинное име */ + if(i == ni) break; + /* Запрещенные символы */ +#ifndef FS_DISABLE_CHECK + if(exists((const /*flash*/ uint8_t*)"+,;=[]*?<:>\\|\"", c)) break; + if(c <= 0x20) break; + if(c >= 0x80) break; +#endif + /* Приводим к верхнему регистру */ + if(c >= 'a' && c <= 'z') c -= 0x20; + /* Сохраняем имя */ + FS_DIRFIND[i++] = c; + } + /* Ошибка */ + return (uint8_t*)1; +} + +static uint8_t fs_open0_create(uint8_t dir) +{ + uint8_t new_name[11]; + uint32_t allocatedCluster; + uint8_t* allocatedEntry; + + /* Сохраняем имя, так как весь буфер будет затерт */ + memcpy(new_name, FS_DIRFIND, 11); + + /* Выделяем кластер для папки */ + if(dir) + { + if(fs_allocCluster(ALLOCCLUSTER)) goto abort; /* fs_file.entry_start_cluster изменен не будет, там первый кластер папки в которой мы создадим файл */ + allocatedCluster = fs_tmp; + } + + /* Добавляем в папку описатель (сектор не сохранен) */ + allocatedEntry = fs_allocEntry(); + if(allocatedEntry == 0) + { + + /* В случае ошибки освобождаем кластер */ + fs_tmp = FREE_CLUSTER; + fs_setNextCluster(allocatedCluster); + goto abort; + } + + /* Устаналиваем имя в описатель. */ + memset(allocatedEntry, 0, 32); + memcpy(allocatedEntry, new_name, 11); + + /* ========== УСТАНОВКА ДАТЫ И ВРЕМЕНИ ========== */ + /* Получаем текущее время и дату */ + uint16_t fat_time = fat_pack_time(); + uint16_t fat_date = fat_pack_date(); + + /* Устанавливаем время создания */ + LD_uint16_t(allocatedEntry + DIR_CrtTime) = fat_time; + LD_uint16_t(allocatedEntry + DIR_CrtDate) = fat_date; + + /* Устанавливаем время последней записи (такое же, как и время создания) */ + LD_uint16_t(allocatedEntry + DIR_WrtTime) = fat_time; + LD_uint16_t(allocatedEntry + DIR_WrtDate) = fat_date; + + /* Обнуляем зарезервированное поле (для совместимости) */ + allocatedEntry[DIR_NTres] = 0; + /* ============================================== */ + + if(!dir) + { + /* Сохраняем описатель на диск */ + if(sd_writeBuf(fs_file.entry_sector)) goto abort; + /* fs_file.entry_sector, fs_file.entry_index - устанавлиается в fs_allocCluster */ + fs_file.entry_start_cluster = 0; + fs_file.size = 0; + fs_file.ptr = 0; +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_FILE; +#endif + return 0; + } + + /* Это папка */ + allocatedEntry[DIR_Attr] = AM_DIR; + fs_setEntryCluster(allocatedEntry, allocatedCluster); + + /* Сохраняем описатель на диск */ + if(sd_writeBuf(fs_file.entry_sector)) goto abort; + + /* Сектор для новой папки */ + fs_tmp = allocatedCluster; + fs_clust2sect(); + + /* Очищаем fs_tmp и за одно buf */ + fs_eraseCluster(1); + + /* Создаем пустую папку */ + memset(buf, ' ', 11); + buf[0] = '.'; + buf[11] = 0x10; + fs_setEntryCluster(buf, allocatedCluster); + + /* Устанавливаем дату/время для записи "." в папке */ + LD_uint16_t(buf + DIR_CrtTime) = fat_time; + LD_uint16_t(buf + DIR_CrtDate) = fat_date; + LD_uint16_t(buf + DIR_WrtTime) = fat_time; + LD_uint16_t(buf + DIR_WrtDate) = fat_date; + + memset(buf+32, ' ', 11); + buf[32] = '.'; + buf[33] = '.'; + buf[32+11] = 0x10; + if(fs_notrootdir) fs_setEntryCluster(buf + 32, fs_file.entry_start_cluster); /* Сейчас в fs_file.size==0 значит корневой каталог */ + + /* Устанавливаем дату/время для записи ".." в папке */ + LD_uint16_t(buf + 32 + DIR_CrtTime) = fat_time; + LD_uint16_t(buf + 32 + DIR_CrtDate) = fat_date; + LD_uint16_t(buf + 32 + DIR_WrtTime) = fat_time; + LD_uint16_t(buf + 32 + DIR_WrtDate) = fat_date; + + /* Сохраняем папку */ + return sd_writeBuf(fs_tmp); +abort: + return 1; +} + +/************************************************************************** +* Открыть файл * +**************************************************************************/ + +uint8_t fs_open() +{ + if(fs_openany()) goto abort; +#ifndef FS_DISABLE_CHECK + if(fs_file.opened == OPENED_FILE) return 0; + fs_file.opened = OPENED_NONE; +#else + if((FS_DIRENTRY[DIR_Attr] & AM_DIR) == 0) return 0; +#endif + lastError = ERR_NO_PATH; +abort: + return 1; +} + +/************************************************************************** +* Открыть папку * +**************************************************************************/ + +uint8_t fs_opendir() +{ + if(fs_openany()) goto abort; +#ifndef FS_DISABLE_CHECK + if(fs_file.opened == OPENED_DIR) return 0; + fs_file.opened = OPENED_NONE; +#else + if(FS_DIRENTRY[DIR_Attr] & AM_DIR) return 0; +#endif + lastError = ERR_NO_PATH; +abort: + return 1; +} + +/************************************************************************** +* Вычислить номер следующего сектора для чтения/записи * +* Вызывается только из fs_read0, fs_write_start * +**************************************************************************/ + +static uint8_t fs_nextRWSector() +{ + if(fs_file.ptr == 0) + { + /* Чтение файла еще не начато */ + fs_tmp = fs_file.entry_start_cluster; + } + else + { + /* Еще не конец сектора */ + if((uint16_t)fs_file.ptr % 512) return 0; + + /* Следующий сектор */ + fs_file.sector++; + + /* Еще не конец кластера */ + if(((fs_file.sector - fs_database) % fs_csize) != 0) return 0; + + /* Следующий кластер */ + fs_tmp = fs_file.cluster; + if(fs_nextCluster()) return 1; + } + + /* Если это был последний кластер, добавляем новый */ + if(fs_tmp == 0) + { + if(fs_allocCluster(ALLOCCLUSTER)) return 1; + if(fs_file.ptr == 0) fs_file.entry_start_cluster = fs_tmp; + else fs_setNextCluster(fs_file.cluster); /* fs_tmp сохранится, так как он не LAST и не FREE */ + } + + /* Ок */ + fs_file.cluster = fs_tmp; + fs_clust2sect(); + fs_file.sector = fs_tmp; + return 0; +} + +/************************************************************************** +* Прочитать из файла несколько байт в buf * +* * +* Пользователь не должен выходить за пределы файла при чтении, иначе * +* возникнет утечка свобожного места на диске. * +* * +* Аргументы: * +* ptr - буфер для чтения, может быть buf * +* len - кол-во байт, которые необходимо прочитать * +**************************************************************************/ + +uint8_t fs_read0(uint8_t* ptr, uint16_t len) +{ + uint16_t sectorLen; + + /* Проверка ошибок программиста */ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + goto abort; + } +#endif + + while(len) + { + /* Если указатель находится на границе сектора */ + if(fs_nextRWSector()) goto abort; + + /* Кол-во байт до конца сектора */ + sectorLen = 512 - ((uint16_t)fs_file.ptr % 512); + if(len < sectorLen) sectorLen = len; + + /* Читаем данные */ + if(ptr) + { + if(sd_read(ptr, fs_file.sector, (uint16_t)fs_file.ptr % 512, sectorLen)) goto abort; + ptr += sectorLen; + } + + /* Увеличиваем смещение */ + fs_file.ptr += sectorLen; + len -= sectorLen; + } + + /* Увеличение размера файла */ + if(fs_file.ptr > fs_file.size) fs_file.size = fs_file.ptr, fs_file.changed = 1; + + return 0; +abort: +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#endif + return 1; +} + +/************************************************************************** +* Прочитать из файла несколько байт в buf * +* * +* Аргументы: * +* ptr - буфер для чтения, может быть buf * +* len - кол-во байт, которые необходимо прочитать * +* readed - указатель, для сохранения кол-ва реально прочитанных байт * +**************************************************************************/ + +uint8_t fs_read(uint8_t* ptr, uint16_t len, uint16_t* readed) +{ + /* Ограничиваем кол-во байт для чтения */ + if(len > fs_file.size - fs_file.ptr) len = (uint16_t)(fs_file.size - fs_file.ptr); + *readed = len; + + /* Проверка на ошибки происходит там */ + return fs_read0(ptr, len); +} + +/************************************************************************** +* Сохранить длину файла и превый кластер в опистаель * +* Вызывается из fs_lseek, fs_write_start, fs_write_end, fs_write_eof * +**************************************************************************/ + +static char fs_saveFileLength() +{ + uint8_t* entry; + + if(fs_file.changed == 0) return 0; + fs_file.changed = 0; + + /* Изменение описателя файла */ + if(sd_readBuf(fs_file.entry_sector)) return 1; + + entry = buf + (fs_file.entry_index % 16) * 32; + LD_uint32_t(entry + DIR_FileSize) = fs_file.size; + fs_setEntryCluster(entry, fs_file.entry_start_cluster); + + return sd_writeBuf(fs_file.entry_sector); +} + +/************************************************************************** +* Установить смещение чтения/записи файла * +**************************************************************************/ + +#define LSEEK_STEP 32768 + +uint8_t fs_lseek(uint32_t off, uint8_t mode) +{ + uint32_t l; + + /* Режим */ + if(mode==1) off += fs_file.ptr; + else if(mode==2) off += fs_file.size; + + /* Можно заменить на fs_file.ptr = 0 для уменьшения кода*/ + if(off >= fs_file.ptr) off -= fs_file.ptr; + else fs_file.ptr = 0; + + do /* Выполняем один цикл даже для off=0, так как внутри происходит проверка на ошибки */ + { + l = off; + if(l > LSEEK_STEP) l = LSEEK_STEP; + if(fs_read0(0, (uint16_t)l)) return 1; + off -= l; + } + while(off); + + /* Размер файла мог изменится */ + fs_saveFileLength(); + + /* Результат */ + fs_tmp = fs_file.ptr; + + return 0; +} + +/************************************************************************** +* Записать в файл (шаг 1) * +***************************************************************************/ + +uint8_t fs_write_start() +{ + uint16_t len; + + /* Проверка ошибок программиста */ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + goto abort; + } + if(fs_wtotal == 0) + { + lastError = ERR_NO_DATA; + goto abort; + } +#endif + + /* Сколько можно еще дописать в этот сектор? */ + len = 512 - (uint16_t)fs_file.ptr % 512; + + /* Ограничиваем остатком данных в файле */ + if(len > fs_wtotal) len = (uint16_t)fs_wtotal; + + /* Вычисление fs_file.sector, выделение кластеров */ + if(fs_nextRWSector()) goto abort; /* Должно вылетать только по ошибкам ERR_NO_FREE_SPACE, ERR_DISK_ERR */ + + /* Корректируем длину файла */ + if(fs_file.size < fs_file.ptr + len) + { + fs_file.size = fs_file.ptr + len; + fs_file.changed = 1; + } + + /* Читаем данные сектора, если не весь сектор будет заполнен */ + if(len != 512) + { + if(sd_readBuf(fs_file.sector)) goto abort; + } + + fs_file_wlen = len; + fs_file_woff = (uint16_t)fs_file.ptr % 512; + return 0; +abort: + /* Скорее всего это ошибка ERR_NO_FREE_SPACE */ + /* Если размер файла был изменен, то надо бы сохранить изменения в описатель файла. */ + fs_saveFileLength(); + /* Закрываем файл */ +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#endif + return 1; +} + +/************************************************************************** +* Записать в файл (шаг 2) * +***************************************************************************/ + +uint8_t fs_write_end() +{ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + goto abort; + } +#endif + + /* Записываем изменения на диск */ + if(sd_writeBuf(fs_file.sector)) goto abort; + + /* В случае ошибки файл может содержать больше кластеров, чем требуется по его размеру. */ + /* Но это не плохо, данные не повреждены. А эта ошибка проявится лишь в уменьшении */ + /* места на диске. */ + + /* Счетчики */ + fs_file.ptr += fs_file_wlen; + fs_wtotal -= fs_file_wlen; + + /* Если запись закончена, сохраняем размера файла и первый кластер */ + if(fs_wtotal == 0) + { + if(fs_saveFileLength()) goto abort; + + if(fs_update_timestamp() != 0) { + /* Ошибка обновления времени - не критично, но можно вернуть ошибку */ + /* goto abort; */ /* Раскомментируйте, если хотите возвращать ошибку */ + } + } + + /* Ок */ + return 0; +abort: +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#endif + return 1; +} + +/************************************************************************** +* Освободить цепочку кластеров начиная с fs_tmp * +**************************************************************************/ + +static uint8_t fs_freeChain() +{ + uint32_t c; + while(1) + { + if(fs_tmp < 2 || fs_tmp >= fs_n_fatent) return 0; + /* Освободить кластер fs_tmp и записть в fs_tmp следующий за ним кластер */ + c = fs_tmp, fs_tmp = FREE_CLUSTER; + if(fs_setNextCluster(c)) break; /* fs_tmp будет содержать следующий кластер, так как записывается FREE_CLUSTER */ + } + return 1; +} + +/************************************************************************** +* Переместить файл/папку * +**************************************************************************/ + +uint8_t fs_move0() +{ + uint8_t* entry; + uint8_t tmp[21]; + uint16_t old_index; + uint32_t old_sector, old_start_cluster; + +#ifndef FS_DISABLE_CHECK + if(fs_file.opened == OPENED_NONE) + { + lastError = ERR_NOT_OPENED; + goto abort; + } +#endif + + /* Запоминаем старый описатель */ + old_index = fs_file.entry_index; + old_sector = fs_file.entry_sector; + old_start_cluster = fs_file.entry_start_cluster; + + /* Создаем новый файл. В папку он превратится позже. 0x80 - это предотвращаем рекурсию. */ + if(fs_open0(OPENED_FILE | 0x80)) goto abort; + + /* Предотвращаем ошибки программиста */ +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#ifndef FS_DISABLE_SWAP + fs_secondFile.opened = OPENED_NONE; +#endif +#endif + /* fs_file.sector содежит первый кластер папки, в которой находится созданный файл. */ + + /* Удаление старого файла/папки и перенос всех свойств */ + if(sd_readBuf(old_sector)) goto abort; + entry = buf + (old_index % 16) * 32; + memcpy(tmp, entry+11, 21); + entry[0] = 0xE5; + if(sd_writeBuf(old_sector)) goto abort; + + /* Копируем все свойства новому файлу, тем самым превращая его в папку */ + if(sd_readBuf(fs_file.entry_sector)) goto abort; + entry = buf + (fs_file.entry_index % 16) * 32; + memcpy(entry+11, tmp, 21); + if(sd_writeBuf(fs_file.entry_sector)) goto abort; + + /* В папке надо еще скорретировать описатель .. */ + if(entry[DIR_Attr] & AM_DIR) + { + fs_tmp = old_start_cluster; /* Первый кластер нашей папки */ + fs_clust2sect(); + if(sd_readBuf(fs_tmp)) goto abort; + fs_setEntryCluster(buf+32, fs_parent_dir_cluster); /* Первый кластер папки предка.*/ + if(sd_writeBuf(fs_tmp)) goto abort; + } + + return 0; +abort: + return 1; +} + +uint8_t fs_move(const char* from, const char* to) +{ + strcpy((char*)buf, from); + if(fs_openany()) return 1; + strcpy((char*)buf, to); + return fs_move0(); +} + +/************************************************************************** +* Удалить файл или пустую папку * +* Имя файла должно содержаться в buf и не превышать FS_MAXFILE симолов * +* включая терминатор * +**************************************************************************/ + +uint8_t fs_delete() +{ + uint32_t entrySector; + uint8_t* entry; + + /* Там будет проверен fs_type == FS_ERROR */ + if(fs_openany()) goto abort; + + /* Предотвращаем ошибки программиста */ + fs_file.opened = OPENED_NONE; +#ifndef FS_DISABLE_SWAP + fs_secondFile.opened = OPENED_NONE; +#endif + + /* Корневую папку удалять нельзя */ + if(FS_DIRENTRY[0] == 0) + { + lastError = ERR_NO_PATH; + goto abort; + } + + /* Сохраняем интерформацию о найденном файле, так как fs_readdir ниже их прибьет */ + entrySector = fs_file.entry_sector; + entry = buf + (fs_file.entry_index % 16) * 32; + + /* В папке не должно быть файлов */ + if(FS_DIRENTRY[DIR_Attr] & AM_DIR) + { + /* Перематывем папку на начало */ + fs_file.entry_able = 0; + /* Ищем первый файл или папку */ + /* fs_file.entry_start_cluster сохряняется (содержит первый кластер файла или папки) */ + if(fs_readdir_nocheck()) goto abort; + /* Если нашли, то ошибка */ + if(fs_file.entry_able) + { + lastError = ERR_DIR_NOT_EMPTY; + goto abort; + } + } + + /* Удаляем описатель */ + if(sd_readBuf(entrySector)) goto abort; + entry[0] = 0xE5; + if(sd_writeBuf(entrySector)) goto abort; + + /* Освобождаем цепочку кластеров */ + fs_tmp = fs_file.entry_start_cluster; + return fs_freeChain(); +abort: + return 1; +} +/************************************************************************** +* Обновить время последней записи файла * +* Файл должен быть открыт * +**************************************************************************/ +static uint8_t fs_update_timestamp(void) +{ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE && fs_file.opened != OPENED_DIR) + { + lastError = ERR_NOT_OPENED; + return 1; + } +#endif + + /* Получаем текущее время */ + uint16_t fat_time = fat_pack_time(); + uint16_t fat_date = fat_pack_date(); + + /* Читаем сектор с записью */ + if(sd_readBuf(fs_file.entry_sector)) return 1; + + /* Получаем указатель на запись в каталоге */ + uint8_t* entry = buf + (fs_file.entry_index % 16) * 32; + + /* Обновляем время последней записи */ + LD_uint16_t(entry + DIR_WrtTime) = fat_time; + LD_uint16_t(entry + DIR_WrtDate) = fat_date; + + /* Если время создания не установлено, устанавливаем его */ + if(LD_uint16_t(entry + DIR_CrtTime) == 0 && LD_uint16_t(entry + DIR_CrtDate) == 0) + { + LD_uint16_t(entry + DIR_CrtTime) = fat_time; + LD_uint16_t(entry + DIR_CrtDate) = fat_date; + } + + /* Сохраняем изменения */ + return sd_writeBuf(fs_file.entry_sector); +} +/************************************************************************** +* Установить конец файла * +**************************************************************************/ + +uint8_t fs_write_eof() +{ + /* Проверка ошибок программиста */ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + goto abort; + } +#endif + + /* Корректируем либо FAT, либо описатель файла. */ + if(fs_file.ptr == 0) + { + /* Удалем все кластеры файла */ + fs_tmp = fs_file.entry_start_cluster; + fs_file.entry_start_cluster = 0; + } + else + { + /* Этот кластер файла последний. */ + fs_tmp = LAST_CLUSTER; + if(fs_setNextCluster(fs_file.cluster)) goto abort; /* fs_tmp будет содержать следующий кластер, так как записывается LAST_CLUSTER */ + } + + /* Удалем все кластеры файла после этого. (они содержатся в fs_tmp); */ + if(fs_freeChain()) goto abort; + + /* Сохраняем длну и первый кластер */ + fs_file.size = fs_file.ptr; + fs_file.changed = 1; + if(!fs_saveFileLength()) return 0; + +abort: +#ifndef FS_DISABLE_CHECK + fs_file.opened = OPENED_NONE; +#endif + return 1; +} + +/************************************************************************** +* Записать в файл * +**************************************************************************/ + +uint8_t fs_write(uint8_t* ptr, uint16_t len) +{ + /* Проверка на ошибки происходит в вызываемых функциях */ + + /* Конец файла */ + if(len == 0) return fs_write_eof(); + + fs_wtotal = len; + do + { + if(fs_write_start()) goto abort; + memcpy(fs_file_wbuf, ptr, fs_file_wlen); + ptr += fs_file_wlen; + if(fs_write_end()) goto abort; + } + while(fs_wtotal); + + return 0; +abort: + return 1; +} + +/************************************************************************** +* Переключить файлы * +**************************************************************************/ + +#ifndef FS_DISABLE_SWAP +void fs_swap() +{ + /* Это занимает меньше ПЗУ, чем три функции memcpy */ + uint8_t t, *a = (uint8_t*)&fs_file, *b = (uint8_t*)&fs_secondFile, n = sizeof(File); + do + { + t=*a, *a=*b, *b=t; + ++a; + ++b; + } + while(--n); +} +#endif + +/************************************************************************** +* Расчет свободного места * +* * +* Результат в переменной fs_tmp в мегабайтах * +* Функция закрывает файл * +**************************************************************************/ + +#ifndef FS_DISABLE_GETFREESPACE +uint8_t fs_getfree() +{ + /* Мы испортим переменную fs_file.sector, поэтому закрываем файл */ + fs_file.opened = OPENED_NONE; + + /* Кол-во свободных кластеров будет в fs_file.sector */ + fs_file.sector = 0; + if(fs_allocCluster(1)) return 1; + + /* Пересчет в мегабайты */ + fs_tmp = ((fs_file.sector >> 10) + 1) / 2 * fs_csize; + + return 0; +} +#endif + +/************************************************************************** +* Размер накопителя в мегабайтах * +**************************************************************************/ + +uint8_t fs_gettotal() +{ + /* Проверка ошибок программиста */ +#ifndef FS_DISABLE_CHECK + if(fs_type == FS_ERROR) + { + lastError = ERR_NO_FILESYSTEM; + return 1; + } +#endif + + fs_tmp = ((fs_n_fatent >> 10) + 1) / 2 * fs_csize; + return 0; +} + +/************************************************************************** +* Размер файла * +**************************************************************************/ + +uint8_t fs_getfilesize() +{ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + return 1; + } +#endif + fs_tmp = fs_file.size; + return 0; +} + +/************************************************************************** +* Указатель чтения записи файла * +**************************************************************************/ + +uint8_t fs_tell() +{ +#ifndef FS_DISABLE_CHECK + if(fs_file.opened != OPENED_FILE) + { + lastError = ERR_NOT_OPENED; + return 1; + } +#endif + fs_tmp = fs_file.ptr; + return 0; +} diff --git a/components/SD_Card/fs.h b/components/SD_Card/fs.h new file mode 100644 index 0000000..84b5de4 --- /dev/null +++ b/components/SD_Card/fs.h @@ -0,0 +1,187 @@ +/* +It is an open source software to implement FAT file system to +small embedded systems. This is a free software and is opened for education, +research and commercial developments under license policy of following trems. + +(C) 2013 vinxru +(C) 2010, ChaN, all right reserved. + +It is a free software and there is NO WARRANTY. +No restriction on use. You can use, modify and redistribute it for +personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +Redistributions of source code must retain the above copyright notice. + +Version 0.99 5-05-2013 +*/ + +#ifndef _FS_H_ +#define _FS_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* Disable checking and kill the file system */ +/* С помощью этого макроса можно отключить проеерки, что бы сэкономить ПЗУ и убить файловую систему.*/ +/* #define FS_DISABLE_CHECK */ + +/* Two opened files */ +/* Два открытых файла */ +/* #define FS_DISABLE_SWAP */ + +/* Calculation of free disk space */ +/* Определение свободного места на диске */ +/* #define FS_DISABLE_GETFREESPACE */ + +/* Work buffer for filesystem */ +/* Буфер для работы файловой системы */ +extern uint8_t buf[]; + +typedef struct +{ +#ifndef FS_DISABLE_CHECK + uint8_t opened; /* Что открыто: OPENED_NONE, OPENED_FILE, OPENED_DIR */ +#endif + uint8_t entry_able; /* Результат выполнения функции fs_dirread */ + uint16_t entry_index; /* Номер записи в каталоге */ + uint32_t entry_cluster; /* Кластер записи в каталоге */ + uint32_t entry_sector; /* Сектор записи в каталоге */ + uint32_t entry_start_cluster; /* Первый сектор файла или каталога (0 - корневой каталог FAT16) */ + uint32_t ptr; /* Указатель чтения/записи файла*/ + uint32_t size; /* Размер файла / File size */ + uint32_t cluster; /* Текущий кластер файла */ + uint32_t sector; /* Текущий сектор файла */ + uint8_t changed; /* Размер файла изменился, надо сохранить */ +} File; +/* Error */ +/* Ошибки файловой системы */ + +#define ERR_OK 0 // Нет ошибки +#define ERR_NO_FILESYSTEM 1 // Файловая система не обнаружена +#define ERR_DISK_ERR 2 // Ошибка чтения/записи +#define ERR_NOT_OPENED 3 // Файл/папка не открыта +#define ERR_NO_PATH 4 // Файл/папка не найдена +#define ERR_DIR_FULL 5 // Папка содержит максимальное кол-во файлов +#define ERR_NO_FREE_SPACE 6 // Нет свободного места +#define ERR_DIR_NOT_EMPTY 7 // Нельзя удалить папку, она не пуста +#define ERR_FILE_EXISTS 8 // Файл/папка с таким именем уже существует +#define ERR_NO_DATA 9 // fs_file_wtotal=0 при вызове функции fs_write_begin + +#define ERR_MAX_FILES 10 // Не используется файловой системой, резерв +#define ERR_RECV_STRING 11 // Не используется файловой системой, резерв +#define ERR_INVALID_COMMAND 12 // Не используется файловой системой, резерв + +#define ERR_ALREADY_OPENED 13 // Файл уже открыт (fs_swap) + +/* Filesystem variables. Can change */ +/* Переменные файловой системы. Можно изменять */ + +extern uint32_t fs_tmp; +extern uint8_t lastError; /* Последняя ошибка файловой системы или диска */ // ОТСЮДА ВЫРВАЛ ПЕРЕМЕННЫЕ +extern uint16_t fs_wtotal; // Используется функциями fs_write_start, fs_write_end*/ + +extern uint8_t fs_type; /* FS_FAT16, FS_FAT32, FS_ERROR */ +/* Maximal length of file name */ +/* Максимальная длина имени */ + +#define FS_MAXFILE 469 + +/* Result of fs_readdir */ +/* Описатель прочитанный функцией fs_readdir */ + +#define FS_DIRENTRY (buf + 480) + +/* Functions. Returns not 0 if error occured. Destroy buf variable*/ +/* Функцяии. Возращают не 0, если ошибка. Все функции портят buf */ + +uint8_t fs_init(); /* Инициалиазция файловой системы / Init filesystem */ +uint8_t fs_check(); /* Проверка наличия диска, и если нужно, то его инициализация / Checking the disk and, if necessary, it will be initialized */ +uint8_t fs_readdir(); /* Прочитать содежимое папки в DIRENTRY / Read folder contents in DIRENTRY */ +uint8_t fs_delete(); /* Удалить файл или папку, имя в buf / Delete file or folder, name in buf */ +uint8_t fs_open0(uint8_t what); /* Открыть/создать файл или папку, имя в buf. Open/create file or foder, name in buf */ +uint8_t fs_move0(); /* Переместить файл/папку. Move file or folder, source file must been opened, destination name in buf */ +uint8_t fs_move(const char* from, const char* to); /* Переместить файл/папку. Move file or folder. */ +uint8_t fs_lseek(uint32_t ptr, uint8_t mode); /* Установить указатель чтения/записи файла, увеличивает размер файла. / Set file pointer, enlarge file size. */ +uint8_t fs_tell(); /* Получить указатель чтения/записи файла в fs_tmp / Get file pointer in fs_tmp. */ +uint8_t fs_getfilesize(); /* Получить размер файла / Get file size. */ +uint8_t fs_read0(uint8_t* ptr, uint16_t len); /* Прочитать из файла. НЕЛЬЗЯ ВЫХОДИТЬ ЗА ПРЕДЕЛЫ ФАЙЛА! / Read from the file, DO NOT COME OUT FILE */ +uint8_t fs_read(uint8_t* ptr, uint16_t len, uint16_t* readed); /* Прочитать из файла. / Read from the file. */ +uint8_t fs_write(uint8_t* ptr, uint16_t len); /* Записать в файл, увеличивает размер файла. / Записать в файл, enlarge file size. */ +uint8_t fs_write_eof(); /* Установить конец файла, уменьшает размер файла. / Set end of file, reduces file size */ +uint8_t fs_gettotal(); /* Общее место на диске в fs_tmp в мегабайтах / Total disk space in fs_tmp (megabytes) */ + +#ifndef FS_DISABLE_SWAP +void fs_swap(); /* Переключится на второй файл / Switch to the second file */ +#endif + +#ifndef FS_DISABLE_GETFREESPACE +uint8_t fs_getfree(); /* Свободное место на диске в fs_tmp в мегабайтах / Free disk space in fs_tmp (megabytes) */ +#endif + + +/* Функции ниже позволяют использовать для записи буфер (buf). +* The functions below can be used to write the buffer (buf). +* +* wtotal = размер данных для записи; +* while(wtotal) { +* fs_write_start(&wtotal); +* Копируем fs_file_wlen байт в fs_file_wbuf +* Ни одна функция ФС не должеа выпонятсья между ними +* fs_write_end(&wtotal); +* } +* +* See the source of fs_write +* Или смотри исходники fs_write +*/ + +#define fs_file_wlen (*(uint16_t*)&fs_tmp) +#define fs_file_woff ((uint16_t*)&fs_tmp)[1] +#define fs_file_wbuf (buf + fs_file_woff) + +uint8_t fs_write_start(); +uint8_t fs_write_end(); + +/* Derived from the function fs_open0 */ +/* Производные от функции fs_open0 */ + +uint8_t fs_open(); /* Открыть файл */ +uint8_t fs_opendir(); /* Открыть папку */ +#define fs_openany() fs_open0(OPENED_NONE) /* Открыть файл или папку */ +#define fs_create() fs_open0(OPENED_FILE) /* Создать файл */ +#define fs_createdir() fs_open0(OPENED_DIR) /* Создать папку */ + +extern File fs_file; +/* Values ??fs_opened */ +/* Значения fs_opened */ + +#define OPENED_NONE 0 +#define OPENED_FILE 1 +#define OPENED_DIR 2 + +/* File attributes */ +/* Атрибуты файлов */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ + +/* Fodler descriptor (FS_DIRENTRY) */ +/* Описатель */ + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/components/SD_Card/sd.c b/components/SD_Card/sd.c new file mode 100644 index 0000000..a43ad21 --- /dev/null +++ b/components/SD_Card/sd.c @@ -0,0 +1,298 @@ +/* +It is an open source software to implement SD routines to +small embedded systems. This is a free software and is opened for education, +research and commercial developments under license policy of following trems. + +(C) 2013 vinxru (aleksey.f.morozov@gmail.com) + +It is a free software and there is NO WARRANTY. +No restriction on use. You can use, modify and redistribute it for +personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +Redistributions of source code must retain the above copyright notice. + +Version 0.99 5-05-2013 +*/ +#ifndef F_CPU +#define F_CPU 16000000 +#endif +#include +#include +#include "spi.h" +#include "sd.h" +#include "fs.h" + +uint8_t sd_sdhc; /* Используется SDHC карта */ + +/************************************************************************** +* Протокол SPI для ATMega8 * +* Может отличаться для разных МК. * +**************************************************************************/ + +/* Куда подключена линия CS карты */ +#define SD_CS_ENABLE PORTB &= ~0x01; //SS LOW +#define SD_CS_DISABLE PORTB |= 0x01; //SS HIGH + +/* Совместимость с разными версиями CodeVisionAVR */ +#ifndef SPI2X +#define SPI2X 0 +#endif + +/************************************************************************** +* Отправка команды * +**************************************************************************/ + +/* Используемые каманды SD карты */ + +#define GO_IDLE_STATE (0x40 | 0 ) +#define SEND_IF_COND (0x40 | 8 ) +#define READ_SINGLE_BLOCK (0x40 | 17) +#define WRITE_SINGLE_BLOCK (0x40 | 24) +#define SD_SEND_OP_COND (0x40 | 41) +#define APP_CMD (0x40 | 55) +#define READ_OCR (0x40 | 58) + +static uint8_t sd_sendCommand(uint8_t cmd, uint32_t arg) +{ + uint8_t response, retry; + + /* Размещение этого кода тут -4 команды, хотя вроде лишние проверки */ + if(sd_sdhc == 0 && (cmd==READ_SINGLE_BLOCK || cmd==WRITE_SINGLE_BLOCK)) + arg <<= 9; + + /* Выбираем карту */ + SD_CS_ENABLE + + /* Заголовок команды */ + spi_transmit(cmd); + spi_transmit(((uint8_t*)&arg)[3]); + spi_transmit(((uint8_t*)&arg)[2]); + spi_transmit(((uint8_t*)&arg)[1]); + spi_transmit(((uint8_t*)&arg)[0]); + + /* Пару команд требуют CRC. Остальные же команды игнорируют его, поэтому упрощаем код */ + spi_transmit(cmd == SEND_IF_COND ? 0x87 : 0x95); + + /* Ждем подтвреждение (256 тактов) */ + retry = 0; + while((response = spi_receive()) == 0xFF) + if(++retry == 0) break; + + /* Результат команды READ_OCR обрабатываем тут, так как в конце этой функции мы снимем CS и пропускаем 1 байт */ + if(response == 0 && cmd == READ_OCR) + { + /* 32 бита из которых нас интересует один бит */ + sd_sdhc = spi_receive() & 0x40; + spi_receive(); + spi_receive(); + spi_receive(); + } + + /* отпускаем CS и пауза в 1 байт*/ + SD_CS_DISABLE + spi_receive(); + + return response; +} + +/************************************************************************** +* Проверка готовности/наличия карты * +**************************************************************************/ + +uint8_t sd_check() +{ + uint8_t i = 0; + do + { + sd_sendCommand(APP_CMD, 0); + if(sd_sendCommand(SD_SEND_OP_COND, 0x40000000) == 0) return 0; + } + while(--i); + return 1; +} + +/************************************************************************** +* Инициализация карты (эта функция вызывается функцией sd_init) * +**************************************************************************/ + +static uint8_t sd_init_int() +{ + uint8_t i; + + /* Сбрасываем SDHC флаг */ + sd_sdhc = 0; + + /* Минимум 80 пустых тактов */ + for(i=10; i; --i) + spi_receive(); + + /* CMD0 Посылаем команду сброса */ + if(sd_sendCommand(GO_IDLE_STATE, 0) != 1) goto abort; + + /* CMD8 Узнаем версию карты */ + i = 0; + if(sd_sendCommand(SEND_IF_COND, 0x000001AA)) + i = 1; + + /* CMD41 Ожидание окончания инициализации */ + if(sd_check()) goto abort; + + /* Только для второй версии карты */ + if(i) + { + /* CMD58 определение SDHC карты. Ответ обрабатывается в функции sd_sendCommand */ + if(sd_sendCommand(READ_OCR, 0) != 0) goto abort; + } + + return 0; +abort: + return 1; +} + +/************************************************************************** +* Инициализация карты * +**************************************************************************/ + +uint8_t sd_init() +{ + + LED2_DDR |= (1 << LED2_PIN); + LED1_DDR |= (1 << LED1_PIN); + + uint8_t tries; + + /* Освобождаем CS на всякий случай */ + SD_CS_DISABLE + + /* Включаем SPI */ + //spi_init(); + + /* Делаем несколько попыток инициализации */ + tries = 10; + while(sd_init_int()) + if(--tries == 0) + { + lastError = ERR_DISK_ERR; + return 1; + } + + /* Вклчюаем максимальную скорость */ + spi_highSpeed(); + + return 0; +} + +/************************************************************************** +* Ожидание определенного байта на шине * +**************************************************************************/ + +static uint8_t sd_waitBus(uint8_t byte) +{ + uint16_t retry = 0; + do + { + if(spi_receive() == byte) return 0; + } + while(++retry); + return 1; +} + +/************************************************************************** +* Чтение произвольного участка сектора * +**************************************************************************/ + +uint8_t sd_read(uint8_t* buffer, uint32_t sector, uint16_t offsetInSector, uint16_t length) +{ + LED_R_ON(); + uint8_t b; + uint16_t i; + + /* Посылаем команду */ + if(sd_sendCommand(READ_SINGLE_BLOCK, sector)) goto abort; + + /* Сразу же возращаем CS, что бы принять ответ команды */ + SD_CS_ENABLE + + /* Ждем стартовый байт */ + if(sd_waitBus(0xFE)) goto abort; + + /* Принимаем 512 байт */ + for(i=512; i; --i) + { + b = spi_receive(); + if(offsetInSector) + { + offsetInSector--; + continue; + } + if(length == 0) continue; + length--; + *buffer++ = b; + } + + /* CRC игнорируем */ + spi_receive(); + spi_receive(); + + /* отпускаем CS и пауза в 1 байт*/ + SD_CS_DISABLE + spi_receive(); + + /* Ок */ + LED_R_OFF(); + return 0; + + /* Ошибка и отпускаем CS.*/ +abort: + SD_CS_DISABLE + lastError = ERR_DISK_ERR; + LED_R_OFF(); + return 1; +} + +/************************************************************************** +* Запись сектора (512 байт) * +**************************************************************************/ + +uint8_t sd_write512(uint8_t* buffer, uint32_t sector) +{ + LED_W_ON(); + uint16_t n; + + /* Посылаем команду */ + if(sd_sendCommand(WRITE_SINGLE_BLOCK, sector)) goto abort; + + /* Сразу же возращаем CS, что бы отправить блок данных */ + SD_CS_ENABLE + + /* Посылаем стартовый байт */ + spi_transmit(0xFE); + + /* Данные */ + for(n=512; n; --n) + spi_transmit(*buffer++); + + /* CRC игнорируется */ + spi_transmit(0xFF); + spi_transmit(0xFF); + + /* Ответ МК */ + if((spi_receive() & 0x1F) != 0x05) goto abort; + + /* Ждем окончания записи, т.е. пока не освободится шина */ + if(sd_waitBus(0xFF)) goto abort; + + /* отпускаем CS и пауза в 1 байт*/ + SD_CS_DISABLE + spi_receive(); + + /* Ок */ + LED_W_OFF(); + return 0; + + /* Ошибка.*/ +abort: + SD_CS_DISABLE + lastError = ERR_DISK_ERR; + LED_W_OFF(); + return 1; +} diff --git a/components/SD_Card/sd.h b/components/SD_Card/sd.h new file mode 100644 index 0000000..119cc64 --- /dev/null +++ b/components/SD_Card/sd.h @@ -0,0 +1,45 @@ +/* +It is an open source software to implement SD routines to +small embedded systems. This is a free software and is opened for education, +research and commercial developments under license policy of following trems. + +(C) 2013 vinxru (aleksey.f.morozov@gmail.com) + +It is a free software and there is NO WARRANTY. +No restriction on use. You can use, modify and redistribute it for +personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +Redistributions of source code must retain the above copyright notice. + +Version 0.99 5-05-2013 +*/ + +#ifndef _SD_H_ +#define _SD_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define LED1_PORT PORTB +#define LED1_DDR DDRB +#define LED1_PIN PB4 + +#define LED2_PORT PORTB +#define LED2_DDR DDRB +#define LED2_PIN PB5 + +#define LED_R_ON() (LED1_PORT |= (1 << LED1_PIN)) +#define LED_R_OFF() (LED1_PORT &= ~(1 << LED1_PIN)) + +#define LED_W_ON() (LED2_PORT |= (1 << LED2_PIN)) +#define LED_W_OFF() (LED2_PORT &= ~(1 << LED2_PIN)) + +uint8_t sd_init(); /* Инициализация карты */ +uint8_t sd_check(); /* Проверка наличия карты */ +uint8_t sd_read(uint8_t* buffer, uint32_t sector, uint16_t offsetInSector, uint16_t length); /* Чтение части сектора */ +uint8_t sd_write512(uint8_t* buffer, uint32_t sector); /* Запись сектора */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/components/SD_Card/spi.c b/components/SD_Card/spi.c new file mode 100644 index 0000000..ed03976 --- /dev/null +++ b/components/SD_Card/spi.c @@ -0,0 +1,43 @@ +// SD Controller for Computer "Specialst" +// (c) 26-05-2013 vinxru (aleksey.f.morozov@gmail.com) + +// Based on sources CC Dharmani, Chennai (India) +// 1 May 2013 vinxru +#ifndef F_CPU +#define F_CPU 16000000ULL +#endif +#include "spi.h" +#include +#include +#ifndef SPI2X +#define SPI2X 0 +#endif + +void spi_init(void) +{ + DDRB = 0xF7; // + PORTB = 0xF7; // + SPCR = 0x52; // setup SPI: Master mode, MSB first, SCK phase low, SCK idle low + SPSR = 0x00; +} + +uint8_t spi_transmit(uint8_t data) +{ + SPDR = data; + while(!(SPSR & 0x80)); // Wait for transmission complete + return SPDR; +} + +uint8_t spi_receive() +{ + SPDR = 0xFF; + while(!(SPSR & 0x80)); // Wait for reception complete + return SPDR; +} + +void spi_highSpeed() +{ + SPCR = 0x50; + SPSR |= (1< + +void spi_init(); +uint8_t spi_transmit(uint8_t); +uint8_t spi_receive(); +void spi_highSpeed(); +#ifdef __cplusplus +} +#endif +#endif diff --git a/nbproject/Makefile-default.mk b/nbproject/Makefile-default.mk index 44f4df1..15ee9b7 100644 --- a/nbproject/Makefile-default.mk +++ b/nbproject/Makefile-default.mk @@ -51,17 +51,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=components/DS3231/DS3231.c components/DS3231/i2cMaster.c components/Serial.cpp IdiBusCore/IdiBus/IDIBUS_IMPL.c IdiBusCore/IdiBus/RSLink.c IdiBusCore/Required/MEMORY.c IdiBusCore/Required/MODBUS_CRC.c IdiBusCore/Required/SYSTEM.c IdiBusCore/Required/USART1.c IdiBusCore/idibus_custom.c IdiBusCore/idibus_hw.c IdiBusCore/main.c IdiBusSlave.cpp +SOURCEFILES_QUOTED_IF_SPACED=components/DS3231/DS3231.c components/DS3231/i2cMaster.c components/SD_Card/fs.c components/SD_Card/sd.c components/SD_Card/spi.c components/Serial.cpp IdiBusCore/IdiBus/IDIBUS_IMPL.c IdiBusCore/IdiBus/RSLink.c IdiBusCore/Required/MEMORY.c IdiBusCore/Required/MODBUS_CRC.c IdiBusCore/Required/SYSTEM.c IdiBusCore/Required/USART1.c IdiBusCore/idibus_custom.c IdiBusCore/idibus_hw.c IdiBusCore/main.c IdiBusSlave.cpp # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/components/DS3231/DS3231.o ${OBJECTDIR}/components/DS3231/i2cMaster.o ${OBJECTDIR}/components/Serial.o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o ${OBJECTDIR}/IdiBusCore/Required/USART1.o ${OBJECTDIR}/IdiBusCore/idibus_custom.o ${OBJECTDIR}/IdiBusCore/idibus_hw.o ${OBJECTDIR}/IdiBusCore/main.o ${OBJECTDIR}/IdiBusSlave.o -POSSIBLE_DEPFILES=${OBJECTDIR}/components/DS3231/DS3231.o.d ${OBJECTDIR}/components/DS3231/i2cMaster.o.d ${OBJECTDIR}/components/Serial.o.d ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d ${OBJECTDIR}/IdiBusCore/Required/USART1.o.d ${OBJECTDIR}/IdiBusCore/idibus_custom.o.d ${OBJECTDIR}/IdiBusCore/idibus_hw.o.d ${OBJECTDIR}/IdiBusCore/main.o.d ${OBJECTDIR}/IdiBusSlave.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/components/DS3231/DS3231.o ${OBJECTDIR}/components/DS3231/i2cMaster.o ${OBJECTDIR}/components/SD_Card/fs.o ${OBJECTDIR}/components/SD_Card/sd.o ${OBJECTDIR}/components/SD_Card/spi.o ${OBJECTDIR}/components/Serial.o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o ${OBJECTDIR}/IdiBusCore/Required/USART1.o ${OBJECTDIR}/IdiBusCore/idibus_custom.o ${OBJECTDIR}/IdiBusCore/idibus_hw.o ${OBJECTDIR}/IdiBusCore/main.o ${OBJECTDIR}/IdiBusSlave.o +POSSIBLE_DEPFILES=${OBJECTDIR}/components/DS3231/DS3231.o.d ${OBJECTDIR}/components/DS3231/i2cMaster.o.d ${OBJECTDIR}/components/SD_Card/fs.o.d ${OBJECTDIR}/components/SD_Card/sd.o.d ${OBJECTDIR}/components/SD_Card/spi.o.d ${OBJECTDIR}/components/Serial.o.d ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d ${OBJECTDIR}/IdiBusCore/Required/USART1.o.d ${OBJECTDIR}/IdiBusCore/idibus_custom.o.d ${OBJECTDIR}/IdiBusCore/idibus_hw.o.d ${OBJECTDIR}/IdiBusCore/main.o.d ${OBJECTDIR}/IdiBusSlave.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/components/DS3231/DS3231.o ${OBJECTDIR}/components/DS3231/i2cMaster.o ${OBJECTDIR}/components/Serial.o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o ${OBJECTDIR}/IdiBusCore/Required/USART1.o ${OBJECTDIR}/IdiBusCore/idibus_custom.o ${OBJECTDIR}/IdiBusCore/idibus_hw.o ${OBJECTDIR}/IdiBusCore/main.o ${OBJECTDIR}/IdiBusSlave.o +OBJECTFILES=${OBJECTDIR}/components/DS3231/DS3231.o ${OBJECTDIR}/components/DS3231/i2cMaster.o ${OBJECTDIR}/components/SD_Card/fs.o ${OBJECTDIR}/components/SD_Card/sd.o ${OBJECTDIR}/components/SD_Card/spi.o ${OBJECTDIR}/components/Serial.o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o ${OBJECTDIR}/IdiBusCore/Required/USART1.o ${OBJECTDIR}/IdiBusCore/idibus_custom.o ${OBJECTDIR}/IdiBusCore/idibus_hw.o ${OBJECTDIR}/IdiBusCore/main.o ${OBJECTDIR}/IdiBusSlave.o # Source Files -SOURCEFILES=components/DS3231/DS3231.c components/DS3231/i2cMaster.c components/Serial.cpp IdiBusCore/IdiBus/IDIBUS_IMPL.c IdiBusCore/IdiBus/RSLink.c IdiBusCore/Required/MEMORY.c IdiBusCore/Required/MODBUS_CRC.c IdiBusCore/Required/SYSTEM.c IdiBusCore/Required/USART1.c IdiBusCore/idibus_custom.c IdiBusCore/idibus_hw.c IdiBusCore/main.c IdiBusSlave.cpp +SOURCEFILES=components/DS3231/DS3231.c components/DS3231/i2cMaster.c components/SD_Card/fs.c components/SD_Card/sd.c components/SD_Card/spi.c components/Serial.cpp IdiBusCore/IdiBus/IDIBUS_IMPL.c IdiBusCore/IdiBus/RSLink.c IdiBusCore/Required/MEMORY.c IdiBusCore/Required/MODBUS_CRC.c IdiBusCore/Required/SYSTEM.c IdiBusCore/Required/USART1.c IdiBusCore/idibus_custom.c IdiBusCore/idibus_hw.c IdiBusCore/main.c IdiBusSlave.cpp # Pack Options PACK_COMPILER_OPTIONS=-I "${DFP_DIR}/include" @@ -126,168 +126,204 @@ endif # ------------------------------------------------------------------------------------ # Rules for buildStep: compile ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/components/DS3231/DS3231.o: components/DS3231/DS3231.c .generated_files/flags/default/50350ab519a922d0263486f669cf2669f2c8512c .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/DS3231/DS3231.o: components/DS3231/DS3231.c .generated_files/flags/default/b75e98c10091e4a3d2512cd80a7ec3a72047b40b .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components/DS3231" @${RM} ${OBJECTDIR}/components/DS3231/DS3231.o.d @${RM} ${OBJECTDIR}/components/DS3231/DS3231.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT ${OBJECTDIR}/components/DS3231/DS3231.o -o ${OBJECTDIR}/components/DS3231/DS3231.o components/DS3231/DS3231.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT ${OBJECTDIR}/components/DS3231/DS3231.o -o ${OBJECTDIR}/components/DS3231/DS3231.o components/DS3231/DS3231.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/components/DS3231/i2cMaster.o: components/DS3231/i2cMaster.c .generated_files/flags/default/5f0f8ce9bd702055c7459161074d9f521bbac4f5 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/DS3231/i2cMaster.o: components/DS3231/i2cMaster.c .generated_files/flags/default/2e003f1c90afcc4bcf8fae966da40573e8ce5e04 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components/DS3231" @${RM} ${OBJECTDIR}/components/DS3231/i2cMaster.o.d @${RM} ${OBJECTDIR}/components/DS3231/i2cMaster.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT ${OBJECTDIR}/components/DS3231/i2cMaster.o -o ${OBJECTDIR}/components/DS3231/i2cMaster.o components/DS3231/i2cMaster.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) - -${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o: IdiBusCore/IdiBus/IDIBUS_IMPL.c .generated_files/flags/default/d4d431dd98aa10b3ebf5ed5198710bcf91594af1 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT ${OBJECTDIR}/components/DS3231/i2cMaster.o -o ${OBJECTDIR}/components/DS3231/i2cMaster.o components/DS3231/i2cMaster.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/fs.o: components/SD_Card/fs.c .generated_files/flags/default/55081227c8cb484c185bad33ddc641fdb66c2622 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/fs.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/fs.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/fs.o.d" -MT "${OBJECTDIR}/components/SD_Card/fs.o.d" -MT ${OBJECTDIR}/components/SD_Card/fs.o -o ${OBJECTDIR}/components/SD_Card/fs.o components/SD_Card/fs.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/sd.o: components/SD_Card/sd.c .generated_files/flags/default/7921bcecca57ada4d2f522ba653083e83e13fbf1 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/sd.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/sd.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/sd.o.d" -MT "${OBJECTDIR}/components/SD_Card/sd.o.d" -MT ${OBJECTDIR}/components/SD_Card/sd.o -o ${OBJECTDIR}/components/SD_Card/sd.o components/SD_Card/sd.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/spi.o: components/SD_Card/spi.c .generated_files/flags/default/cdd251aca53eba973585c4de57770317e0179d56 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/spi.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/spi.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/spi.o.d" -MT "${OBJECTDIR}/components/SD_Card/spi.o.d" -MT ${OBJECTDIR}/components/SD_Card/spi.o -o ${OBJECTDIR}/components/SD_Card/spi.o components/SD_Card/spi.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o: IdiBusCore/IdiBus/IDIBUS_IMPL.c .generated_files/flags/default/294fe03370ad5f2d3e056c5d8da6d46fd744c891 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/IdiBus" @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o IdiBusCore/IdiBus/IDIBUS_IMPL.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o IdiBusCore/IdiBus/IDIBUS_IMPL.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o: IdiBusCore/IdiBus/RSLink.c .generated_files/flags/default/9839f1789d4cecd384998fc265b74172eabf8e9f .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o: IdiBusCore/IdiBus/RSLink.c .generated_files/flags/default/47cc985eb1387524739d82d9025d8fb8fe4787c8 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/IdiBus" @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o IdiBusCore/IdiBus/RSLink.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o IdiBusCore/IdiBus/RSLink.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/MEMORY.o: IdiBusCore/Required/MEMORY.c .generated_files/flags/default/d5e0a3f622a3c23d966dfd7b6b62e4df504c81ad .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/MEMORY.o: IdiBusCore/Required/MEMORY.c .generated_files/flags/default/40df7c0de9c936c2c5131933525bbbfab195525c .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o -o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o IdiBusCore/Required/MEMORY.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o -o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o IdiBusCore/Required/MEMORY.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o: IdiBusCore/Required/MODBUS_CRC.c .generated_files/flags/default/59c6757c6c97bb5795d63980114e0e3dabe10f19 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o: IdiBusCore/Required/MODBUS_CRC.c .generated_files/flags/default/385cc08c60dd6e709d55d44575fe941f1671b08b .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o -o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o IdiBusCore/Required/MODBUS_CRC.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o -o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o IdiBusCore/Required/MODBUS_CRC.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o: IdiBusCore/Required/SYSTEM.c .generated_files/flags/default/379a7b6cd9ef82ad09306bb445e8fc1222b35185 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o: IdiBusCore/Required/SYSTEM.c .generated_files/flags/default/ebb1cf0e0523923a979dad0682169e80f597135f .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o -o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o IdiBusCore/Required/SYSTEM.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o -o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o IdiBusCore/Required/SYSTEM.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/USART1.o: IdiBusCore/Required/USART1.c .generated_files/flags/default/e431a3c715f2ed28f1ac349726ae939d24645491 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/USART1.o: IdiBusCore/Required/USART1.c .generated_files/flags/default/55a6e4eb53d90b2f05b7e590f6fe6befe1652735 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/USART1.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/USART1.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/USART1.o -o ${OBJECTDIR}/IdiBusCore/Required/USART1.o IdiBusCore/Required/USART1.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/USART1.o -o ${OBJECTDIR}/IdiBusCore/Required/USART1.o IdiBusCore/Required/USART1.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/idibus_custom.o: IdiBusCore/idibus_custom.c .generated_files/flags/default/bb6c41e49678b27546812558e3e5a44aacffa140 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/idibus_custom.o: IdiBusCore/idibus_custom.c .generated_files/flags/default/b350bf2ba11210bbcaffd22c579b41795256993e .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/idibus_custom.o.d @${RM} ${OBJECTDIR}/IdiBusCore/idibus_custom.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_custom.o -o ${OBJECTDIR}/IdiBusCore/idibus_custom.o IdiBusCore/idibus_custom.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_custom.o -o ${OBJECTDIR}/IdiBusCore/idibus_custom.o IdiBusCore/idibus_custom.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/idibus_hw.o: IdiBusCore/idibus_hw.c .generated_files/flags/default/da9dc502576eae6c26465a743cd0ff692d91eb24 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/idibus_hw.o: IdiBusCore/idibus_hw.c .generated_files/flags/default/6b26d97c0e3dac990fb8a4928e81f26e38eb149c .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/idibus_hw.o.d @${RM} ${OBJECTDIR}/IdiBusCore/idibus_hw.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_hw.o -o ${OBJECTDIR}/IdiBusCore/idibus_hw.o IdiBusCore/idibus_hw.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_hw.o -o ${OBJECTDIR}/IdiBusCore/idibus_hw.o IdiBusCore/idibus_hw.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/main.o: IdiBusCore/main.c .generated_files/flags/default/7035e2061def77ffab54fc4f6211a13f114becfd .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/main.o: IdiBusCore/main.c .generated_files/flags/default/8d3cd6ed16a6c5d75aa2b5797a643fefec51ea9 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/main.o.d @${RM} ${OBJECTDIR}/IdiBusCore/main.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/main.o.d" -MT "${OBJECTDIR}/IdiBusCore/main.o.d" -MT ${OBJECTDIR}/IdiBusCore/main.o -o ${OBJECTDIR}/IdiBusCore/main.o IdiBusCore/main.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/main.o.d" -MT "${OBJECTDIR}/IdiBusCore/main.o.d" -MT ${OBJECTDIR}/IdiBusCore/main.o -o ${OBJECTDIR}/IdiBusCore/main.o IdiBusCore/main.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) else -${OBJECTDIR}/components/DS3231/DS3231.o: components/DS3231/DS3231.c .generated_files/flags/default/72f82099cef6c6b2219a07033155140b2939f22 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/DS3231/DS3231.o: components/DS3231/DS3231.c .generated_files/flags/default/b82907f8ec51d30775f8a003a46eddee233a1059 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components/DS3231" @${RM} ${OBJECTDIR}/components/DS3231/DS3231.o.d @${RM} ${OBJECTDIR}/components/DS3231/DS3231.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT ${OBJECTDIR}/components/DS3231/DS3231.o -o ${OBJECTDIR}/components/DS3231/DS3231.o components/DS3231/DS3231.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT "${OBJECTDIR}/components/DS3231/DS3231.o.d" -MT ${OBJECTDIR}/components/DS3231/DS3231.o -o ${OBJECTDIR}/components/DS3231/DS3231.o components/DS3231/DS3231.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/components/DS3231/i2cMaster.o: components/DS3231/i2cMaster.c .generated_files/flags/default/f4821df3154d6c2b20eb2bbcc5ab87cdbc115867 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/DS3231/i2cMaster.o: components/DS3231/i2cMaster.c .generated_files/flags/default/7fbac4260dc4506cf9df4c5b47618e1dad495fa8 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components/DS3231" @${RM} ${OBJECTDIR}/components/DS3231/i2cMaster.o.d @${RM} ${OBJECTDIR}/components/DS3231/i2cMaster.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT ${OBJECTDIR}/components/DS3231/i2cMaster.o -o ${OBJECTDIR}/components/DS3231/i2cMaster.o components/DS3231/i2cMaster.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) - -${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o: IdiBusCore/IdiBus/IDIBUS_IMPL.c .generated_files/flags/default/cd005048c20b4f8408aae8d847ce275f41fb78e8 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT "${OBJECTDIR}/components/DS3231/i2cMaster.o.d" -MT ${OBJECTDIR}/components/DS3231/i2cMaster.o -o ${OBJECTDIR}/components/DS3231/i2cMaster.o components/DS3231/i2cMaster.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/fs.o: components/SD_Card/fs.c .generated_files/flags/default/5f5c356b731fd3b942000f0db68e133f17482ec1 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/fs.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/fs.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/fs.o.d" -MT "${OBJECTDIR}/components/SD_Card/fs.o.d" -MT ${OBJECTDIR}/components/SD_Card/fs.o -o ${OBJECTDIR}/components/SD_Card/fs.o components/SD_Card/fs.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/sd.o: components/SD_Card/sd.c .generated_files/flags/default/6fbb47a355f15ac50f680669fdefcfed62153308 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/sd.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/sd.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/sd.o.d" -MT "${OBJECTDIR}/components/SD_Card/sd.o.d" -MT ${OBJECTDIR}/components/SD_Card/sd.o -o ${OBJECTDIR}/components/SD_Card/sd.o components/SD_Card/sd.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/components/SD_Card/spi.o: components/SD_Card/spi.c .generated_files/flags/default/a6e8e7e83c647792aafdff9be56af1bce2745c1b .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 + @${MKDIR} "${OBJECTDIR}/components/SD_Card" + @${RM} ${OBJECTDIR}/components/SD_Card/spi.o.d + @${RM} ${OBJECTDIR}/components/SD_Card/spi.o + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/SD_Card/spi.o.d" -MT "${OBJECTDIR}/components/SD_Card/spi.o.d" -MT ${OBJECTDIR}/components/SD_Card/spi.o -o ${OBJECTDIR}/components/SD_Card/spi.o components/SD_Card/spi.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + +${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o: IdiBusCore/IdiBus/IDIBUS_IMPL.c .generated_files/flags/default/8e1c3ba5ae7c14fc1462d33518cd5efd42714ecc .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/IdiBus" @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o IdiBusCore/IdiBus/IDIBUS_IMPL.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/IDIBUS_IMPL.o IdiBusCore/IdiBus/IDIBUS_IMPL.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o: IdiBusCore/IdiBus/RSLink.c .generated_files/flags/default/c7c590bff8a3cd1ff6caac7956f76f0713d3c72c .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o: IdiBusCore/IdiBus/RSLink.c .generated_files/flags/default/5d9a54c45df71cf9c94ec36953af20c0fd70d8df .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/IdiBus" @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d @${RM} ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o IdiBusCore/IdiBus/RSLink.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT "${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o.d" -MT ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o -o ${OBJECTDIR}/IdiBusCore/IdiBus/RSLink.o IdiBusCore/IdiBus/RSLink.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/MEMORY.o: IdiBusCore/Required/MEMORY.c .generated_files/flags/default/6489ce70cb5491fb242d4fa2a70838316094d175 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/MEMORY.o: IdiBusCore/Required/MEMORY.c .generated_files/flags/default/3f232dfffd6a73d52e3b8a6e242bd608a55b9c58 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o -o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o IdiBusCore/Required/MEMORY.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MEMORY.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o -o ${OBJECTDIR}/IdiBusCore/Required/MEMORY.o IdiBusCore/Required/MEMORY.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o: IdiBusCore/Required/MODBUS_CRC.c .generated_files/flags/default/647a86467f894d9ed24dfdd8ac0feffafd870282 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o: IdiBusCore/Required/MODBUS_CRC.c .generated_files/flags/default/d7c3301b35003da8a7c0b8d98383b42b01106911 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o -o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o IdiBusCore/Required/MODBUS_CRC.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o -o ${OBJECTDIR}/IdiBusCore/Required/MODBUS_CRC.o IdiBusCore/Required/MODBUS_CRC.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o: IdiBusCore/Required/SYSTEM.c .generated_files/flags/default/5d83f5de92a231238f8f75df1b3ef94b8a05b409 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o: IdiBusCore/Required/SYSTEM.c .generated_files/flags/default/4f0afe68cdaa8002f344e907180f663f8d414c88 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o -o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o IdiBusCore/Required/SYSTEM.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o -o ${OBJECTDIR}/IdiBusCore/Required/SYSTEM.o IdiBusCore/Required/SYSTEM.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/Required/USART1.o: IdiBusCore/Required/USART1.c .generated_files/flags/default/66613652c2b2c02215110a36db1c06e0e2c393e8 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/Required/USART1.o: IdiBusCore/Required/USART1.c .generated_files/flags/default/a5e955a507daf869605c5e73aaeca01c6c8b588e .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore/Required" @${RM} ${OBJECTDIR}/IdiBusCore/Required/USART1.o.d @${RM} ${OBJECTDIR}/IdiBusCore/Required/USART1.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/USART1.o -o ${OBJECTDIR}/IdiBusCore/Required/USART1.o IdiBusCore/Required/USART1.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT "${OBJECTDIR}/IdiBusCore/Required/USART1.o.d" -MT ${OBJECTDIR}/IdiBusCore/Required/USART1.o -o ${OBJECTDIR}/IdiBusCore/Required/USART1.o IdiBusCore/Required/USART1.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/idibus_custom.o: IdiBusCore/idibus_custom.c .generated_files/flags/default/bf2fde24ac6c3b2e1ed27f7b2984cd7479c9656b .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/idibus_custom.o: IdiBusCore/idibus_custom.c .generated_files/flags/default/36dde7ad5571bbfe1f1be8df9047ae0b5c825ec7 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/idibus_custom.o.d @${RM} ${OBJECTDIR}/IdiBusCore/idibus_custom.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_custom.o -o ${OBJECTDIR}/IdiBusCore/idibus_custom.o IdiBusCore/idibus_custom.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_custom.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_custom.o -o ${OBJECTDIR}/IdiBusCore/idibus_custom.o IdiBusCore/idibus_custom.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/idibus_hw.o: IdiBusCore/idibus_hw.c .generated_files/flags/default/85e7255b11423cb24ed1ba94824b46f2d7264f30 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/idibus_hw.o: IdiBusCore/idibus_hw.c .generated_files/flags/default/acfece918ef43e8b0b80f46b10283761e988fc97 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/idibus_hw.o.d @${RM} ${OBJECTDIR}/IdiBusCore/idibus_hw.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_hw.o -o ${OBJECTDIR}/IdiBusCore/idibus_hw.o IdiBusCore/idibus_hw.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT "${OBJECTDIR}/IdiBusCore/idibus_hw.o.d" -MT ${OBJECTDIR}/IdiBusCore/idibus_hw.o -o ${OBJECTDIR}/IdiBusCore/idibus_hw.o IdiBusCore/idibus_hw.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusCore/main.o: IdiBusCore/main.c .generated_files/flags/default/11cb3fdede3c3e0bc7601382ea36e8f9a9e9af7 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusCore/main.o: IdiBusCore/main.c .generated_files/flags/default/4d9ad3287ca0ac5dcc2881eda46d6b1d381d8957 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/IdiBusCore" @${RM} ${OBJECTDIR}/IdiBusCore/main.o.d @${RM} ${OBJECTDIR}/IdiBusCore/main.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/main.o.d" -MT "${OBJECTDIR}/IdiBusCore/main.o.d" -MT ${OBJECTDIR}/IdiBusCore/main.o -o ${OBJECTDIR}/IdiBusCore/main.o IdiBusCore/main.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusCore/main.o.d" -MT "${OBJECTDIR}/IdiBusCore/main.o.d" -MT ${OBJECTDIR}/IdiBusCore/main.o -o ${OBJECTDIR}/IdiBusCore/main.o IdiBusCore/main.c -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) endif # ------------------------------------------------------------------------------------ # Rules for buildStep: compileCPP ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/components/Serial.o: components/Serial.cpp .generated_files/flags/default/8fcc39c7d89bf344ed713ab9b0cafd1d950b4274 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/Serial.o: components/Serial.cpp .generated_files/flags/default/6eedc515731fe03625541b8092b6e2e14b502d54 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components" @${RM} ${OBJECTDIR}/components/Serial.o.d @${RM} ${OBJECTDIR}/components/Serial.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/Serial.o.d" -MT "${OBJECTDIR}/components/Serial.o.d" -MT ${OBJECTDIR}/components/Serial.o -o ${OBJECTDIR}/components/Serial.o components/Serial.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/Serial.o.d" -MT "${OBJECTDIR}/components/Serial.o.d" -MT ${OBJECTDIR}/components/Serial.o -o ${OBJECTDIR}/components/Serial.o components/Serial.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusSlave.o: IdiBusSlave.cpp .generated_files/flags/default/83436abf1f13efcdacae23c23d8225887da720bf .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusSlave.o: IdiBusSlave.cpp .generated_files/flags/default/b201acfeede6feccd0fa1700341cbee099995410 .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/IdiBusSlave.o.d @${RM} ${OBJECTDIR}/IdiBusSlave.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusSlave.o.d" -MT "${OBJECTDIR}/IdiBusSlave.o.d" -MT ${OBJECTDIR}/IdiBusSlave.o -o ${OBJECTDIR}/IdiBusSlave.o IdiBusSlave.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -g -DDEBUG -gdwarf-2 -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusSlave.o.d" -MT "${OBJECTDIR}/IdiBusSlave.o.d" -MT ${OBJECTDIR}/IdiBusSlave.o -o ${OBJECTDIR}/IdiBusSlave.o IdiBusSlave.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) else -${OBJECTDIR}/components/Serial.o: components/Serial.cpp .generated_files/flags/default/172261e5988e0bda69a64282f5d4b9236e1a0e3a .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/components/Serial.o: components/Serial.cpp .generated_files/flags/default/4efb7f259b35c5d96582e543d03584a80a9b79fe .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}/components" @${RM} ${OBJECTDIR}/components/Serial.o.d @${RM} ${OBJECTDIR}/components/Serial.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/Serial.o.d" -MT "${OBJECTDIR}/components/Serial.o.d" -MT ${OBJECTDIR}/components/Serial.o -o ${OBJECTDIR}/components/Serial.o components/Serial.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/components/Serial.o.d" -MT "${OBJECTDIR}/components/Serial.o.d" -MT ${OBJECTDIR}/components/Serial.o -o ${OBJECTDIR}/components/Serial.o components/Serial.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -${OBJECTDIR}/IdiBusSlave.o: IdiBusSlave.cpp .generated_files/flags/default/a74bbcadb7d2e80a057d3584c526c3f5b6668a6d .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 +${OBJECTDIR}/IdiBusSlave.o: IdiBusSlave.cpp .generated_files/flags/default/f55a6a38fd719d90fe5cac592208ad78e426f4d .generated_files/flags/default/da39a3ee5e6b4b0d3255bfef95601890afd80709 @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/IdiBusSlave.o.d @${RM} ${OBJECTDIR}/IdiBusSlave.o - ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/FatFS" -I"components/DS3231" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusSlave.o.d" -MT "${OBJECTDIR}/IdiBusSlave.o.d" -MT ${OBJECTDIR}/IdiBusSlave.o -o ${OBJECTDIR}/IdiBusSlave.o IdiBusSlave.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) + ${MP_CPPC} $(MP_EXTRA_CC_PRE) -mmcu=atmega1280 ${PACK_COMPILER_OPTIONS} ${PACK_COMMON_OPTIONS} -x c++ -c -D__$(MP_PROCESSOR_OPTION)__ -I"IdiBusCore" -I"IdiBusCore/IdiBus" -I"IdiBusCore/Required" -I"components" -I"components/DS3231" -I"components/SD_Card" -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "${OBJECTDIR}/IdiBusSlave.o.d" -MT "${OBJECTDIR}/IdiBusSlave.o.d" -MT ${OBJECTDIR}/IdiBusSlave.o -o ${OBJECTDIR}/IdiBusSlave.o IdiBusSlave.cpp -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) endif diff --git a/nbproject/Makefile-genesis.properties b/nbproject/Makefile-genesis.properties index 35558ad..7803e94 100644 --- a/nbproject/Makefile-genesis.properties +++ b/nbproject/Makefile-genesis.properties @@ -1,13 +1,13 @@ # -#Wed Jun 17 19:22:07 MSK 2026 +#Thu Jun 18 18:11:42 MSK 2026 default.languagetoolchain.version=14.2.0 default.Pack.dfplocation=C\:\\Users\\Michail\\.mchp_packs\\Microchip\\ATmega_DFP\\3.5.296 default.com-microchip-mplab-nbide-toolchain-avr-AVRLanguageToolchain.md5=7077cb0f7d3286937e616ce3e96e957a conf.ids=default default.languagetoolchain.dir=C\:\\Users\\Michail\\AVR\\cooler_tool\\bin -host.id=1au8-yc59-u8 +host.id=j20m-9n47-m default.platformTool.md5=null -configurations-xml=f542f1386b31395cd747c126941e36e0 +configurations-xml=ce6ff5c6abf1abdba4979c3ef20c7ea4 com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=6cd85c1014597ae4d039afea70fe46c5 proj.dir=C\:\\Users\\Michail\\MPLABXProjects\\IdiBus_Logger host.platform=windows