/* Includes ------------------------------------------------------------------*/
#include
"stm32f0xx_hal.h"
/* Private variables ---------------------------------------------------------*/
I
2
C_HandleTypeDef hi
2
c
1
;
/* Private variables ---------------------------------------------------------*/
uint
8
_t data =
0
xFF;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static
void MX_GPIO_Init(void);
static
void MX_I
2
C
1
_Init(void);
/* Private function prototypes -----------------------------------------------*/
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I
2
C
1
_Init();
while (HAL_I
2
C_GetState(&hi
2
c
1
) != HAL_I
2
C_STATE_READY)
{
// Waiting for setup? - Flash at
2
Hz
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
HAL_Delay(
250
);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
HAL_Delay(
250
);
}
while(HAL_I
2
C_Slave_Receive_IT(&hi
2
c
1
, (uint
8
_t *) data,
1
) != HAL_OK)
{
// Transfer error in transmission process - Flash at
1
Hz
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
HAL_Delay(
500
);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
HAL_Delay(
500
);
}
while (HAL_I
2
C_GetState(&hi
2
c
1
) != HAL_I
2
C_STATE_READY)
{
//
5
Hz flash while not ready
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
HAL_Delay(
100
);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
HAL_Delay(
100
);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
while (
1
)
{
//
0.5
Hz blip when idle
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
HAL_Delay(
100
);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
HAL_Delay(
1900
);
}
}
void HAL_I
2
C_SlaveRxCpltCallback(I
2
C_HandleTypeDef *hi
2
c)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
}
void HAL_I
2
C_ErrorCallback(I
2
C_HandleTypeDef *hi
2
c)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
HAL_Delay(
900
);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_RESET);
HAL_Delay(
100
);
}
/** System Clock Configuration */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue =
16
;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV
1
;
RCC_ClkInitStruct.APB
1
CLKDivider = RCC_HCLK_DIV
1
;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_
0
);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I
2
C
1
;
PeriphClkInit.I
2
c
1
ClockSelection = RCC_I
2
C
1
CLKSOURCE_HSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/
1000
);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
/* I2C1 init function */
void MX_I
2
C
1
_Init(void)
{
hi
2
c
1
.Instance = I
2
C
1
;
hi
2
c
1
.Init.Timing =
0
x
2000090
E;
hi
2
c
1
.Init.OwnAddress
1
=
0
xC
2
;
hi
2
c
1
.Init.AddressingMode = I
2
C_ADDRESSINGMODE_
7
BIT;
hi
2
c
1
.Init.DualAddressMode = I
2
C_DUALADDRESS_DISABLED;
hi
2
c
1
.Init.OwnAddress
2
=
0
;
hi
2
c
1
.Init.OwnAddress
2
Masks = I
2
C_OA
2
_NOMASK;
hi
2
c
1
.Init.GeneralCallMode = I
2
C_GENERALCALL_DISABLED;
hi
2
c
1
.Init.NoStretchMode = I
2
C_NOSTRETCH_DISABLED;
if(HAL_I
2
C_Init(&hi
2
c
1
) != HAL_OK){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_
5
, GPIO_PIN_SET);
}
/**Configure Analogue filter
*/
HAL_I
2
CEx_AnalogFilter_Config(&hi
2
c
1
, I
2
C_ANALOGFILTER_ENABLED);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_
5
;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint
8
_t* file, uint
32
_t line)
{
}
#endif
/**
* @}
*/
/**
* @}
*/
void
HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if
(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PA9 ------> I2C1_SCL
PA10 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__I2C1_CLK_ENABLE();
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C1_IRQn);
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
void
HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
{
/* I2C in mode Transmitter ---------------------------------------------------*/
if
(((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI | I2C_IT_ADDRI)) == SET))
{
/* Slave mode selected */
if
(hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX)
{
I2C_SlaveTransmit_ISR(hi2c);
}
}
if
(((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI)) == SET))
{
/* Master mode selected */
if
((hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_TX))
{
I2C_MasterTransmit_ISR(hi2c);
}
}
/* I2C in mode Receiver ----------------------------------------------------*/
if
(((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI | I2C_IT_ADDRI)) == SET))
{
/* Slave mode selected */
if
(hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX)
{
I2C_SlaveReceive_ISR(hi2c);
// <<<<<<<<----------- ENTERS ISR HERE
}
}
if
(((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI)) == SET))
{
/* Master mode selected */
if
((hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX))
{
I2C_MasterReceive_ISR(hi2c);
}
}
}
static
HAL_StatusTypeDef I2C_SlaveReceive_ISR(I2C_HandleTypeDef *hi2c)
{
/* Process Locked */
__HAL_LOCK(hi2c);
if
(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET)
{
/* Clear NACK Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
HAL_I2C_ErrorCallback(hi2c);
}
else
if
(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)
{
/* Clear ADDR flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); ///// <<<<<----- No Problems when this runs
}
else
if
(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
{
/* Read data from RXDR */
(*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
///// <<<<<----- HARD FAULT ERROR OCCURS HERE
hi2c->XferSize--;
hi2c->XferCount--;
}
else
if
(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
{
/* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */
__HAL_I2C_DISABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_RXI );
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
HAL_I2C_SlaveRxCpltCallback(hi2c);
}
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return
HAL_OK;
}