diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index 2540c60..0b7af04 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,7 +5,7 @@
-
+
@@ -16,7 +16,7 @@
-
+
diff --git a/Vinclude/V_i2cMem.h b/Vinclude/V_i2cMem.h
index e72bc7b..f63c12d 100644
--- a/Vinclude/V_i2cMem.h
+++ b/Vinclude/V_i2cMem.h
@@ -1,14 +1,31 @@
-/*
- * V_i2cMem.h
- *
- * Created on: 15 авг. 2019 г.
- * Author: Dmitry
- */
+/*!
+ Copyright 2019 АО "НИИЭТ" и ООО "НПФ ВЕКТОР"
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ \file v_i2cMem.h
+ \brief Драйвер для работы с микросхемой флеш памяти 24LC256 по
+ интерфейсу I2C
+ \author ООО "НПФ Вектор". http://motorcontrol.ru
+ \version v 1.0 10/08/2019
+
+ \addtogroup v_i2cMem
+@{
+*/
#ifndef INCLUDE_V_I2CMEM_H_
#define INCLUDE_V_I2CMEM_H_
-#define EEPROM_MEM_LENGTH 32768 //длина флешки в байтах (256 кбит)
+#define EEPROM_MEM_LENGTH 32768 // Размер памяти в байтах (256 кбит)
struct SI2cMem;
typedef volatile struct SI2cMem TI2cMem;
@@ -16,7 +33,7 @@ typedef volatile struct SI2cMem TI2cMem;
struct SI2cMem {
Uint16 MEMstartaddr; //! Адрес на flash
Uint16 data_length; //! Длина данных в байтах
- Uint16 *DSPstartaddr; //! Адрес на массив с данными
+ Uint16 *DSPstartaddr; //! Адрес на массив с данными в контроллере
Uint16 LastErr; //! Код ошибки (если возникла)
void (*init)(TI2cMem*);
void (*write)(TI2cMem*);
diff --git a/Vsrc/V_i2cMem.c b/Vsrc/V_i2cMem.c
index 2693d7f..f108954 100644
--- a/Vsrc/V_i2cMem.c
+++ b/Vsrc/V_i2cMem.c
@@ -1,10 +1,27 @@
-/*
- * V_i2cMem.c
- *
- * Created on: 15 авг. 2019 г.
- * Author: Dmitry
- */
+/*!
+ Copyright 2019 АО "НИИЭТ" и ООО "НПФ ВЕКТОР"
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ \file v_i2cMem.c
+ \brief Драйвер для работы с микросхемой флеш памяти 24LC256 по
+ интерфейсу I2C
+ \author ООО "НПФ Вектор". http://motorcontrol.ru
+ \version v 1.0 10/08/2019
+
+ \addtogroup v_i2cMem
+@{
+*/
#include "main.h"
#include "V_i2cmem.h"
@@ -15,11 +32,17 @@
TI2cMem i2cMem = I2CMEM_DEFAULTS;
-// Функция ожидания выполнения команды
+// Желаемая частота шины I2C в килогерцах
+#define I2CMEM_FREQUENCY_KHZ 400
+
+// Функция ожидания выполнения команды модулем I2C
+// Просто ждёт, пока модуль выйдет из состояния "IDLE"
Uint16 i2c_waitIdle() {
Uint32 idle = 0;
+
while ((I2C->ST & I2C_ST_MODE_Msk) == I2C_ST_MODE_IDLE){
idle++;
+ // Если ожидание слишком долгое - выдать ошибку
if (idle > 10000000)
return 1;
};
@@ -27,7 +50,9 @@ Uint16 i2c_waitIdle() {
return 0;
}
-// Функция ждёт, пока закончится внутренний цикл записи в памяти
+
+// Функция ждёт, пока закончится внутренний цикл записи в микросхеме памяти.
+// Пока цикл идёт, микросхема не квитирует отправленный ей байт с собственным адресом и командой "Write"
// Если должались, пока микросхема освободится, то на выходе из функции она будет в состоянии
// ожидания приёма внутреннего адреса (то есть её послан старт и адрес устройства с битом "Write")
Uint16 i2c_waitMemBusyAndSendAddWr () {
@@ -66,11 +91,13 @@ Uint16 i2c_waitMemBusyAndSendAddWr () {
}
} while ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTADPA);
+ // Дошли до сюда - всё хорошо
return I2C_MEM_ERROR_OK;
}
-
-// Инит/переинит записи массива, который надо вызывать при достижении границы страницы (64 байта)
+// Вспомогательная функция для блочной записи данных в памяти.
+// Осуществляет инит/переинит записи массива, который надо вызывать
+// при достижении границы страницы (64 байта) внутри памяти.
Uint16 i2c_initWriteArray (Uint16 address) {
Uint16 retVal;
// Ждём, пока память память закончин внутреннее сохранение
@@ -100,16 +127,16 @@ Uint16 i2c_initWriteArray (Uint16 address) {
return I2C_MEM_ERROR_OK;
}
-// Запись массива
+// Запись массива байт в память.
Uint16 i2c_writeArray(Uint16 address, Uint16 *dataPtr_u16, Uint16 length_u8) {
// Тут внутри проще работать с байтами
Uint8* dataPtr_u8 = (Uint8*)dataPtr_u16;
+ // Отправляем адрес, с котрого начнём запись
i2c_initWriteArray(address);
- // Поехали данные
+ // Отправляем данные
while (length_u8 > 0) {
- // Данные
I2C->SDA = *dataPtr_u8;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
@@ -118,11 +145,12 @@ Uint16 i2c_writeArray(Uint16 address, Uint16 *dataPtr_u16, Uint16 length_u8) {
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_WRITE_HW_ERR;
- // Смотрим, не дошли ли до конца страницы внутри памяти/
- // Если дошли - надо сделать стоп и подождать, пока данные пропишутся
length_u8--;
dataPtr_u8++;
address++;
+
+ // Смотрим, не дошли ли до конца страницы внутри памяти/
+ // Если дошли - надо отправить стоп и подождать, пока данные пропишутся
if ((address & 0x3F) == 0) {
// Формируем стоп и перезапускаем записывалку на новый адрес
I2C->CTL0 = I2C_CTL0_STOP_Msk;
@@ -144,7 +172,7 @@ Uint16 i2c_readArray(Uint16 address, Uint16* readDataPtr_u16, Uint16 length_u8){
Uint16 retVal;
- // Ждём, пока память память закончин внутреннее сохранение
+ // Ждём, пока память память закончит внутреннее сохранение
retVal = i2c_waitMemBusyAndSendAddWr();
if (retVal != I2C_MEM_ERROR_OK)
return retVal;
@@ -185,8 +213,8 @@ Uint16 i2c_readArray(Uint16 address, Uint16* readDataPtr_u16, Uint16 length_u8){
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRADPA)
return I2C_MEM_ERROR_READ_HW_ERR;
+ // До последнего байта принимаем и квитируем
while (length_u8 > 1) {
- // Принимаем байт, и квитируем
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
@@ -216,9 +244,8 @@ Uint16 i2c_readArray(Uint16 address, Uint16* readDataPtr_u16, Uint16 length_u8){
}
-// Желаемая частота шины I2C в килогерцах
-#define I2CMEM_FREQUENCY_KHZ 400
+// Инит модуля I2C и GPIO, к которым подключена память
void I2CMEM_Init(TI2cMem*p){
// Разрешаем работу 0 и 1 ножек порта А и переводим их в периферийный режим
GPIOA->DENSET |= 0x3;
@@ -230,23 +257,25 @@ void I2CMEM_Init(TI2cMem*p){
I2C->CTL1 |= (25000 / I2CMEM_FREQUENCY_KHZ) << I2C_CTL1_SCLFRQ_Pos;
}
+// Запись массива байтов
void I2CMEM_Write(TI2cMem*p){
- // Запись
p->LastErr = i2c_writeArray(p->MEMstartaddr, p->DSPstartaddr, p->data_length);
}
+// Чтение массива байтов
void I2CMEM_Read(TI2cMem*p){
- // Чтение
p->LastErr = i2c_readArray(p->MEMstartaddr, p->DSPstartaddr, p->data_length);
}
+// Полная очистка памяти
void I2CMEM_Clear(TI2cMem*p){
- // Стирание
Uint32 i = 0;
Uint16 ffArr[32];
for (i = 0; i < 32; i++) {
ffArr[i] = 0xFFFF;
}
+
+ // Забиваем каждую страницу 0xFF
for (i = 0; i < EEPROM_MEM_LENGTH; i += 0x40){
p->MEMstartaddr = i;
p->DSPstartaddr = ffArr;
@@ -257,109 +286,4 @@ void I2CMEM_Clear(TI2cMem*p){
return;
}
}
-
-/****** Депрекейтед, как говорится *******/
-//// Запись в память одного байта и "стоп"
-//Uint16 i2c_writeSingleByteAndStop(Uint16 address, Uint8 data)
-//{
-// Uint16 retVal;
-// // Ждём, пока память память закончин внутреннее сохранение
-// retVal = i2c_waitMemBusyAndSendAddWr();
-// if (retVal != I2C_MEM_ERROR_OK)
-// return retVal;
-//
-// // Страший байт адреса 0x0000____
-// I2C->SDA = (address >> 8) & 0xFF;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если не квитирован - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
-// return I2C_MEM_ERROR_WRITE_HW_ERR;
-//
-// // Младший байт адреса 0x____0000
-// I2C->SDA = (address >> 0) & 0xFF;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если не квитирован - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
-// return I2C_MEM_ERROR_WRITE_HW_ERR;
-//
-// // Данные
-// I2C->SDA = data;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если не квитирован - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
-// return I2C_MEM_ERROR_WRITE_HW_ERR;
-//
-// // Формируем стоп
-// I2C->CTL0 = I2C_CTL0_STOP_Msk;
-// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
-// return I2C_MEM_ERROR_OK;
-//}
-//
-//
-//// Чтение одного байта и стоп
-//Uint8 i2c_readSingleByteAndStop(Uint16 address, Uint16* readData)
-//{
-// Uint16 retVal;
-//
-// // Ждём, пока память память закончин внутреннее сохранение
-// retVal = i2c_waitMemBusyAndSendAddWr();
-// if (retVal != I2C_MEM_ERROR_OK)
-// return retVal;
-//
-// // Страший байт адреса 0x0000____
-// I2C->SDA = (address >> 8) & 0xFF;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если не квитирован - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
-// return I2C_MEM_ERROR_READ_HW_ERR;
-//
-// // Младший байт адреса 0x____0000
-// I2C->SDA = (address >> 0) & 0xFF;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если не квитирован - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
-// return I2C_MEM_ERROR_READ_HW_ERR;
-//
-// // Повторный старт, чтобы перейти в режим мастера-приёмника
-// I2C->CTL0 = I2C_CTL0_START_Msk;
-// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если режим неправильный - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_RSDONE)
-// return I2C_MEM_ERROR_READ_HW_ERR;
-//
-// // Адрес устройства + Read
-// I2C->SDA = 0b10100001;
-// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если передача адреса устройства не квитирована - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRADPA)
-// return I2C_MEM_ERROR_READ_HW_ERR;
-//
-// // Принимаем байт, но не квитируем
-// I2C->CTL0 = I2C_CTL0_ACK_Msk; // Reset + NACK
-// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
-// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
-//
-// // Если режим не стал правильным - ошибка
-// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRDANA)
-// return I2C_MEM_ERROR_READ_HW_ERR;
-//
-// *readData = I2C->SDA;
-// // Формируем стоп
-// I2C->CTL0 = I2C_CTL0_STOP_Msk | I2C_CTL0_CLRST_Msk;
-//
-// return I2C_MEM_ERROR_OK;
-//}
+/*@}*/