cancel
Showing results for 
Search instead for 
Did you mean: 

understanding the I2C peripheral on STM32L412

deep_rune
Associate III

I want to use the I2C peripheral on my STM32L412C8T6, although I read the reference manual I'm still finding the operation of this peripheral a little confusing. I have a 4 channel I2C 12bit DAC to operate, so I want the I2C to act as a master transmitter in fast mode (400KHz), transmitting first the address then 8 bytes of data which are the 12bit values of 4 channels split over two bytes. I have the clock for the I2C set to 16MHz and the rise and fall times set at 300nS - as per the reference manual.

I've programmed everything as best as I can see how, but my interrupt never runs so I must have been doing something wrong. This is my setup for the I2C -

static void MX_I2C2_Init(void)
{
  hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x00610611;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter 
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter 
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
  {
    Error_Handler();
  }
}

Here is my interrupt

void I2C2_EV_IRQHandler(void)
{
	 if (I2C2->ISR & 1<<1)
	  {
	    i2ccounter++;
	    I2C2->TXDR = DACdata[i2ccounter];
	  }
 
	 if (I2C2->ISR & 1<<6)
	 	  {
		 	 i2ccounter = 0;
	 	    I2C2 ->CR2 |= 1<<13;
	 	  }
  HAL_I2C_EV_IRQHandler(&hi2c2);
}

at the start of the main I use

  I2C2 ->CR2 |= 0b111 << 16; //bytes to send = 8
  I2C2 ->CR2 |= 1<<13; //start I2C

Can anyone tell me what im missing here?

6 REPLIES 6
KnarfB
Principal III

Have you enabled the interrupt in the NVIC?

I wouldn't mix HAL and register level prog.

yes the I2C event interrupt is enabled in the NVIC

interesting about the mixture of HAL and register level programming - why avoid it? i usually use HAL only via cube, otherwise everything with the registers

You are starting the transfer with flipping a bit, not with HAL_I2C_Master_Transmit_IT.

This might be okay, but HAL_I2C_Master_Transmit_IT would have done more, perharps changing some values in hi2c2.

Later, when HAL_I2C_EV_IRQHandler is called, it uses hi2c2 which was not prepared accordingly.

IMHO doing the setup with HAL and the rest without HAL would be safer.

>>why avoid it?

So things work out of the box, and you can play with register level optimization if the performance gained by doing so warrants it.

Very few here have interest in debugging/diagnosing failure of register level code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
KnarfB
Principal III

Did you set TXIE? Don't see code for I2C2 ->CR1.

I'm not sure where i can actually learn about HAL - what resources should I look at?