Merging pull request #63 Improvements to STM32F1 I2C, CAN, RCC, and USB (f107)
Merge remote-tracking branch 'icd/master'
This commit is contained in:
@@ -85,7 +85,8 @@ Initialize the selected CAN peripheral block.
|
||||
@returns int 0 on success, 1 on initialization failure.
|
||||
*/
|
||||
int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
|
||||
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp)
|
||||
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp,
|
||||
bool loopback, bool silent)
|
||||
{
|
||||
u32 wait_ack = 0x00000000;
|
||||
u32 can_msr_inak_timeout = 0x0000FFFF;
|
||||
@@ -107,6 +108,9 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
|
||||
if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)
|
||||
return 1;
|
||||
|
||||
/* clear can timing bits */
|
||||
CAN_BTR(canport) = 0;
|
||||
|
||||
/* Set the automatic bus-off management. */
|
||||
if (ttcm)
|
||||
CAN_MCR(canport) |= CAN_MCR_TTCM;
|
||||
@@ -138,8 +142,19 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
|
||||
else
|
||||
CAN_MCR(canport) &= ~CAN_MCR_TXFP;
|
||||
|
||||
if (silent)
|
||||
CAN_BTR(canport) |= CAN_BTR_SILM;
|
||||
else
|
||||
CAN_BTR(canport) &= ~CAN_BTR_SILM;
|
||||
|
||||
if (loopback)
|
||||
CAN_BTR(canport) |= CAN_BTR_LBKM;
|
||||
else
|
||||
CAN_BTR(canport) &= ~CAN_BTR_LBKM;
|
||||
|
||||
|
||||
/* Set bit timings. */
|
||||
CAN_BTR(canport) = sjw | ts2 | ts1 |
|
||||
CAN_BTR(canport) |= sjw | ts2 | ts1 |
|
||||
(u32)(CAN_BTR_BRP_MASK & (brp - 1));
|
||||
|
||||
/* Request initialization "leave". */
|
||||
@@ -456,3 +471,8 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
|
||||
if (release)
|
||||
can_fifo_release(canport, fifo);
|
||||
}
|
||||
|
||||
bool can_available_mailbox(u32 canport)
|
||||
{
|
||||
return CAN_TSR(canport) & (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2);
|
||||
}
|
||||
|
||||
@@ -35,3 +35,25 @@ void desig_get_unique_id(u32 result[])
|
||||
result[1] = bits63_32;
|
||||
result[2] = bits31_16 << 16 | bits15_0;
|
||||
}
|
||||
|
||||
void desig_get_unique_id_as_string(char *string,
|
||||
unsigned int string_len)
|
||||
{
|
||||
int i, len;
|
||||
u8 device_id[12];
|
||||
static const char chars[] = "0123456789ABCDEF";
|
||||
|
||||
desig_get_unique_id((u32 *)device_id);
|
||||
|
||||
/* Each byte produces two characters */
|
||||
len = (2 * sizeof(device_id) < string_len) ?
|
||||
2 * sizeof(device_id) : string_len - 1;
|
||||
|
||||
for (i = 0; i < len; i += 2) {
|
||||
string[i] = chars[(device_id[i / 2] >> 0) & 0x0F];
|
||||
string[i + 1] = chars[(device_id[i / 2] >> 4) & 0x0F];
|
||||
}
|
||||
|
||||
string[len] = '\0';
|
||||
}
|
||||
|
||||
|
||||
@@ -433,5 +433,10 @@ void dma_set_number_of_data(u32 dma, u8 channel, u16 number)
|
||||
{
|
||||
DMA_CNDTR(dma, channel) = number;
|
||||
}
|
||||
|
||||
void dma_clear_flag(u32 dma, u32 flag)
|
||||
{
|
||||
DMA_ISR(dma) &= ~flag;
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ value cannot be ascertained from the hardware.
|
||||
*/
|
||||
void gpio_primary_remap(u8 swjdisable, u32 maps)
|
||||
{
|
||||
AFIO_MAPR = swjdisable | (maps & 0x1FFFFF);
|
||||
AFIO_MAPR |= swjdisable | (maps & 0x1FFFFF);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
@@ -182,7 +182,7 @@ The AFIO remapping feature is used only with the STM32F10x series.
|
||||
*/
|
||||
void gpio_secondary_remap(u32 maps)
|
||||
{
|
||||
AFIO_MAPR2 = maps;
|
||||
AFIO_MAPR2 |= maps;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -71,6 +71,12 @@ void rcc_osc_ready_int_clear(osc_t osc)
|
||||
case PLL:
|
||||
RCC_CIR |= RCC_CIR_PLLRDYC;
|
||||
break;
|
||||
case PLL2:
|
||||
RCC_CIR |= RCC_CIR_PLL2RDYC;
|
||||
break;
|
||||
case PLL3:
|
||||
RCC_CIR |= RCC_CIR_PLL3RDYC;
|
||||
break;
|
||||
case HSE:
|
||||
RCC_CIR |= RCC_CIR_HSERDYC;
|
||||
break;
|
||||
@@ -98,6 +104,12 @@ void rcc_osc_ready_int_enable(osc_t osc)
|
||||
case PLL:
|
||||
RCC_CIR |= RCC_CIR_PLLRDYIE;
|
||||
break;
|
||||
case PLL2:
|
||||
RCC_CIR |= RCC_CIR_PLL2RDYIE;
|
||||
break;
|
||||
case PLL3:
|
||||
RCC_CIR |= RCC_CIR_PLL3RDYIE;
|
||||
break;
|
||||
case HSE:
|
||||
RCC_CIR |= RCC_CIR_HSERDYIE;
|
||||
break;
|
||||
@@ -125,6 +137,12 @@ void rcc_osc_ready_int_disable(osc_t osc)
|
||||
case PLL:
|
||||
RCC_CIR &= ~RCC_CIR_PLLRDYIE;
|
||||
break;
|
||||
case PLL2:
|
||||
RCC_CIR &= ~RCC_CIR_PLL2RDYIE;
|
||||
break;
|
||||
case PLL3:
|
||||
RCC_CIR &= ~RCC_CIR_PLL3RDYIE;
|
||||
break;
|
||||
case HSE:
|
||||
RCC_CIR &= ~RCC_CIR_HSERDYIE;
|
||||
break;
|
||||
@@ -153,6 +171,12 @@ int rcc_osc_ready_int_flag(osc_t osc)
|
||||
case PLL:
|
||||
return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
|
||||
break;
|
||||
case PLL2:
|
||||
return ((RCC_CIR & RCC_CIR_PLL2RDYF) != 0);
|
||||
break;
|
||||
case PLL3:
|
||||
return ((RCC_CIR & RCC_CIR_PLL3RDYF) != 0);
|
||||
break;
|
||||
case HSE:
|
||||
return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
|
||||
break;
|
||||
@@ -203,6 +227,12 @@ void rcc_wait_for_osc_ready(osc_t osc)
|
||||
case PLL:
|
||||
while ((RCC_CR & RCC_CR_PLLRDY) == 0);
|
||||
break;
|
||||
case PLL2:
|
||||
while ((RCC_CR & RCC_CR_PLL2RDY) == 0);
|
||||
break;
|
||||
case PLL3:
|
||||
while ((RCC_CR & RCC_CR_PLL3RDY) == 0);
|
||||
break;
|
||||
case HSE:
|
||||
while ((RCC_CR & RCC_CR_HSERDY) == 0);
|
||||
break;
|
||||
@@ -238,6 +268,12 @@ void rcc_osc_on(osc_t osc)
|
||||
case PLL:
|
||||
RCC_CR |= RCC_CR_PLLON;
|
||||
break;
|
||||
case PLL2:
|
||||
RCC_CR |= RCC_CR_PLL2ON;
|
||||
break;
|
||||
case PLL3:
|
||||
RCC_CR |= RCC_CR_PLL3ON;
|
||||
break;
|
||||
case HSE:
|
||||
RCC_CR |= RCC_CR_HSEON;
|
||||
break;
|
||||
@@ -273,6 +309,12 @@ void rcc_osc_off(osc_t osc)
|
||||
case PLL:
|
||||
RCC_CR &= ~RCC_CR_PLLON;
|
||||
break;
|
||||
case PLL2:
|
||||
RCC_CR &= ~RCC_CR_PLL2ON;
|
||||
break;
|
||||
case PLL3:
|
||||
RCC_CR &= ~RCC_CR_PLL3ON;
|
||||
break;
|
||||
case HSE:
|
||||
RCC_CR &= ~RCC_CR_HSEON;
|
||||
break;
|
||||
@@ -331,6 +373,8 @@ void rcc_osc_bypass_enable(osc_t osc)
|
||||
RCC_BDCR |= RCC_BDCR_LSEBYP;
|
||||
break;
|
||||
case PLL:
|
||||
case PLL2:
|
||||
case PLL3:
|
||||
case HSI:
|
||||
case LSI:
|
||||
/* Do nothing, only HSE/LSE allowed here. */
|
||||
@@ -361,6 +405,8 @@ void rcc_osc_bypass_disable(osc_t osc)
|
||||
RCC_BDCR &= ~RCC_BDCR_LSEBYP;
|
||||
break;
|
||||
case PLL:
|
||||
case PLL2:
|
||||
case PLL3:
|
||||
case HSI:
|
||||
case LSI:
|
||||
/* Do nothing, only HSE/LSE allowed here. */
|
||||
@@ -484,6 +530,40 @@ void rcc_set_pll_multiplication_factor(u32 mul)
|
||||
RCC_CFGR = (reg32 | (mul << 18));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Set the PLL2 Multiplication Factor.
|
||||
|
||||
@note This only has effect when the PLL is disabled.
|
||||
|
||||
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
|
||||
*/
|
||||
|
||||
void rcc_set_pll2_multiplication_factor(u32 mul)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
reg32 = RCC_CFGR2;
|
||||
reg32 &= ~((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
|
||||
RCC_CFGR2 = (reg32 | (mul << 8));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Set the PLL3 Multiplication Factor.
|
||||
|
||||
@note This only has effect when the PLL is disabled.
|
||||
|
||||
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
|
||||
*/
|
||||
|
||||
void rcc_set_pll3_multiplication_factor(u32 mul)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
reg32 = RCC_CFGR2;
|
||||
reg32 &= ~((1 << 15) | (1 << 14) | (1 << 13) | (1 << 12));
|
||||
RCC_CFGR2 = (reg32 | (mul << 12));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Set the PLL Clock Source.
|
||||
|
||||
@@ -602,6 +682,36 @@ void rcc_set_usbpre(u32 usbpre)
|
||||
RCC_CFGR = (reg32 | (usbpre << 22));
|
||||
}
|
||||
|
||||
void rcc_set_prediv1(u32 prediv)
|
||||
{
|
||||
u32 reg32;
|
||||
reg32 = RCC_CFGR2;
|
||||
reg32 &= ~(1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
|
||||
RCC_CFGR2 |= (reg32 | prediv);
|
||||
}
|
||||
|
||||
void rcc_set_prediv2(u32 prediv)
|
||||
{
|
||||
u32 reg32;
|
||||
reg32 = RCC_CFGR2;
|
||||
reg32 &= ~(1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);
|
||||
RCC_CFGR2 |= (reg32 | (prediv << 4));
|
||||
}
|
||||
|
||||
void rcc_set_prediv1_source(u32 rccsrc)
|
||||
{
|
||||
RCC_CFGR2 &= ~(1 << 16);
|
||||
RCC_CFGR2 |= (rccsrc << 16);
|
||||
}
|
||||
|
||||
void rcc_set_mco(u32 mcosrc)
|
||||
{
|
||||
u32 reg32;
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~((1 << 27) | (1 << 26) | (1 << 25) | (1 << 24));
|
||||
RCC_CFGR |= (reg32 | (mcosrc << 24));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Get the System Clock Source.
|
||||
|
||||
@@ -1030,6 +1140,63 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
|
||||
rcc_ppre2_frequency = 72000000;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Set System Clock PLL at 72MHz from HSE at 25MHz
|
||||
|
||||
*/
|
||||
|
||||
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void)
|
||||
{
|
||||
/* Enable external high-speed oscillator 25MHz. */
|
||||
rcc_osc_on(HSE);
|
||||
rcc_wait_for_osc_ready(HSE);
|
||||
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);
|
||||
|
||||
/*
|
||||
* Sysclk runs with 72MHz -> 2 waitstates.
|
||||
* 0WS from 0-24MHz
|
||||
* 1WS from 24-48MHz
|
||||
* 2WS from 48-72MHz
|
||||
*/
|
||||
flash_set_ws(FLASH_LATENCY_2WS);
|
||||
|
||||
/*
|
||||
* Set prescalers for AHB, ADC, ABP1, ABP2.
|
||||
* Do this before touching the PLL (TODO: why?).
|
||||
*/
|
||||
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */
|
||||
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */
|
||||
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */
|
||||
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */
|
||||
|
||||
/* Set pll2 prediv and multiplier */
|
||||
rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5);
|
||||
rcc_set_pll2_multiplication_factor(RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8);
|
||||
|
||||
/* Enable PLL2 oscillator and wait for it to stabilize */
|
||||
rcc_osc_on(PLL2);
|
||||
rcc_wait_for_osc_ready(PLL2);
|
||||
|
||||
/* Set pll1 prediv/multiplier, prediv1 src, and usb predivider */
|
||||
rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK);
|
||||
rcc_set_prediv1_source(RCC_CFGR2_PREDIV1SRC_PLL2_CLK);
|
||||
rcc_set_prediv1(RCC_CFGR2_PREDIV_DIV5);
|
||||
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9);
|
||||
rcc_set_pll_source(RCC_CFGR_PLLSRC_PREDIV1_CLK);
|
||||
rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3);
|
||||
|
||||
/* enable PLL1 and wait for it to stabilize */
|
||||
rcc_osc_on(PLL);
|
||||
rcc_wait_for_osc_ready(PLL);
|
||||
|
||||
/* Select PLL as SYSCLK source. */
|
||||
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
|
||||
|
||||
/* Set the peripheral clock frequencies used */
|
||||
rcc_ppre1_frequency = 36000000;
|
||||
rcc_ppre2_frequency = 72000000;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief RCC Reset the backup domain
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ void rtc_awake_from_off(osc_t clock_source)
|
||||
RCC_BDCR |= (1 << 9) | (1 << 8);
|
||||
break;
|
||||
case PLL:
|
||||
case PLL2:
|
||||
case PLL3:
|
||||
case HSI:
|
||||
/* Unusable clock source, here to prevent warnings. */
|
||||
/* Turn off clock sources to RTC. */
|
||||
|
||||
144
lib/stm32/i2c.c
144
lib/stm32/i2c.c
@@ -124,6 +124,18 @@ void i2c_send_stop(u32 i2c)
|
||||
I2C_CR1(i2c) |= I2C_CR1_STOP;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Clear Stop Flag.
|
||||
|
||||
Clear the "Send Stop" flag in the I2C config register
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_clear_stop(u32 i2c)
|
||||
{
|
||||
I2C_CR1(i2c) &= ~I2C_CR1_STOP;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Set the 7 bit Slave Address for the Peripheral.
|
||||
|
||||
@@ -269,5 +281,135 @@ void i2c_send_data(u32 i2c, u8 data)
|
||||
I2C_DR(i2c) = data;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Get Data.
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
uint8_t i2c_get_data(u32 i2c)
|
||||
{
|
||||
return I2C_DR(i2c) & 0xff;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Enable Interrupt
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
@param[in] interrupt Unsigned int32. Interrupt to enable.
|
||||
*/
|
||||
void i2c_enable_interrupt(u32 i2c, u32 interrupt)
|
||||
{
|
||||
I2C_CR2(i2c) |= interrupt;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Disable Interrupt
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
@param[in] interrupt Unsigned int32. Interrupt to disable.
|
||||
*/
|
||||
void i2c_disable_interrupt(u32 i2c, u32 interrupt)
|
||||
{
|
||||
I2C_CR2(i2c) &= ~interrupt;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Enable ACK
|
||||
|
||||
Enables acking of own 7/10 bit address
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_enable_ack(u32 i2c)
|
||||
{
|
||||
I2C_CR1(i2c) |= I2C_CR1_ACK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Disable ACK
|
||||
|
||||
Disables acking of own 7/10 bit address
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_disable_ack(u32 i2c)
|
||||
{
|
||||
I2C_CR1(i2c) &= ~I2C_CR1_ACK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C NACK Next Byte
|
||||
|
||||
Causes the I2C controller to NACK the reception of the next byte
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_nack_next(u32 i2c)
|
||||
{
|
||||
I2C_CR1(i2c) |= I2C_CR1_POS;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C NACK Next Byte
|
||||
|
||||
Causes the I2C controller to NACK the reception of the current byte
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_nack_current(u32 i2c)
|
||||
{
|
||||
I2C_CR1(i2c) &= ~I2C_CR1_POS;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Set clock duty cycle
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
@param[in] dutycycle Unsigned int32. I2C duty cycle @ref i2c_duty_cycle.
|
||||
*/
|
||||
void i2c_set_dutycycle(u32 i2c, u32 dutycycle)
|
||||
{
|
||||
if (dutycycle == I2C_CCR_DUTY_DIV2)
|
||||
I2C_CCR(i2c) &= ~I2C_CCR_DUTY;
|
||||
else
|
||||
I2C_CCR(i2c) |= I2C_CCR_DUTY;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Enable DMA
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_enable_dma(u32 i2c)
|
||||
{
|
||||
I2C_CR2(i2c) |= I2C_CR2_DMAEN;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Disable DMA
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_disable_dma(u32 i2c)
|
||||
{
|
||||
I2C_CR2(i2c) &= ~I2C_CR2_DMAEN;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Set DMA last transfer
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_set_dma_last_transfer(u32 i2c)
|
||||
{
|
||||
I2C_CR2(i2c) |= I2C_CR2_LAST;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/** @brief I2C Clear DMA last transfer
|
||||
|
||||
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
|
||||
*/
|
||||
void i2c_clear_dma_last_transfer(u32 i2c)
|
||||
{
|
||||
I2C_CR2(i2c) &= ~I2C_CR2_LAST;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
Reference in New Issue
Block a user