270 lines
5.3 KiB
C
270 lines
5.3 KiB
C
#include "bsp_i2c.h"
|
|
#include "main.h"
|
|
|
|
|
|
extern I2C_HandleTypeDef hi2c1;
|
|
extern I2C_HandleTypeDef hi2c2;
|
|
|
|
|
|
void bsp_I2C_master_transmit(I2C_TypeDef *I2C, uint16_t I2C_address, uint8_t *data, uint16_t len)
|
|
{
|
|
if(I2C == I2C1)
|
|
{
|
|
HAL_I2C_Master_Transmit(&hi2c1, I2C_address, data, len, 100);
|
|
}
|
|
else if(I2C == I2C2)
|
|
{
|
|
HAL_I2C_Master_Transmit(&hi2c2, I2C_address, data, len, 100);
|
|
}
|
|
}
|
|
|
|
|
|
void bsp_I2C_reset(I2C_TypeDef *I2C)
|
|
{
|
|
I2C_HandleTypeDef *hi2c;
|
|
if(I2C == I2C1)
|
|
{
|
|
hi2c = &hi2c1;
|
|
}
|
|
else if(I2C == I2C2)
|
|
{
|
|
hi2c = &hi2c2;
|
|
}
|
|
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
|
|
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
|
|
if (HAL_I2C_Init(hi2c) != HAL_OK)
|
|
{
|
|
Error_Handler();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool_t bsp_I2C_check_ack(I2C_TypeDef *I2C, uint16_t I2C_address)
|
|
{
|
|
I2C_HandleTypeDef *hi2c;
|
|
if(I2C == I2C1)
|
|
{
|
|
hi2c = &hi2c1;
|
|
}
|
|
else if(I2C == I2C2)
|
|
{
|
|
hi2c = &hi2c2;
|
|
}
|
|
|
|
if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) && ((hi2c->hdmatx != NULL && hi2c->hdmatx->Instance->NDTR != 0) || (hi2c->hdmarx != NULL && hi2c->hdmarx->Instance->NDTR != 0)))
|
|
{
|
|
return I2C_ACK;
|
|
}
|
|
else
|
|
{
|
|
uint16_t timeout = 0;
|
|
|
|
timeout = 0;
|
|
while(hi2c->Instance->SR2 & 0x02)
|
|
{
|
|
timeout ++;
|
|
if(timeout > 100)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return I2C_NO_ACK;
|
|
}
|
|
}
|
|
|
|
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
|
|
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x01))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 100)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return I2C_NO_ACK;
|
|
}
|
|
}
|
|
|
|
hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(I2C_address);
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x02))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 500)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return I2C_NO_ACK;
|
|
}
|
|
}
|
|
|
|
do{
|
|
__IO uint32_t tmpreg = 0x00U;
|
|
tmpreg = hi2c->Instance->SR1;
|
|
tmpreg = hi2c->Instance->SR2;
|
|
UNUSED(tmpreg);
|
|
} while(0);
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x80))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 500)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return I2C_NO_ACK;
|
|
}
|
|
}
|
|
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
|
|
return I2C_ACK;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void DMA1_Stream7_IRQHandler(void)
|
|
{
|
|
if(DMA1->HISR & (1<<27))
|
|
{
|
|
__HAL_DMA_CLEAR_FLAG(hi2c2.hdmatx, DMA_HISR_TCIF7);
|
|
SET_BIT(hi2c2.Instance->CR1, I2C_CR1_STOP);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void I2C2_tx_DMA_init(void)
|
|
{
|
|
|
|
//disable DMA
|
|
//ʧЧDMA
|
|
__HAL_DMA_DISABLE(hi2c2.hdmatx);
|
|
|
|
while(hi2c2.hdmatx->Instance->CR & DMA_SxCR_EN)
|
|
{
|
|
__HAL_DMA_DISABLE(hi2c2.hdmatx);
|
|
}
|
|
hi2c2.hdmatx->Instance->PAR = (uint32_t)(&I2C2->DR);
|
|
__HAL_DMA_CLEAR_FLAG(hi2c2.hdmatx, DMA_HISR_TCIF7);
|
|
__HAL_DMA_ENABLE_IT(hi2c2.hdmatx, DMA_IT_TC);
|
|
|
|
|
|
|
|
}
|
|
|
|
void I2C2_tx_DMA_enable(uint32_t tx_buf, uint16_t ndtr)
|
|
{
|
|
//disable DMA
|
|
//ʧЧDMA
|
|
__HAL_DMA_DISABLE(hi2c2.hdmatx);
|
|
|
|
while(hi2c2.hdmatx->Instance->CR & DMA_SxCR_EN)
|
|
{
|
|
__HAL_DMA_DISABLE(hi2c2.hdmatx);
|
|
}
|
|
|
|
__HAL_DMA_CLEAR_FLAG(hi2c2.hdmatx, DMA_HISR_TCIF7);
|
|
|
|
|
|
hi2c2.hdmatx->Instance->M0AR = tx_buf;
|
|
__HAL_DMA_SET_COUNTER(hi2c2.hdmatx, ndtr);
|
|
|
|
__HAL_DMA_ENABLE(hi2c2.hdmatx);
|
|
|
|
}
|
|
|
|
HAL_StatusTypeDef I2C_TX_DMA_START(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
|
|
{
|
|
uint16_t timeout = 0;
|
|
|
|
if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
|
|
{
|
|
hi2c->Instance->CR1 |= I2C_CR1_PE;
|
|
}
|
|
|
|
|
|
timeout = 0;
|
|
while(hi2c->Instance->SR2 & 0x02)
|
|
{
|
|
timeout ++;
|
|
if(timeout > 100)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return HAL_BUSY;
|
|
}
|
|
}
|
|
|
|
|
|
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
|
|
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x01))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 100)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
|
|
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x02))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 500)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
do{
|
|
__IO uint32_t tmpreg = 0x00U;
|
|
tmpreg = hi2c->Instance->SR1;
|
|
tmpreg = hi2c->Instance->SR2;
|
|
UNUSED(tmpreg);
|
|
} while(0);
|
|
|
|
|
|
|
|
timeout = 0;
|
|
while(!(hi2c->Instance->SR1 & 0x80))
|
|
{
|
|
timeout ++;
|
|
if(timeout > 500)
|
|
{
|
|
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
return HAL_OK;
|
|
}
|
|
void I2C2_DMA_transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
|
|
{
|
|
if( I2C_TX_DMA_START(&hi2c2, DevAddress) == HAL_OK)
|
|
{
|
|
I2C2_tx_DMA_enable((uint32_t)pData, Size);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|