/* Драйвер SPI EEPROM, адресация, страницы и автомат завершения операций. Русские пояснения сохранены в UTF-8. */ /* Начинает условие: __SPISE2P_H__ ещё не определён; защищает повторное включение или задаёт значение сборки. */ #ifndef __SPISE2P_H__ /* Определяет защитный символ или переключатель __SPISE2P_H__ для последующей компиляции. */ #define __SPISE2P_H__ /* Physical EEPROM layout shared with the linker and SETGUI. */ /* Подключает "eeprom_config.h": выбор профиля физически установленной EEPROM при сборке. */ #include "eeprom_config.h" /* Подключает "include/balsam167_eeprom_layout.h": настройки и интерфейс balsam167_eeprom_layout. */ #include "include/balsam167_eeprom_layout.h" // Ёмкость памати в байтах /* Preserve compact 16-bit arithmetic for the original 32-KiB build. * Only the large part needs 32-bit word addresses and transfer lengths. */ /* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */ #if EEPROM_M95M02 /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef unsigned long SE2P_SIZE; /* Выбирает альтернативный блок текущего условия компиляции. */ #else /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef unsigned int SE2P_SIZE; /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Задаёт SEEPROM_LEN = BALSAM167_EEPROM_BYTES; данные SEEPROM_LEN. */ #define SEEPROM_LEN BALSAM167_EEPROM_BYTES /* Задаёт NULL = 0; данные NULL. */ #define NULL 0 /* Задаёт SIXTEEN_BIT = 15; SIXTEEN бит. */ #define SIXTEEN_BIT 15 /* Задаёт EIGHT_BIT = 07; EIGHT бит. */ #define EIGHT_BIT 07 /***************************************************************/ /* Configurable Parameter for SPI bus Serial EEPROM */ /***************************************************************/ /* Задаёт SPISE2P_DATA_WIDTH = SIXTEEN_BIT; 2 P данные WIDTH. */ #define SPISE2P_DATA_WIDTH SIXTEEN_BIT//EIGHT_BIT /* Задаёт SPISE2P_ADDR_WIDTH = SIXTEEN_BIT; данные SPISE2P_ADDR_WIDTH. */ #define SPISE2P_ADDR_WIDTH SIXTEEN_BIT /* Задаёт SPIBAUD_REG_VAL = 1; данные SPIBAUD_REG_VAL. */ #define SPIBAUD_REG_VAL 1//12 /* Задаёт SPICLK_PHASE = 1; SPICLK фаза. */ #define SPICLK_PHASE 1 /* Задаёт SPICLK_POLARITY = 0; данные SPICLK_POLARITY. */ #define SPICLK_POLARITY 0 /* Задаёт SPIBAUD_RATE = 100000; данные SPIBAUD_RATE. */ #define SPIBAUD_RATE 100000 //10000000 /**************************************************************/ /**************************************************************/ /* Serial EEPROM Command words, left justified */ /* Задаёт SPISE2P_READ_CMD = 0x0300; 2 P чтение CMD. */ #define SPISE2P_READ_CMD 0x0300 /* Задаёт SPISE2P_WRITE_CMD = 0x0200; 2 P запись CMD. */ #define SPISE2P_WRITE_CMD 0x0200 /* Задаёт SPISE2P_WRDI_CMD = 0x0400; данные SPISE2P_WRDI_CMD. */ #define SPISE2P_WRDI_CMD 0x0400 /* Задаёт SPISE2P_WREN_CMD = 0x0600; данные SPISE2P_WREN_CMD. */ #define SPISE2P_WREN_CMD 0x0600 /* Задаёт SPISE2P_RDSR_CMD = 0x0500; данные SPISE2P_RDSR_CMD. */ #define SPISE2P_RDSR_CMD 0x0500 /* Задаёт SPISE2P_WRSR_CMD = 0x0100; данные SPISE2P_WRSR_CMD. */ #define SPISE2P_WRSR_CMD 0x0100 /* Задаёт SPISE2P_RDID_CMD = 0x0A00; данные SPISE2P_RDID_CMD. */ #define SPISE2P_RDID_CMD 0x0A00 /* Задаёт SPISE2P_DUMMY_DATA = 0x0000; 2 P DUMMY данные. */ #define SPISE2P_DUMMY_DATA 0x0000 /* Задаёт SPISE2P_BUSY_MASK = 0x01; 2 P BUSY маска. */ #define SPISE2P_BUSY_MASK 0x01 /* Symbolic constant for SPICCR to transfer 8bit or 16 bit value*/ /* Задаёт SPISE2P_TFR16BIT = 0x80|(SPICLK_POLARITY<<6)|SIXTEEN_BIT; 2 P 16 бит. */ #define SPISE2P_TFR16BIT 0x80|(SPICLK_POLARITY<<6)|SIXTEEN_BIT /* Задаёт SPISE2P_TFR8BIT = 0x80|(SPICLK_POLARITY<<6)|EIGHT_BIT; 2 P 8 бит. */ #define SPISE2P_TFR8BIT 0x80|(SPICLK_POLARITY<<6)|EIGHT_BIT /* Status valus */ #define SPISE2P_WRRQ 1 /* Write Requset */ /* Задаёт SPISE2P_WRRQ = 1; данные SPISE2P_WRRQ. */ #define SPISE2P_RDRQ 2 /* Read request */ /* Задаёт SPISE2P_RDRQ = 2; данные SPISE2P_RDRQ. */ #define SPISE2P_WRIP 4 /* Write in progress */ /* Задаёт SPISE2P_WRIP = 4; данные SPISE2P_WRIP. */ #define SPISE2P_RDIP 8 /* Read in progress */ /* Задаёт SPISE2P_RDIP = 8; данные SPISE2P_RDIP. */ /* Message declaration */ /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { unsigned int *dataPtr; /* Data pointer */ /* Объявляет dataPtr — данные Ptr. Хранит указатель на данные. */ unsigned long nrData; /* number of data */ /* Объявляет nrData — nr данные. */ unsigned long se2pAddr; /* se2pAddr */ /* Объявляет se2pAddr — данные se2pAddr. */ /* Продолжает список аргументов, полей или выражение }SE2P_DATA;; порядок элементов сохраняется. */ }SE2P_DATA; /* Object declaration */ /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { /* Main loop publishes the descriptor before setting csr; Timer2 consumes it. * Both accesses are volatile so optimization cannot publish the request first. */ /* Продолжает список аргументов, полей или выражение SE2P_DATA * volatile msgPtr;; порядок элементов сохраняется. */ SE2P_DATA * volatile msgPtr; volatile unsigned int csr; /* control/status register */ /* Объявляет csr — данные csr. volatile требует фактического чтения или записи при каждом доступе. */ /* Вызывает void с аргументами (*init)(void *) в текущей последовательности операций. */ void (*init)(void *); /* Вызывает void с аргументами (*tick)(void *) в текущей последовательности операций. */ void (*tick)(void *); /* Вызывает void с аргументами (*csset)(void) в текущей последовательности операций. */ void (*csset)(void); /* Вызывает void с аргументами (*csclr)(void) в текущей последовательности операций. */ void (*csclr)(void); /* Продолжает список аргументов, полей или выражение }SPISE2P_DRV;; порядок элементов сохраняется. */ }SPISE2P_DRV; /* Задаёт SPISE2P_DRV_DEFAULTS = { NULL,; данные SPISE2P_DRV_DEFAULTS. */ #define SPISE2P_DRV_DEFAULTS { NULL,\ 0,/* Элемент постоянной таблицы 0,; порядок значений совпадает с порядком индексов потребителя. */ \ (void (*)(void *))SPISE2P_DRV_init,/* Продолжает список аргументов, полей или выражение (void (*)(void *))SPISE2P_DRV_init,; порядок элементов сохраняется. */ \ (void (*)(void *))SPISE2P_DRV_tick,/* Продолжает список аргументов, полей или выражение (void (*)(void *))SPISE2P_DRV_tick,; порядок элементов сохраняется. */ \ (void (*)(void))SPISE2P_DRV_csset,/* Продолжает список аргументов, полей или выражение (void (*)(void))SPISE2P_DRV_csset,; порядок элементов сохраняется. */ \ (void (*)(void))SPISE2P_DRV_csclr} /* Продолжает список аргументов, полей или выражение (void (*)(void))SPISE2P_DRV_csclr}; порядок элементов сохраняется. */ /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef SPISE2P_DRV *SPISE2P_DRV_handle; /* Объявляет интерфейс функции SPISE2P_DRV_init; реализация вызывается через этот прототип. */ void SPISE2P_DRV_init(SPISE2P_DRV * ); /* Продвигает неблокирующий автомат SPI EEPROM: команда, адрес, данные и ожидание завершения записи. */ void SPISE2P_DRV_tick(SPISE2P_DRV *); /* Объявляет интерфейс функции SPISE2P_DRV_csset; реализация вызывается через этот прототип. */ void SPISE2P_DRV_csset(void); /* Объявляет интерфейс функции SPISE2P_DRV_csclr; реализация вызывается через этот прототип. */ void SPISE2P_DRV_csclr(void); /* Проверяет завершение текущего задания SPI EEPROM перед постановкой следующего. */ unsigned int spiSe2pFree(SPISE2P_DRV *se2p); /* Ставит задание записи в SPI-драйвер с учётом состояния занятости EEPROM. */ void spiSe2pWrite(SPISE2P_DRV *se2p, SE2P_DATA *data); /* Ставит задание чтения в SPI-драйвер с указателем буфера, длиной и физическим адресом. */ void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *data); /* Условие компиляции (SPISE2P_DATA_WIDTH==SIXTEEN_BIT): выбранный блок включается в текущий вариант прошивки. */ #if(SPISE2P_DATA_WIDTH==SIXTEEN_BIT) /* Задаёт PROM_LEN = BALSAM167_EEPROM_WORDS; данные PROM_LEN. */ #define PROM_LEN BALSAM167_EEPROM_WORDS /* Задаёт PAGE_LEN = (BALSAM167_EEPROM_PAGE_BYTES / 2); данные PAGE_LEN. */ #define PAGE_LEN (BALSAM167_EEPROM_PAGE_BYTES / 2) /* Задаёт WORD_LEN = 2; слово LEN. */ #define WORD_LEN 2 /* Выбирает альтернативный блок текущего условия компиляции. */ #else /* Задаёт PROM_LEN = BALSAM167_EEPROM_BYTES; данные PROM_LEN. */ #define PROM_LEN BALSAM167_EEPROM_BYTES /* Задаёт PAGE_LEN = BALSAM167_EEPROM_PAGE_BYTES; данные PAGE_LEN. */ #define PAGE_LEN BALSAM167_EEPROM_PAGE_BYTES /* Задаёт WORD_LEN = 1; слово LEN. */ #define WORD_LEN 1 /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Установка драйвера сериальной EEPROM. ** ** Инициализациа SPI и проч. Также настройка таймера. ** ** Драйвер работает на прерываниах от таймера 2! */ /* Объявляет интерфейс функции InitSeeprom; реализация вызывается через этот прототип. */ void InitSeeprom(void); /* Запись блока в SEEPROM. Параметры таковы: ** ** adres - адрес в епромке, куда писать. ** ** adres = 0..0x8000, если длина слова 8 бит ** ** adres = 0..0x4000, если длина слова 16 бит ** ** buf - указатель на памать, откуда писать. ** ** size - длина блока в байтах. По-любому в байтах! */ /* Пишет EEPROM с разделением по физическим страницам; область параметров не пересекает образ прошивки. */ void Seeprom_write(SE2P_SIZE adres, unsigned int buf[], SE2P_SIZE size); /* Чтение блока из SEEPROM. Параметры таковы: ** ** adres - адрес в епромке, откуда читать. ** ** adres = 0..0x8000, если длина слова 8 бит ** ** adres = 0..0x4000, если длина слова 16 бит ** ** buf - указатель на памать, куда читать. ** ** size - длина блока в байтах. По-любому в байтах! */ /* Читает EEPROM порциями; адрес задаётся словами C28x, размер переводится в число передаваемых слов. */ void Seeprom_read(SE2P_SIZE adres, unsigned int buf[], SE2P_SIZE size); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif