Compare commits
5 Commits
8b930ebe12
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03d26cef1 | ||
| 12922152bb | |||
| 16f46c87c4 | |||
|
|
c82bbdc1ca | ||
|
|
c63d98f431 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -46,4 +46,4 @@ JLinkSettings.ini
|
||||
|
||||
# Other Files
|
||||
|
||||
/Objects/
|
||||
MDK-ARM/Objects/
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,4 +1,4 @@
|
||||
[submodule "Core/ExtendedLibs"]
|
||||
path = Core/ExtendedLibs
|
||||
[submodule "MDK-ARM/Core/ExtendedLibs"]
|
||||
path = MDK-ARM/Core/ExtendedLibs
|
||||
url = https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs.git
|
||||
branch = release
|
||||
branch = develop
|
||||
|
||||
Submodule Core/ExtendedLibs deleted from 457ec2a729
971
MDK-ARM/Core/App/i2c.c
Normal file
971
MDK-ARM/Core/App/i2c.c
Normal file
@@ -0,0 +1,971 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.c
|
||||
* @author Разваляев Алексей
|
||||
* @brief Драйвер I2C на основе PLIB035.
|
||||
* Этот файл содержит:
|
||||
* + Инициализацию I2C
|
||||
* + Функции для работы в режиме мастера (блокирующие):
|
||||
* - Блокирующая передача/прием
|
||||
* - Функции чтения/записи регистров устройств
|
||||
* - Проверка наличия устройства
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Использование этого драйвера предполагает наличие корректных настроек:
|
||||
* - Определена конфигурационная структура i2c_config в periph_config.h
|
||||
* - Определены пины SDA/SCL для I2C
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
==============================================================================
|
||||
##### Как использовать этот драйвер #####
|
||||
==============================================================================
|
||||
|
||||
1. Настройка в periph_config.h:
|
||||
(+) Определите i2c_config для I2C
|
||||
(+) Настройте частоту SCL (FSFreq для стандартного режима, HSFreq для высокоскоростного)
|
||||
(+) Используйте enum для настройки:
|
||||
• I2C_Mode_Master - режим мастера
|
||||
• I2C_Mode_Slave - режим ведомого
|
||||
|
||||
2. Инициализация:
|
||||
(+) i2c_init_first() - настройка GPIO, тактирования
|
||||
(+) i2c_init(&hi2c, &config) - инициализация I2C
|
||||
|
||||
3. Запуск I2C:
|
||||
(+) I2C_Start(&hi2c) - включение I2C
|
||||
|
||||
4. Работа в режиме мастера (блокирующие функции):
|
||||
- Основные функции:
|
||||
(+) I2C_Master_Transmit(&hi2c, addr, buf, size, timeout) - передача данных
|
||||
(+) I2C_Master_Receive(&hi2c, addr, buf, size, timeout) - прием данных
|
||||
(+) I2C_Master_WriteReg(&hi2c, addr, reg, val, timeout) - запись регистра
|
||||
(+) I2C_Master_ReadReg(&hi2c, addr, reg, buf, size, timeout) - чтение регистра
|
||||
(+) I2C_Master_WriteRegs(&hi2c, addr, reg, buf, size, timeout) - запись нескольких регистров
|
||||
(+) I2C_Master_ReadRegs(&hi2c, addr, reg, buf, size, timeout) - чтение нескольких регистров
|
||||
(+) I2C_Master_IsDeviceReady(&hi2c, addr, timeout) - проверка наличия устройства
|
||||
|
||||
5. Обработка ошибок:
|
||||
(+) I2C_GetLastError(&hi2c) - получение кода последней ошибки
|
||||
(+) Callback-функция ошибки вызывается автоматически при ошибках
|
||||
|
||||
6. GPIO для I2C:
|
||||
(+) Пины настраиваются автоматически при вызове i2c_init_first()
|
||||
(+) При необходимости можно вызвать i2c_gpio_deinit() для восстановления
|
||||
|
||||
==============================================================================
|
||||
##### Особенности работы #####
|
||||
==============================================================================
|
||||
|
||||
- Режимы работы:
|
||||
- Master: инициирует передачу данных, управляет шиной
|
||||
- Slave: реагирует на запросы мастера
|
||||
|
||||
- Скорости работы:
|
||||
- Standard Mode (до 100 кГц)
|
||||
- Fast Mode (до 400 кГц)
|
||||
- Fast Mode Plus (до 1 МГц)
|
||||
- High Speed Mode (до 3.4 МГц)
|
||||
|
||||
- Адресация:
|
||||
- 7-битная адресация (стандартная)
|
||||
- 10-битная адресация (поддерживается)
|
||||
|
||||
- Обработка ошибок:
|
||||
- Обрабатываются ошибки шины, арбитража, таймаута
|
||||
- При ошибке вызывается ErrCallback и сохраняется код ошибки
|
||||
- После ошибки требуется переинициализация I2C
|
||||
|
||||
- Функции работы с регистрами:
|
||||
- Упрощают чтение/запись регистров устройств на шине I2C
|
||||
- Поддерживают различные размеры регистров (8/16 бит)
|
||||
|
||||
- Проверка устройства:
|
||||
- Функция проверяет ответ устройства на свой адрес
|
||||
- Полезна для проверки подключения устройств
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//-- Includes ------------------------------------------------------------------
|
||||
#include "periph_config.h"
|
||||
|
||||
I2C_HandleTypeDef hi2c; /*!< Хендл I2C */
|
||||
|
||||
//-- Private function prototypes -----------------------------------------------
|
||||
static OperationStatus __i2c_master_wait_bus_free(I2C_HandleTypeDef *hi2c, uint32_t timeout);
|
||||
static OperationStatus __i2c_master_send_start(I2C_HandleTypeDef *hi2c, uint32_t timeout);
|
||||
static OperationStatus __i2c_master_send_address(I2C_HandleTypeDef *hi2c, uint16_t addr, uint8_t direction, uint32_t timeout);
|
||||
static OperationStatus __i2c_master_send_stop(I2C_HandleTypeDef *hi2c, uint32_t timeout);
|
||||
static OperationStatus __i2c_master_transmit_blocking(I2C_HandleTypeDef *hi2c, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
static OperationStatus __i2c_master_receive_blocking(I2C_HandleTypeDef *hi2c, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
static void __i2c_set_error(I2C_HandleTypeDef *hi2c, uint8_t error);
|
||||
|
||||
//-- I2C Init functions -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Первичная инициализация I2C
|
||||
* @details Настройка I2C и хендла: GPIO, тактирование
|
||||
*/
|
||||
void i2c_init_first(void)
|
||||
{
|
||||
#if (USE_I2C==1)
|
||||
// Настройка пинов для I2C
|
||||
i2c_gpio_init();
|
||||
|
||||
// Включение тактирования и сброс I2C
|
||||
RCU_APBClkCmd(RCU_APBClk_I2C, ENABLE);
|
||||
RCU_APBRstCmd(RCU_APBRst_I2C, ENABLE);
|
||||
|
||||
// Инициализируем I2C
|
||||
hi2c.Instance = I2C;
|
||||
hi2c.LastError = I2C_ERROR_NONE;
|
||||
i2c_init(&hi2c, &i2c_config);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Инициализация I2C
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param NewConfig указатель на новую конфигурацию I2C, иначе используется та, что в структуре
|
||||
* @retval OperationStatus OK - если всё хорошо, ERROR - если ошибка
|
||||
*/
|
||||
OperationStatus i2c_init(I2C_HandleTypeDef *hi2c, I2C_ExtInit_TypeDef *NewConfig)
|
||||
{
|
||||
if(!hi2c || !hi2c->Instance)
|
||||
return ERROR;
|
||||
|
||||
if(NewConfig != NULL)
|
||||
{
|
||||
hi2c->Config = NewConfig;
|
||||
}
|
||||
if(hi2c->Config == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// Сбрасываем ошибку
|
||||
hi2c->LastError = I2C_ERROR_NONE;
|
||||
|
||||
// Настраиваем частоту SCL
|
||||
if(hi2c->Config->I2C_Init.HSMode == ENABLE)
|
||||
{
|
||||
// Высокоскоростной режим
|
||||
I2C_HSFreqConfig(hi2c->Config->HSFreq, hi2c->Config->I2CFreq);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Стандартный/быстрый режим
|
||||
I2C_FSFreqConfig(hi2c->Config->FSFreq, hi2c->Config->I2CFreq);
|
||||
}
|
||||
|
||||
// Настраиваем таймаут
|
||||
if(hi2c->Config->I2C_Init.Timeout != DISABLE)
|
||||
{
|
||||
I2C_TimeoutClkDivConfig(hi2c->Config->I2C_Init.TimeoutClkDiv);
|
||||
I2C_SetTimeoutCounterLoad(hi2c->Config->I2C_Init.TimeoutLoad);
|
||||
}
|
||||
|
||||
// Настраиваем дополнительные функции
|
||||
I2C_AlertResponseMatchCmd(hi2c->Config->I2C_Init.AlertResponse);
|
||||
I2C_GlobalCallMatchCmd(hi2c->Config->I2C_Init.GlobalCall);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Установка коллбека I2C
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param CallbackType Тип коллбека
|
||||
* @param Callback Функция коллбека
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке
|
||||
*/
|
||||
OperationStatus I2C_Set_Callback(I2C_HandleTypeDef* hi2c, I2C_CallbackTypeDef CallbackType, void (*Callback)())
|
||||
{
|
||||
if (!hi2c || !hi2c->Instance || !hi2c->Config)
|
||||
return ERROR;
|
||||
|
||||
switch(CallbackType)
|
||||
{
|
||||
case I2C_Callback_Tx:
|
||||
hi2c->Config->TxCallback = Callback;
|
||||
break;
|
||||
case I2C_Callback_Rx:
|
||||
hi2c->Config->RxCallback = Callback;
|
||||
break;
|
||||
case I2C_Callback_Addr:
|
||||
hi2c->Config->AddrCallback = Callback;
|
||||
break;
|
||||
case I2C_Callback_Error:
|
||||
hi2c->Config->ErrCallback = Callback;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
//-- I2C API functions --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Запуск I2C
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке
|
||||
*/
|
||||
OperationStatus I2C_Start(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
if (!hi2c)
|
||||
return ERROR;
|
||||
|
||||
// Сбрасываем ошибку
|
||||
hi2c->LastError = I2C_ERROR_NONE;
|
||||
|
||||
// Включаем I2C
|
||||
I2C_Cmd(ENABLE);
|
||||
|
||||
// Если режим ведомого, настраиваем адрес и включаем распознавание
|
||||
if(hi2c->Config->I2C_Init.Mode == I2C_Mode_Slave)
|
||||
{
|
||||
if(hi2c->Config->I2C_Init.Addr10Bit == ENABLE)
|
||||
{
|
||||
I2C_Slave10AddrCmd(ENABLE);
|
||||
I2C_SetSlave10Addr(hi2c->Config->I2C_Init.SlaveAddr >> 8);
|
||||
I2C_SetSlaveAddr(hi2c->Config->I2C_Init.SlaveAddr & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_Slave10AddrCmd(DISABLE);
|
||||
I2C_SetSlaveAddr(hi2c->Config->I2C_Init.SlaveAddr);
|
||||
}
|
||||
I2C_SlaveCmd(ENABLE);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Остановка I2C
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке
|
||||
*/
|
||||
OperationStatus I2C_Stop(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
if (!hi2c)
|
||||
return ERROR;
|
||||
|
||||
// Выключаем I2C
|
||||
I2C_Cmd(DISABLE);
|
||||
|
||||
// Если режим ведомого, выключаем распознавание адреса
|
||||
if(hi2c->Config->I2C_Init.Mode == I2C_Mode_Slave)
|
||||
{
|
||||
I2C_SlaveCmd(DISABLE);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получение кода последней ошибки
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @retval Код последней ошибки I2C
|
||||
*/
|
||||
uint8_t I2C_GetLastError(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
if (!hi2c)
|
||||
return I2C_ERROR_NONE;
|
||||
|
||||
return hi2c->LastError;
|
||||
}
|
||||
|
||||
//-- I2C Master functions -----------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Передача данных в режиме мастера (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param buf указатель на буфер данных
|
||||
* @param size размер данных в байтах
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_Transmit(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint8_t *buf,
|
||||
uint16_t size,
|
||||
uint32_t timeout)
|
||||
{
|
||||
OperationStatus status;
|
||||
|
||||
if (!hi2c || !buf || size == 0)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_NONE);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// Проверяем, свободна ли шина
|
||||
status = __i2c_master_wait_bus_free(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем START
|
||||
status = __i2c_master_send_start(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем адрес с направлением "запись"
|
||||
status = __i2c_master_send_address(hi2c, addr, I2C_Direction_Transmitter, timeout);
|
||||
if (status != OK)
|
||||
{
|
||||
// При NACK отправляем STOP и выходим
|
||||
if (hi2c->LastError == I2C_ERROR_NACK)
|
||||
{
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// Передаем данные
|
||||
status = __i2c_master_transmit_blocking(hi2c, buf, size, timeout);
|
||||
|
||||
// Отправляем STOP (даже при ошибке в данных)
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
|
||||
// Если была ошибка передачи данных, возвращаем ошибку
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Вызываем callback успешной передачи
|
||||
if (hi2c->Config->TxCallback)
|
||||
hi2c->Config->TxCallback();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Прием данных в режиме мастера (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param buf указатель на буфер приема
|
||||
* @param size количество принимаемых байт
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_Receive(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint8_t *buf,
|
||||
uint16_t size,
|
||||
uint32_t timeout)
|
||||
{
|
||||
OperationStatus status;
|
||||
|
||||
if (!hi2c || !buf || size == 0)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_NONE);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// Проверяем, свободна ли шина
|
||||
status = __i2c_master_wait_bus_free(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем START
|
||||
status = __i2c_master_send_start(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем адрес с направлением "чтение"
|
||||
status = __i2c_master_send_address(hi2c, addr, I2C_Direction_Receiver, timeout);
|
||||
if (status != OK)
|
||||
{
|
||||
// При NACK отправляем STOP и выходим
|
||||
if (hi2c->LastError == I2C_ERROR_NACK)
|
||||
{
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// Принимаем данные
|
||||
status = __i2c_master_receive_blocking(hi2c, buf, size, timeout);
|
||||
|
||||
// Отправляем STOP (даже при ошибке приема)
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
|
||||
// Если была ошибка приема данных, возвращаем ошибку
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Вызываем callback успешного приема
|
||||
if (hi2c->Config->RxCallback)
|
||||
hi2c->Config->RxCallback();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запись регистра устройства (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param reg адрес регистра
|
||||
* @param value значение для записи
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_WriteReg(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint16_t reg,
|
||||
uint8_t value,
|
||||
uint32_t timeout)
|
||||
{
|
||||
uint8_t data[3];
|
||||
uint16_t reg_size = (hi2c->Config->I2C_Init.RegSize == I2C_RegSize_8bit) ? 1 : 2;
|
||||
|
||||
if (reg_size == 1)
|
||||
{
|
||||
data[0] = (uint8_t)reg;
|
||||
data[1] = value;
|
||||
return I2C_Master_Transmit(hi2c, addr, data, 2, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = (uint8_t)(reg >> 8);
|
||||
data[1] = (uint8_t)reg;
|
||||
data[2] = value;
|
||||
return I2C_Master_Transmit(hi2c, addr, data, 3, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Чтение регистра устройства (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param reg адрес регистра
|
||||
* @param buf указатель на буфер для данных
|
||||
* @param size размер данных для чтения
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_ReadReg(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint16_t reg,
|
||||
uint8_t *buf,
|
||||
uint16_t size,
|
||||
uint32_t timeout)
|
||||
{
|
||||
OperationStatus status;
|
||||
uint8_t reg_data[2];
|
||||
uint16_t reg_size = (hi2c->Config->I2C_Init.RegSize == I2C_RegSize_8bit) ? 1 : 2;
|
||||
|
||||
// Сначала отправляем адрес регистра
|
||||
if (reg_size == 1)
|
||||
{
|
||||
reg_data[0] = (uint8_t)reg;
|
||||
status = I2C_Master_Transmit(hi2c, addr, reg_data, 1, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_data[0] = (uint8_t)(reg >> 8);
|
||||
reg_data[1] = (uint8_t)reg;
|
||||
status = I2C_Master_Transmit(hi2c, addr, reg_data, 2, timeout);
|
||||
}
|
||||
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Затем читаем данные
|
||||
return I2C_Master_Receive(hi2c, addr, buf, size, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Запись нескольких регистров (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param reg начальный адрес регистра
|
||||
* @param buf указатель на буфер данных
|
||||
* @param size количество регистров для записи
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_WriteRegs(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint16_t reg,
|
||||
uint8_t *buf,
|
||||
uint16_t size,
|
||||
uint32_t timeout)
|
||||
{
|
||||
OperationStatus status;
|
||||
uint16_t reg_size = (hi2c->Config->I2C_Init.RegSize == I2C_RegSize_8bit) ? 1 : 2;
|
||||
|
||||
// Проверяем, свободна ли шина
|
||||
status = __i2c_master_wait_bus_free(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем START
|
||||
status = __i2c_master_send_start(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем адрес с направлением "запись"
|
||||
status = __i2c_master_send_address(hi2c, addr, I2C_Direction_Transmitter, timeout);
|
||||
if (status != OK)
|
||||
{
|
||||
// При NACK отправляем STOP и выходим
|
||||
if (hi2c->LastError == I2C_ERROR_NACK)
|
||||
{
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// Отправляем адрес регистра (первый байт)
|
||||
if (reg_size == 1)
|
||||
{
|
||||
status = __i2c_master_transmit_blocking(hi2c, (uint8_t*)®, 1, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Для 16-битного адреса отправляем старший, затем младший байт
|
||||
uint8_t reg_bytes[2] = {(uint8_t)(reg >> 8), (uint8_t)reg};
|
||||
status = __i2c_master_transmit_blocking(hi2c, reg_bytes, 2, timeout);
|
||||
}
|
||||
|
||||
if (status != OK)
|
||||
{
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Отправляем данные
|
||||
status = __i2c_master_transmit_blocking(hi2c, buf, size, timeout);
|
||||
|
||||
// Отправляем STOP
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
|
||||
// Если была ошибка передачи данных, возвращаем ошибку
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Вызываем callback успешной передачи
|
||||
if (hi2c->Config->TxCallback)
|
||||
hi2c->Config->TxCallback();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Чтение нескольких регистров (блокирующий режим)
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param reg начальный адрес регистра
|
||||
* @param buf указатель на буфер для данных
|
||||
* @param size количество регистров для чтения
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если успешно, ERROR - при ошибке или таймауте
|
||||
*/
|
||||
OperationStatus I2C_Master_ReadRegs(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint16_t reg,
|
||||
uint8_t *buf,
|
||||
uint16_t size,
|
||||
uint32_t timeout)
|
||||
{
|
||||
// Для чтения нескольких регистров используется та же функция, что и для одного
|
||||
// т.к. после отправки адреса регистра можно читать любое количество байт
|
||||
return I2C_Master_ReadReg(hi2c, addr, reg, buf, size, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Проверка наличия устройства на шине
|
||||
* @param hi2c указатель на хендл I2C
|
||||
* @param addr адрес устройства на шине I2C
|
||||
* @param timeout таймаут ожидания (мс)
|
||||
* @retval OperationStatus OK - если устройство отвечает, ERROR - если нет ответа
|
||||
*/
|
||||
OperationStatus I2C_Master_IsDeviceReady(I2C_HandleTypeDef *hi2c,
|
||||
uint16_t addr,
|
||||
uint32_t timeout)
|
||||
{
|
||||
OperationStatus status;
|
||||
|
||||
if (!hi2c)
|
||||
return ERROR;
|
||||
|
||||
// Проверяем, свободна ли шина
|
||||
status = __i2c_master_wait_bus_free(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем START
|
||||
status = __i2c_master_send_start(hi2c, timeout);
|
||||
if (status != OK)
|
||||
return status;
|
||||
|
||||
// Отправляем адрес с направлением "запись" (любое направление подойдет для проверки)
|
||||
status = __i2c_master_send_address(hi2c, addr, I2C_Direction_Transmitter, timeout);
|
||||
|
||||
// Отправляем STOP независимо от результата
|
||||
__i2c_master_send_stop(hi2c, timeout);
|
||||
|
||||
// Если устройство ответило ACK, значит оно готово
|
||||
if (status == OK && hi2c->LastError == I2C_ERROR_NONE)
|
||||
return OK;
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
//-- I2C GPIO functions -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Инициализация GPIO для I2C
|
||||
*/
|
||||
void i2c_gpio_init(void)
|
||||
{
|
||||
#if USE_I2C==1
|
||||
// Получаем структуры
|
||||
GPIO_Init_TypeDef *sda_config = gpio_get_init(I2C_GPIO_Port, I2C_SDA_Pin);
|
||||
GPIO_Init_TypeDef *scl_config = gpio_get_init(I2C_GPIO_Port, I2C_SCL_Pin);
|
||||
|
||||
// SDA пин
|
||||
if (sda_config != NULL)
|
||||
{
|
||||
GPIO_StructInit(sda_config);
|
||||
sda_config->Pin = I2C_SDA_Pin;
|
||||
sda_config->AltFunc = ENABLE;
|
||||
sda_config->Digital = ENABLE;
|
||||
sda_config->OutMode = GPIO_OutMode_OD; // Открытый сток для I2C
|
||||
sda_config->PullMode = GPIO_PullMode_PU; // Подтяжка к питанию для I2C
|
||||
GPIO_Init(I2C_GPIO_Port, sda_config);
|
||||
}
|
||||
|
||||
// SCL пин
|
||||
if (scl_config != NULL)
|
||||
{
|
||||
GPIO_StructInit(scl_config);
|
||||
scl_config->Pin = I2C_SCL_Pin;
|
||||
scl_config->AltFunc = ENABLE;
|
||||
scl_config->Digital = ENABLE;
|
||||
scl_config->OutMode = GPIO_OutMode_OD; // Открытый сток для I2C
|
||||
scl_config->PullMode = GPIO_PullMode_PU; // Подтяжка к питанию для I2C
|
||||
GPIO_Init(I2C_GPIO_Port, scl_config);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Деинициализация GPIO для I2C
|
||||
*/
|
||||
void i2c_gpio_deinit(void)
|
||||
{
|
||||
#if USE_I2C==1
|
||||
// Получаем структуры
|
||||
GPIO_Init_TypeDef *sda_config = gpio_get_init(I2C_GPIO_Port, I2C_SDA_Pin);
|
||||
GPIO_Init_TypeDef *scl_config = gpio_get_init(I2C_GPIO_Port, I2C_SCL_Pin);
|
||||
|
||||
// Восстанавливаем оригинальные настройки из таблицы
|
||||
if (sda_config != NULL)
|
||||
{
|
||||
GPIO_StructInit(sda_config);
|
||||
sda_config->Pin = I2C_SDA_Pin;
|
||||
GPIO_Init(I2C_GPIO_Port, sda_config);
|
||||
}
|
||||
|
||||
if (scl_config != NULL)
|
||||
{
|
||||
GPIO_StructInit(scl_config);
|
||||
scl_config->Pin = I2C_SCL_Pin;
|
||||
GPIO_Init(I2C_GPIO_Port, scl_config);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-- I2C private functions ----------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Установка ошибки I2C
|
||||
*/
|
||||
static void __i2c_set_error(I2C_HandleTypeDef *hi2c, uint8_t error)
|
||||
{
|
||||
if (!hi2c)
|
||||
return;
|
||||
|
||||
hi2c->LastError = error;
|
||||
|
||||
// Вызываем callback ошибки, если он установлен
|
||||
if (hi2c->Config->ErrCallback)
|
||||
hi2c->Config->ErrCallback(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ожидание освобождения шины I2C
|
||||
*/
|
||||
static OperationStatus __i2c_master_wait_bus_free(I2C_HandleTypeDef *hi2c, uint32_t timeout)
|
||||
{
|
||||
uint32_t starttick = millis();
|
||||
|
||||
while(I2C_BusBusyStatus() == SET)
|
||||
{
|
||||
if(millis() - starttick > timeout)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_BUS_BUSY);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Отправка условия START
|
||||
*/
|
||||
static OperationStatus __i2c_master_send_start(I2C_HandleTypeDef *hi2c, uint32_t timeout)
|
||||
{
|
||||
uint32_t starttick = millis();
|
||||
I2C_State_TypeDef state;
|
||||
|
||||
// Формируем START
|
||||
I2C_StartCmd();
|
||||
|
||||
// Ожидаем подтверждения формирования START
|
||||
while(1)
|
||||
{
|
||||
state = I2C_GetState();
|
||||
|
||||
if (state == I2C_State_STDONE || state == I2C_State_HMTMCOK)
|
||||
{
|
||||
// START успешно сформирован
|
||||
return OK;
|
||||
}
|
||||
else if (state == I2C_State_BERROR)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_BUS_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
else if (state == I2C_State_IDLARL || state == I2C_State_HIDLARL)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_ARBITRATION_LOST);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(millis() - starttick > timeout)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_TIMEOUT);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Отправка адреса устройства
|
||||
*/
|
||||
static OperationStatus __i2c_master_send_address(I2C_HandleTypeDef *hi2c, uint16_t addr, uint8_t direction, uint32_t timeout)
|
||||
{
|
||||
uint8_t address;
|
||||
uint32_t starttick = millis();
|
||||
I2C_State_TypeDef state;
|
||||
|
||||
// Формируем адрес
|
||||
if (addr > 0x7F)
|
||||
{
|
||||
// 10-битный адрес - первая часть всегда на запись
|
||||
address = 0xF0 | ((addr >> 7) & 0x06);
|
||||
I2C_SetData(address | I2C_Direction_Transmitter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 7-битный адрес
|
||||
address = (addr << 1);
|
||||
I2C_SetData(address | direction);
|
||||
}
|
||||
|
||||
// Сбрасываем флаг прерывания
|
||||
I2C_ITStatusClear();
|
||||
|
||||
// Ожидаем подтверждения адреса
|
||||
while(1)
|
||||
{
|
||||
state = I2C_GetState();
|
||||
|
||||
// ACK получен для 7-битного адреса
|
||||
if ((direction == I2C_Direction_Transmitter &&
|
||||
(state == I2C_State_MTADPA || state == I2C_State_HMTADPA)) ||
|
||||
(direction == I2C_Direction_Receiver &&
|
||||
(state == I2C_State_MRADPA || state == I2C_State_HMRADPA)))
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
// NACK получен
|
||||
else if ((direction == I2C_Direction_Transmitter &&
|
||||
(state == I2C_State_MTADNA || state == I2C_State_HMTADNA)) ||
|
||||
(direction == I2C_Direction_Receiver &&
|
||||
(state == I2C_State_MRADNA || state == I2C_State_HMRADNA)))
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_NACK);
|
||||
return ERROR;
|
||||
}
|
||||
// Ошибка шины
|
||||
else if (state == I2C_State_BERROR)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_BUS_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
// Потеря арбитража
|
||||
else if (state == I2C_State_IDLARL || state == I2C_State_HIDLARL)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_ARBITRATION_LOST);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(millis() - starttick > timeout)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_TIMEOUT);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Отправка условия STOP
|
||||
*/
|
||||
static OperationStatus __i2c_master_send_stop(I2C_HandleTypeDef *hi2c, uint32_t timeout)
|
||||
{
|
||||
uint32_t starttick = millis();
|
||||
|
||||
// Формируем STOP
|
||||
I2C_StopCmd();
|
||||
|
||||
// Сбрасываем флаг прерывания
|
||||
I2C_ITStatusClear();
|
||||
|
||||
// Ожидаем освобождения шины (опционально, не обязательно)
|
||||
// while(I2C_BusBusyStatus() == SET)
|
||||
// {
|
||||
// if(millis() - starttick > timeout)
|
||||
// {
|
||||
// __i2c_set_error(hi2c, I2C_ERROR_TIMEOUT);
|
||||
// return ERROR;
|
||||
// }
|
||||
// }
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Блокирующая передача данных
|
||||
*/
|
||||
static OperationStatus __i2c_master_transmit_blocking(I2C_HandleTypeDef *hi2c, uint8_t *buf, uint16_t size, uint32_t timeout)
|
||||
{
|
||||
uint32_t starttick;
|
||||
I2C_State_TypeDef state;
|
||||
|
||||
for(uint16_t i = 0; i < size; i++)
|
||||
{
|
||||
// Отправляем байт данных
|
||||
I2C_SetData(buf[i]);
|
||||
|
||||
// Сбрасываем флаг прерывания
|
||||
I2C_ITStatusClear();
|
||||
|
||||
starttick = millis();
|
||||
|
||||
// Ожидаем подтверждения байта
|
||||
while(1)
|
||||
{
|
||||
state = I2C_GetState();
|
||||
|
||||
// ACK получен
|
||||
if (state == I2C_State_MTDAPA || state == I2C_State_HMTDAPA)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// NACK получен
|
||||
else if (state == I2C_State_MTDANA || state == I2C_State_HMTDANA)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_NACK);
|
||||
return ERROR;
|
||||
}
|
||||
// Ошибка шины
|
||||
else if (state == I2C_State_BERROR)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_BUS_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
// Потеря арбитража
|
||||
else if (state == I2C_State_IDLARL || state == I2C_State_HIDLARL)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_ARBITRATION_LOST);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(millis() - starttick > timeout)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_TIMEOUT);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Блокирующий прием данных
|
||||
*/
|
||||
static OperationStatus __i2c_master_receive_blocking(I2C_HandleTypeDef *hi2c, uint8_t *buf, uint16_t size, uint32_t timeout)
|
||||
{
|
||||
uint32_t starttick;
|
||||
I2C_State_TypeDef state;
|
||||
|
||||
for(uint16_t i = 0; i < size; i++)
|
||||
{
|
||||
starttick = millis();
|
||||
|
||||
// Ожидаем приема байта
|
||||
while(1)
|
||||
{
|
||||
state = I2C_GetState();
|
||||
|
||||
// Байт получен с ACK или NACK
|
||||
if (state == I2C_State_MRDAPA || state == I2C_State_MRDANA ||
|
||||
state == I2C_State_HMRDAPA || state == I2C_State_HMRDANA)
|
||||
{
|
||||
// Читаем данные
|
||||
buf[i] = I2C_GetData();
|
||||
|
||||
// Для последнего байта отправляем NACK
|
||||
if (i == size - 1)
|
||||
{
|
||||
I2C_NACKCmd();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// Ошибка шины
|
||||
else if (state == I2C_State_BERROR)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_BUS_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
// Потеря арбитража
|
||||
else if (state == I2C_State_IDLARL || state == I2C_State_HIDLARL)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_ARBITRATION_LOST);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(millis() - starttick > timeout)
|
||||
{
|
||||
__i2c_set_error(hi2c, I2C_ERROR_TIMEOUT);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
183
MDK-ARM/Core/App/i2c.h
Normal file
183
MDK-ARM/Core/App/i2c.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.h
|
||||
* @author Разваляев Алексей
|
||||
* @brief Драйвер I2C на основе PLIB035.
|
||||
* Данный файл содержит определения типов, структур и прототипы функций
|
||||
* для работы с I2C, включая:
|
||||
* + Структуры и typedef для I2C
|
||||
* + Прототипы функций для инициализации и API драйвера
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __I2C_H
|
||||
#define __I2C_H
|
||||
|
||||
//-- Includes ------------------------------------------------------------------
|
||||
#include "plib035.h"
|
||||
#include "plib035_i2c.h"
|
||||
#include "retarget_conf.h"
|
||||
|
||||
//-- Defines -------------------------------------------------------------------
|
||||
// Дефайны для пинов I2C
|
||||
#define I2C_SCL_Pin GPIO_Pin_0 /**< PA0 — I2C SCL */
|
||||
#define I2C_SDA_Pin GPIO_Pin_1 /**< PA1 — I2C SDA */
|
||||
#define I2C_GPIO_Port GPIOA /**< GPIO порт I2C */
|
||||
|
||||
// Стандартные частоты I2C
|
||||
#define I2C_STANDARD_MODE 100000 /**< 100 kHz */
|
||||
#define I2C_FAST_MODE 400000 /**< 400 kHz */
|
||||
#define I2C_FAST_MODE_PLUS 1000000 /**< 1 MHz */
|
||||
#define I2C_HIGH_SPEED_MODE 3400000 /**< 3.4 MHz */
|
||||
|
||||
// Максимальное время ожидания по умолчанию (мс)
|
||||
#define I2C_DEFAULT_TIMEOUT 1000
|
||||
|
||||
// Коды ошибок I2C
|
||||
#define I2C_ERROR_NONE 0x00
|
||||
#define I2C_ERROR_BUS_BUSY 0x01
|
||||
#define I2C_ERROR_TIMEOUT 0x02
|
||||
#define I2C_ERROR_NACK 0x03
|
||||
#define I2C_ERROR_ARBITRATION_LOST 0x04
|
||||
#define I2C_ERROR_BUS_ERROR 0x05
|
||||
#define I2C_ERROR_PEC_FAIL 0x06
|
||||
|
||||
//-- Types ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Типы callback-функций I2C
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
I2C_Callback_Tx, /*!< Передача данных завершена */
|
||||
I2C_Callback_Rx, /*!< Приём данных завершён */
|
||||
I2C_Callback_Addr, /*!< Ведомый получил свой адрес */
|
||||
I2C_Callback_Error, /*!< Ошибка I2C */
|
||||
|
||||
} I2C_CallbackTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Режимы работы I2C
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
I2C_Mode_Master, /*!< Режим мастера */
|
||||
I2C_Mode_Slave, /*!< Режим ведомого */
|
||||
} I2C_ModeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Направление передачи I2C
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
I2C_Direction_Transmitter, /*!< Направление: передатчик */
|
||||
I2C_Direction_Receiver, /*!< Направление: приемник */
|
||||
} I2C_DirectionTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Размер регистра устройства
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
I2C_RegSize_8bit, /*!< Размер регистра: 8 бит */
|
||||
I2C_RegSize_16bit, /*!< Размер регистра: 16 бит */
|
||||
} I2C_RegSizeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Структура инициализации I2C
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
I2C_ModeTypeDef Mode; /*!< Режим работы: I2C_Mode_Master или I2C_Mode_Slave */
|
||||
FunctionalState HSMode; /*!< Высокоскоростной режим */
|
||||
FunctionalState Addr10Bit; /*!< 10-битная адресация */
|
||||
I2C_RegSizeTypeDef RegSize; /*!< Размер регистра: I2C_RegSize_8bit или I2C_RegSize_16bit */
|
||||
uint16_t SlaveAddr; /*!< Адрес ведомого (для режима Slave) */
|
||||
|
||||
FunctionalState Timeout; /*!< Таймаут: */
|
||||
I2C_TimeoutClkDiv_TypeDef TimeoutClkDiv; /*!< Делитель тактирования таймаута */
|
||||
uint8_t TimeoutLoad; /*!< Значение загрузки счетчика таймаута */
|
||||
|
||||
FunctionalState AlertResponse; /*!< Ответ на тревогу */
|
||||
FunctionalState GlobalCall; /*!< Общий вызов */
|
||||
|
||||
} I2C_Init_TypeDef;
|
||||
|
||||
/**
|
||||
* @brief Расширенная конфигурация I2C
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
I2C_Init_TypeDef I2C_Init; /*!< Базовая конфигурация I2C */
|
||||
|
||||
uint32_t I2CFreq; /*!< Частота тактирования I2C в Гц */
|
||||
uint32_t FSFreq; /*!< Частота SCL в стандартном режиме в Гц */
|
||||
uint32_t HSFreq; /*!< Частота SCL в высокоскоростном режиме в Гц */
|
||||
|
||||
/* Callback функции */
|
||||
void (*TxCallback)(void); /*!< Вызывается при завершении передачи */
|
||||
void (*RxCallback)(void); /*!< Вызывается при завершении приема */
|
||||
void (*AddrCallback)(void); /*!< Вызывается когда ведомый получает свой адрес */
|
||||
void (*ErrCallback)(uint8_t error); /*!< Вызывается при ошибке I2C с кодом ошибки */
|
||||
|
||||
} I2C_ExtInit_TypeDef;
|
||||
|
||||
/**
|
||||
* @brief Хендл I2C
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
I2C_TypeDef *Instance; /*!< Регистры I2C */
|
||||
I2C_ExtInit_TypeDef *Config; /*!< Конфигурация I2C */
|
||||
|
||||
uint8_t LastError; /*!< Код последней ошибки */
|
||||
|
||||
} I2C_HandleTypeDef;
|
||||
|
||||
//-- External handles ----------------------------------------------------------
|
||||
|
||||
extern I2C_HandleTypeDef hi2c;
|
||||
|
||||
//-- Exported functions prototypes ---------------------------------------------
|
||||
|
||||
/* Init functions */
|
||||
|
||||
/* Первичная инициализация I2C */
|
||||
void i2c_init_first(void);
|
||||
/* Инициализация I2C */
|
||||
OperationStatus i2c_init(I2C_HandleTypeDef *hi2c, I2C_ExtInit_TypeDef *NewConfig);
|
||||
/* Инициализация GPIO для I2C */
|
||||
void i2c_gpio_init(void);
|
||||
/* Деинициализация GPIO для I2C */
|
||||
void i2c_gpio_deinit(void);
|
||||
|
||||
/* API functions*/
|
||||
|
||||
/* Установка callback-функции I2C */
|
||||
OperationStatus I2C_Set_Callback(I2C_HandleTypeDef *hi2c, I2C_CallbackTypeDef CallbackType, void (*Callback)());
|
||||
/* Запуск I2C */
|
||||
OperationStatus I2C_Start(I2C_HandleTypeDef *hi2c);
|
||||
/* Остановка I2C */
|
||||
OperationStatus I2C_Stop(I2C_HandleTypeDef *hi2c);
|
||||
|
||||
/* Получение кода последней ошибки */
|
||||
uint8_t I2C_GetLastError(I2C_HandleTypeDef *hi2c);
|
||||
|
||||
/* Передача данных в режиме мастера (блокирующий режим) */
|
||||
OperationStatus I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t addr, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
/* Прием данных в режиме мастера (блокирующий режим) */
|
||||
OperationStatus I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t addr, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
/* Запись регистра устройства (блокирующий режим) */
|
||||
OperationStatus I2C_Master_WriteReg(I2C_HandleTypeDef *hi2c, uint16_t addr, uint16_t reg, uint8_t value, uint32_t timeout);
|
||||
/* Чтение регистра устройства (блокирующий режим) */
|
||||
OperationStatus I2C_Master_ReadReg(I2C_HandleTypeDef *hi2c, uint16_t addr, uint16_t reg, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
/* Запись нескольких регистров (блокирующий режим) */
|
||||
OperationStatus I2C_Master_WriteRegs(I2C_HandleTypeDef *hi2c, uint16_t addr, uint16_t reg, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
/* Чтение нескольких регистров (блокирующий режим) */
|
||||
OperationStatus I2C_Master_ReadRegs(I2C_HandleTypeDef *hi2c, uint16_t addr, uint16_t reg, uint8_t *buf, uint16_t size, uint32_t timeout);
|
||||
|
||||
/* Проверка наличия устройства на шине */
|
||||
OperationStatus I2C_Master_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t addr, uint32_t timeout);
|
||||
|
||||
#endif /*__I2C_H*/
|
||||
@@ -17,8 +17,9 @@ void periph_init()
|
||||
{
|
||||
sysclk_init();
|
||||
uart_init_first();
|
||||
adc_init_first();
|
||||
tmr_init_first();
|
||||
adc_init_first();
|
||||
i2c_init_first();
|
||||
gpio_init();
|
||||
#ifdef RETARGET
|
||||
retarget_init();
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "uart.h"
|
||||
#include "tmr.h"
|
||||
#include "adc.h"
|
||||
#include "i2c.h"
|
||||
|
||||
/* Обработчик ошибок */
|
||||
void Error_Handler(void);
|
||||
@@ -59,6 +60,10 @@ void Error_Handler(void);
|
||||
#define USE_ADC_DC2 0 /*!< Использовать Компаратор 2 */
|
||||
#define USE_ADC_DC3 0 /*!< Использовать Компаратор 3 */
|
||||
|
||||
/* I2C */
|
||||
#define USE_I2C 0 /*!< Использовать I2C */
|
||||
|
||||
|
||||
/** @note Для RETARGET надо объявить этот дефайн в проекте
|
||||
Options for Target -> C/C++ -> Defines
|
||||
*/
|
||||
@@ -306,6 +311,23 @@ static ADC_DC_ExtInit_TypeDef adc_dc3_config = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//-- I2C Конфигурации ---------------------------------------------------------
|
||||
#if USE_I2C==1
|
||||
static I2C_ExtInit_TypeDef i2c_config = {
|
||||
//Mode, HSMode, Addr10Bit, RegSize, SlaveAddr
|
||||
I2C_Mode_Master, DISABLE, DISABLE, I2C_RegSize_8bit, 0x00,
|
||||
//Timeout, TimeoutClkDiv, TimeoutLoad
|
||||
DISABLE, I2C_TimeoutClkDiv_Div4, 0x00,
|
||||
//AlertResponse, GlobalCall
|
||||
DISABLE, DISABLE,
|
||||
//I2CFreq, FSFreq, HSFreq
|
||||
SYSCLK_CORE_CLOCK_MHZ * __MHZ, I2C_STANDARD_MODE, I2C_HIGH_SPEED_MODE,
|
||||
//TxCallback, RxCallback, AddrCallback, ErrCallback
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
//-- NVIC Конфигурации --------------------------------------------------------
|
||||
/** @brief Приоритеты прерываний, 0 - самый высокий приоритет*/
|
||||
static uint8_t NCIV_Priorities[] =
|
||||
1
MDK-ARM/Core/ExtendedLibs
Submodule
1
MDK-ARM/Core/ExtendedLibs
Submodule
Submodule MDK-ARM/Core/ExtendedLibs added at 795ebbd220
@@ -77,7 +77,7 @@
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<IsCurrentTarget>1</IsCurrentTarget>
|
||||
</OPTFL>
|
||||
<CpuCode>0</CpuCode>
|
||||
<CpuCode>255</CpuCode>
|
||||
<DebugOpt>
|
||||
<uSim>0</uSim>
|
||||
<uTrg>1</uTrg>
|
||||
@@ -380,6 +380,18 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>.\Core\App\i2c.c</PathWithFileName>
|
||||
<FilenameWithoutPath>i2c.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>11</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>.\Core\App\sysclk.c</PathWithFileName>
|
||||
<FilenameWithoutPath>sysclk.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
@@ -387,7 +399,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>11</FileNumber>
|
||||
<FileNumber>12</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -407,7 +419,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>12</FileNumber>
|
||||
<FileNumber>13</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -419,7 +431,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>13</FileNumber>
|
||||
<FileNumber>14</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -431,7 +443,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>14</FileNumber>
|
||||
<FileNumber>15</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -443,7 +455,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>15</FileNumber>
|
||||
<FileNumber>16</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -455,7 +467,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>16</FileNumber>
|
||||
<FileNumber>17</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -467,7 +479,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>17</FileNumber>
|
||||
<FileNumber>18</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -479,7 +491,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>18</FileNumber>
|
||||
<FileNumber>19</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -491,7 +503,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>19</FileNumber>
|
||||
<FileNumber>20</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -503,7 +515,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>20</FileNumber>
|
||||
<FileNumber>21</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -515,7 +527,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>21</FileNumber>
|
||||
<FileNumber>22</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -535,7 +547,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>4</GroupNumber>
|
||||
<FileNumber>22</FileNumber>
|
||||
<FileNumber>23</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -547,7 +559,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>4</GroupNumber>
|
||||
<FileNumber>23</FileNumber>
|
||||
<FileNumber>24</FileNumber>
|
||||
<FileType>2</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -567,7 +579,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>24</FileNumber>
|
||||
<FileNumber>25</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -579,7 +591,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>25</FileNumber>
|
||||
<FileNumber>26</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -591,7 +603,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>26</FileNumber>
|
||||
<FileNumber>27</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -603,7 +615,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>27</FileNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -615,7 +627,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -627,7 +639,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -639,7 +651,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -651,7 +663,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -663,7 +675,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -675,7 +687,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -687,7 +699,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -699,7 +711,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -711,7 +723,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -723,7 +735,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileNumber>38</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -735,7 +747,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>38</FileNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -755,7 +767,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -767,7 +779,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -779,7 +791,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -434,6 +434,11 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\Core\App\adc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>i2c.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\Core\App\i2c.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>sysclk.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user