Skip to content

Commit

Permalink
Merge branch 'main'
Browse files Browse the repository at this point in the history
  • Loading branch information
RadioPizza committed Jan 25, 2025
1 parent e9a9da9 commit cb500a3
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 234 deletions.
66 changes: 33 additions & 33 deletions src/drivers/adxl345/adxl345.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,36 @@
*/

/* Определение адресов регистров */
#define ADXL345_REG_DEVID 0x00 /**< @brief Регистр идентификатора устройства */
#define ADXL345_REG_THRESH_TAP 0x1D /**< @brief Порог ударов */
#define ADXL345_REG_OFSX 0x1E /**< @brief Смещение по оси X */
#define ADXL345_REG_OFSY 0x1F /**< @brief Смещение по оси Y */
#define ADXL345_REG_OFSZ 0x20 /**< @brief Смещение по оси Z */
#define ADXL345_REG_DUR 0x21 /**< @brief Длительность удара */
#define ADXL345_REG_LATENT 0x22 /**< @brief Задержка между ударами */
#define ADXL345_REG_WINDOW 0x23 /**< @brief Окно между ударами */
#define ADXL345_REG_THRESH_ACT 0x24 /**< @brief Порог активности */
#define ADXL345_REG_THRESH_INACT 0x25 /**< @brief Порог неактивности */
#define ADXL345_REG_TIME_INACT 0x26 /**< @brief Время неактивности */
#define ADXL345_REG_ACT_INACT_CTL 0x27 /**< @brief Управление осями для детекции активности/неактивности */
#define ADXL345_REG_THRESH_FF 0x28 /**< @brief Порог свободного падения */
#define ADXL345_REG_TIME_FF 0x29 /**< @brief Время свободного падения */
#define ADXL345_REG_TAP_AXES 0x2A /**< @brief Управление осями для одиночного/двойного удара */
#define ADXL345_REG_DEVID 0x00 /**< @brief Регистр идентификатора устройства */
#define ADXL345_REG_THRESH_TAP 0x1D /**< @brief Порог ударов */
#define ADXL345_REG_OFSX 0x1E /**< @brief Смещение по оси X */
#define ADXL345_REG_OFSY 0x1F /**< @brief Смещение по оси Y */
#define ADXL345_REG_OFSZ 0x20 /**< @brief Смещение по оси Z */
#define ADXL345_REG_DUR 0x21 /**< @brief Длительность удара */
#define ADXL345_REG_LATENT 0x22 /**< @brief Задержка между ударами */
#define ADXL345_REG_WINDOW 0x23 /**< @brief Окно между ударами */
#define ADXL345_REG_THRESH_ACT 0x24 /**< @brief Порог активности */
#define ADXL345_REG_THRESH_INACT 0x25 /**< @brief Порог неактивности */
#define ADXL345_REG_TIME_INACT 0x26 /**< @brief Время неактивности */
#define ADXL345_REG_ACT_INACT_CTL 0x27 /**< @brief Управление осями для детекции активности/неактивности */
#define ADXL345_REG_THRESH_FF 0x28 /**< @brief Порог свободного падения */
#define ADXL345_REG_TIME_FF 0x29 /**< @brief Время свободного падения */
#define ADXL345_REG_TAP_AXES 0x2A /**< @brief Управление осями для одиночного/двойного удара */
#define ADXL345_REG_ACT_TAP_STATUS 0x2B /**< @brief Источник одиночного/двойного удара */
#define ADXL345_REG_BW_RATE 0x2C /**< @brief Частота данных и режим энергосбережения */
#define ADXL345_REG_POWER_CTL 0x2D /**< @brief Управление энергопотреблением */
#define ADXL345_REG_INT_ENABLE 0x2E /**< @brief Управление разрешением прерываний */
#define ADXL345_REG_INT_MAP 0x2F /**< @brief Управление назначением прерываний */
#define ADXL345_REG_INT_SOURCE 0x30 /**< @brief Источник прерываний */
#define ADXL345_REG_DATA_FORMAT 0x31 /**< @brief Управление форматом данных */
#define ADXL345_REG_DATAX0 0x32 /**< @brief Данные оси X младший байт */
#define ADXL345_REG_DATAX1 0x33 /**< @brief Данные оси X старший байт */
#define ADXL345_REG_DATAY0 0x34 /**< @brief Данные оси Y младший байт */
#define ADXL345_REG_DATAY1 0x35 /**< @brief Данные оси Y старший байт */
#define ADXL345_REG_DATAZ0 0x36 /**< @brief Данные оси Z младший байт */
#define ADXL345_REG_DATAZ1 0x37 /**< @brief Данные оси Z старший байт */
#define ADXL345_REG_FIFO_CTL 0x38 /**< @brief Управление FIFO */
#define ADXL345_REG_FIFO_STATUS 0x39 /**< @brief Состояние FIFO */
#define ADXL345_REG_BW_RATE 0x2C /**< @brief Частота данных и режим энергосбережения */
#define ADXL345_REG_POWER_CTL 0x2D /**< @brief Управление энергопотреблением */
#define ADXL345_REG_INT_ENABLE 0x2E /**< @brief Управление разрешением прерываний */
#define ADXL345_REG_INT_MAP 0x2F /**< @brief Управление назначением прерываний */
#define ADXL345_REG_INT_SOURCE 0x30 /**< @brief Источник прерываний */
#define ADXL345_REG_DATA_FORMAT 0x31 /**< @brief Управление форматом данных */
#define ADXL345_REG_DATAX0 0x32 /**< @brief Данные оси X младший байт */
#define ADXL345_REG_DATAX1 0x33 /**< @brief Данные оси X старший байт */
#define ADXL345_REG_DATAY0 0x34 /**< @brief Данные оси Y младший байт */
#define ADXL345_REG_DATAY1 0x35 /**< @brief Данные оси Y старший байт */
#define ADXL345_REG_DATAZ0 0x36 /**< @brief Данные оси Z младший байт */
#define ADXL345_REG_DATAZ1 0x37 /**< @brief Данные оси Z старший байт */
#define ADXL345_REG_FIFO_CTL 0x38 /**< @brief Управление FIFO */
#define ADXL345_REG_FIFO_STATUS 0x39 /**< @brief Состояние FIFO */

/** @} */ // end of ADXL345_REGISTERS

Expand All @@ -57,7 +57,7 @@
*/

/* Определение констант */
#define ADXL345_DEVICE_ID 0xE5 /**< @brief Ожидаемый идентификатор устройства */
#define ADXL345_DEVICE_ID 0xE5 /**< @brief Ожидаемый идентификатор устройства */

/** @} */ // end of ADXL345_CONSTANTS

Expand All @@ -82,11 +82,11 @@
* @return uint8_t Статус инициализации
* @retval 0 Успешная инициализация ADXL345
* @retval 1 Ошибка инициализации (неверный идентификатор устройства)
*
*
* @sa ADXL345_ReadReg
* @sa ADXL345_WriteReg
* @sa ADXL345_ReadAccel
*
*
* @code
* // Пример использования:
* uint8_t result = ADXL345_Init();
Expand All @@ -98,7 +98,7 @@
* // Обработка ошибки
* }
* @endcode
*
*
* @note Перед вызовом функции должен быть инициализирован интерфейс SPI
* @warning Функция не проверяет корректность инициализации SPI
*/
Expand Down
45 changes: 26 additions & 19 deletions src/drivers/i2c/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ uint8_t I2C_Init(I2C_Mode_t mode)
I2C_FREQR = 16; // Частота тактирования 16 МГц

/* Настраиваем параметры в зависимости от режима */
if (mode == I2C_STANDARD_MODE) {
if (mode == I2C_STANDARD_MODE)
{
/* Стандартный режим (100 кГц) */
CCRL_Value = 0x50;
CCRH_Value = 0x00;
TRISER_Value = 17;
}
else { /* I2C_FAST_MODE */
else
{ /* I2C_FAST_MODE */
/* Быстрый режим (400 кГц) */
CCR = 13; // Вычислено ранее
CCRL_Value = (uint8_t)(CCR & 0xFF); // Младшие 8 бит CCR
CCR = 13; // Вычислено ранее
CCRL_Value = (uint8_t)(CCR & 0xFF); // Младшие 8 бит CCR
CCRH_Value = (uint8_t)((CCR >> 8) & 0x0F) | I2C_CCRH_FS; // Старшие биты CCR + бит FS (Fast Mode)
TRISER_Value = 6;
}
Expand All @@ -53,45 +55,50 @@ uint8_t I2C_Init(I2C_Mode_t mode)

/* Включаем периферию I2C */
I2C_CR1 |= I2C_CR1_PE; // Устанавливаем бит PE для включения I2C

/* Проверяем успешность инициализации */
return (I2C_CR1 & I2C_CR1_PE) ? 0 : 1;
}

void I2C_Start(void)
{
I2C_CR2 |= I2C_CR2_START; // Генерируем условие START
while (!(I2C_SR1 & I2C_SR1_SB)); // Ждем установки флага SB (Start Bit)
I2C_CR2 |= I2C_CR2_START; // Генерируем условие START
while (!(I2C_SR1 & I2C_SR1_SB))
; // Ждем установки флага SB (Start Bit)
}

void I2C_Stop(void)
{
I2C_CR2 |= I2C_CR2_STOP; // Генерируем условие STOP
I2C_CR2 |= I2C_CR2_STOP; // Генерируем условие STOP
}

void I2C_WriteAddress(uint8_t address)
{
I2C_DR = address; // Отправляем адрес
while (!(I2C_SR1 & I2C_SR1_ADDR)); // Ждем установки флага ADDR
(void)I2C_SR3; // Читаем SR3 для сброса флага ADDR
I2C_DR = address; // Отправляем адрес
while (!(I2C_SR1 & I2C_SR1_ADDR))
; // Ждем установки флага ADDR
(void)I2C_SR3; // Читаем SR3 для сброса флага ADDR
}

void I2C_WriteData(uint8_t data)
{
I2C_DR = data; // Отправляем данные
while (!(I2C_SR1 & I2C_SR1_TXE)); // Ждем, пока TXE (регистр данных пуст)
I2C_DR = data; // Отправляем данные
while (!(I2C_SR1 & I2C_SR1_TXE))
; // Ждем, пока TXE (регистр данных пуст)
}

uint8_t I2C_ReadData_ACK(void)
{
I2C_CR2 |= I2C_CR2_ACK; // Устанавливаем бит ACK
while (!(I2C_SR1 & I2C_SR1_RXNE)); // Ждем установки флага RXNE
return I2C_DR; // Возвращаем полученные данные
I2C_CR2 |= I2C_CR2_ACK; // Устанавливаем бит ACK
while (!(I2C_SR1 & I2C_SR1_RXNE))
; // Ждем установки флага RXNE
return I2C_DR; // Возвращаем полученные данные
}

uint8_t I2C_ReadData_NACK(void)
{
I2C_CR2 &= ~I2C_CR2_ACK; // Сбрасываем бит ACK
while (!(I2C_SR1 & I2C_SR1_RXNE)); // Ждем установки флага RXNE
return I2C_DR; // Возвращаем полученные данные
I2C_CR2 &= ~I2C_CR2_ACK; // Сбрасываем бит ACK
while (!(I2C_SR1 & I2C_SR1_RXNE))
; // Ждем установки флага RXNE
return I2C_DR; // Возвращаем полученные данные
}
4 changes: 2 additions & 2 deletions src/drivers/i2c/i2c.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file i2c.h
* @brief Библиотека-драйвер для работы с аппартаным интерфейсом I2C
*
*
* Этот файл содержит прототипы функций и необходимые определения для работы с SPI.
*/

Expand Down Expand Up @@ -86,7 +86,7 @@ typedef enum

/**
* @brief Инициализация интерфейса I2C
*
*
* @details Выполняет настройку периферийного модуля I2C для работы в одном из двух режимов:
* - Стандартный режим (Standard Mode) с частотой 100 кГц
* - Быстрый режим (Fast Mode) с частотой 400 кГц
Expand Down
102 changes: 102 additions & 0 deletions src/drivers/m24512/m24512.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* @file m24512.c
* @brief Реализация функций для работы с EEPROM M24512
*/

#include "m24512.h"
#include "i2c.h"
#include "delay.h"

/** @brief Время ожидания завершения записи в мс */
#define M24512_WRITE_TIMEOUT 5

/**
* @brief Проверка занятости устройства
*
* @return Результат проверки
* @retval 0 Устройство готово к работе
* @retval 1 Устройство занято
*/
static uint8_t M24512_IsBusy(void)
{
I2C_Start();
I2C_WriteAddress(M24512_BASE_ADDR, w);
I2C_Stop();
return 0;
}

/**
* @brief Ожидание готовности устройства
*
* @return Результат ожидания
* @retval 0 Устройство готово к работе
* @retval 1 Таймаут ожидания готовности
*/
static uint8_t M24512_WaitReady(void)
{
uint8_t timeout = 100; /* Максимальное время ожидания ~500 мс */

while (M24512_IsBusy() && timeout)
{
delay(5);
timeout--;
}

return (timeout == 0);
}

uint8_t M24512_Init(void)
{
I2C_Start();
I2C_WriteAddress_for_EEPROM(M24512_BASE_ADDR, w);
return 0;
}

uint8_t M24512_WriteByte(uint16_t addr, uint8_t data)
{
if (addr > M24512_MAX_ADDR)
{
return 1;
}

if (M24512_WaitReady())
{
return 1;
}

I2C_Start();
I2C_WriteAddress_for_EEPROM(M24512_BASE_ADDR, w);
I2C_WriteData((uint8_t)(addr >> 8));
I2C_WriteData((uint8_t)(addr & 0xFF));
I2C_WriteData(data);
I2C_Stop();

delay(M24512_WRITE_TIMEOUT);

return 0;
}

uint8_t M24512_ReadByte(uint16_t addr, uint8_t *data)
{
if (addr > M24512_MAX_ADDR || data == 0)
{
return 1;
}

if (M24512_WaitReady())
{
return 1;
}

I2C_Start();
I2C_WriteAddress(M24512_BASE_ADDR);
I2C_WriteData((uint8_t)(addr >> 8));
I2C_WriteData((uint8_t)(addr & 0xFF));

I2C_Start();
I2C_WriteAddress(M24512_BASE_ADDR | 0x01);
*data = I2C_ReadData_NACK();
I2C_Stop();

return 0;
}
84 changes: 84 additions & 0 deletions src/drivers/m24512/m24512.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* @file m24512.h
* @brief Библиотека-драйвер для работы с EEPROM M24512
*
* Этот файл содержит прототипы функций и необходимые определения
* для работы с микросхемой энергонезависимой памяти M24512 по интерфейсу I2C.
*
* Основные характеристики M24512:
* - Объем памяти: 512 Кбит (64 КБайт)
* - Организация: 65536 x 8 бит
* - Интерфейс: I2C (до 400 кГц)
* - Напряжение питания: 2.5В - 5.5В
* - Время записи страницы: 5 мс макс.
*/

#ifndef M24512_H
#define M24512_H

#include <stdint.h>

/** @defgroup M24512_Constants Константы для работы с M24512
* @{
*/

/** @brief Базовый адрес устройства M24512 на шине I2C */
#define M24512_BASE_ADDR 0xA0

/** @brief Максимальный адрес памяти */
#define M24512_MAX_ADDR 0xFFFF

/** @brief Размер страницы памяти в байтах */
#define M24512_PAGE_SIZE 128

/** @} */

/** @defgroup M24512_Functions Функции для работы с M24512
* @{
*/

/**
* @brief Инициализация M24512
*
* Выполняет проверку наличия и доступности микросхемы памяти на шине I2C.
* Необходимо вызвать перед началом работы с микросхемой.
*
* @return Результат инициализации
* @retval 0 Инициализация выполнена успешно, устройство отвечает
* @retval 1 Ошибка инициализации, устройство не отвечает
*/
uint8_t M24512_Init(void);

/**
* @brief Запись байта данных по указанному адресу
*
* Записывает один байт данных по указанному адресу памяти.
* После записи автоматически выполняется ожидание завершения
* внутреннего цикла записи микросхемы.
*
* @param[in] addr Адрес для записи (0x0000 - 0xFFFF)
* @param[in] data Байт данных для записи
*
* @return Результат операции записи
* @retval 0 Запись выполнена успешно
* @retval 1 Ошибка записи или некорректный адрес
*/
uint8_t M24512_WriteByte(uint16_t addr, uint8_t data);

/**
* @brief Чтение байта данных с указанного адреса
*
* Читает один байт данных с указанного адреса памяти.
*
* @param[in] addr Адрес для чтения (0x0000 - 0xFFFF)
* @param[out] data Указатель на переменную для сохранения прочитанного байта
*
* @return Результат операции чтения
* @retval 0 Чтение выполнено успешно
* @retval 1 Ошибка чтения, некорректный адрес или NULL указатель
*/
uint8_t M24512_ReadByte(uint16_t addr, uint8_t *data);

/** @} */

#endif /* M24512_H */
Loading

0 comments on commit cb500a3

Please sign in to comment.