From 694ef95bcae006544a8eed06f64b2a9321c24663 Mon Sep 17 00:00:00 2001 From: IOsetting Date: Tue, 24 Jan 2023 14:55:30 +0800 Subject: [PATCH] feat: ll i2c at24c32 example --- Examples/LL/I2C/AT24C32/main.c | 259 ++++++++++++++++++++++++++ Examples/LL/I2C/AT24C32/main.h | 27 +++ Examples/LL/I2C/AT24C32/py32f0xx_it.c | 40 ++++ Examples/LL/I2C/AT24C32/py32f0xx_it.h | 19 ++ 4 files changed, 345 insertions(+) create mode 100644 Examples/LL/I2C/AT24C32/main.c create mode 100644 Examples/LL/I2C/AT24C32/main.h create mode 100644 Examples/LL/I2C/AT24C32/py32f0xx_it.c create mode 100644 Examples/LL/I2C/AT24C32/py32f0xx_it.h diff --git a/Examples/LL/I2C/AT24C32/main.c b/Examples/LL/I2C/AT24C32/main.c new file mode 100644 index 0000000..58d8444 --- /dev/null +++ b/Examples/LL/I2C/AT24C32/main.c @@ -0,0 +1,259 @@ +/*** + * Demo: I2C - AT24C32 Read/Write + * + * PY32 + * PF1 SCL + * PF0 SDA + */ +#include +#include "main.h" +#include "py32f0xx_bsp_printf.h" + + +#define MASTER_ADDRESS 0xA0 +#define AT24C_ADDRESS 0xAE +#define AT24C_MEM_ADDRESS 0x80 + +#define I2C_STATE_READY 0 +#define I2C_STATE_BUSY_TX 1 +#define I2C_STATE_BUSY_RX 2 + +/* + * EERPOM data address length + * + * 1-byte: AT24C01 - AT24C16 + * 2-byte: AT24C32+ + */ +#define AT24C_DATA_ADDR_8B 0 +#define AT24C_DATA_ADDR_16B 1 +#define AT24C_DATA_ADDR_LEN AT24C_DATA_ADDR_16B + +#define SIZE sizeof(test_text) +const uint8_t test_text[]={"I2C read/write test"}; + +__IO uint32_t i2cState = I2C_STATE_READY; + +static void APP_SystemClockConfig(void); +static void APP_I2CConfig(void); +void APP_I2C_Transmit(uint8_t devAddress, uint16_t memAddress, uint8_t *pData, uint16_t len); +uint8_t APP_I2C_ReceiveByte(uint16_t devAddress, uint16_t memAddress); + +void AT24CXX_Read(uint16_t dataAddr, uint8_t *pBuffer, uint16_t len) +{ + while (len--) + { + *pBuffer++ = APP_I2C_ReceiveByte(AT24C_ADDRESS, dataAddr++); + LL_mDelay(5); + } +} + +void AT24CXX_Write(uint16_t dataAddr, uint8_t *pBuffer, uint16_t len) +{ + while (len--) + { + APP_I2C_Transmit(AT24C_ADDRESS, dataAddr++, pBuffer++, 1); + // Writing might halt if delay is too short + LL_mDelay(5); + } +} + +int main(void) +{ + uint8_t buf[SIZE]; + + APP_SystemClockConfig(); + + BSP_USART_Config(115200); + printf("I2C Demo: AT24C32\r\nClock: %ld\r\n", SystemCoreClock); + + APP_I2CConfig(); + + printf("Start writing..."); + AT24CXX_Write(AT24C_MEM_ADDRESS, (uint8_t *)test_text, SIZE); + printf("succ\r\n"); + + printf("Start reading..."); + AT24CXX_Read(AT24C_MEM_ADDRESS, buf, SIZE); + printf("read: %s\r\n", buf); + + while(1); +} + +static void APP_I2CConfig(void) +{ + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOF); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + + // PF1 SCL + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + // PF0 SDA + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + + LL_I2C_InitTypeDef I2C_InitStruct; + /* + * Clock speed: + * - standard = 100khz + * - fast = 400khz + */ + I2C_InitStruct.ClockSpeed = LL_I2C_MAX_SPEED_FAST; + I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_16_9; + I2C_InitStruct.OwnAddress1 = MASTER_ADDRESS; + I2C_InitStruct.TypeAcknowledge = LL_I2C_NACK; + LL_I2C_Init(I2C1, &I2C_InitStruct); +} + +void APP_I2C_Transmit(uint8_t devAddress, uint16_t memAddress, uint8_t *pData, uint16_t len) +{ + while (i2cState == I2C_STATE_BUSY_TX); + LL_I2C_DisableBitPOS(I2C1); + + i2cState = I2C_STATE_BUSY_TX; + /* Start */ + LL_I2C_GenerateStartCondition(I2C1); + while (LL_I2C_IsActiveFlag_SB(I2C1) != 1); + /* Send slave address */ + LL_I2C_TransmitData8(I2C1, (devAddress & (uint8_t)(~0x01))); + while(LL_I2C_IsActiveFlag_ADDR(I2C1) != 1); + LL_I2C_ClearFlag_ADDR(I2C1); + + /* Send memory address */ + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); +#if (AT24C_DATA_ADDR_LEN == AT24C_DATA_ADDR_8B) + LL_I2C_TransmitData8(I2C1, (uint8_t)(memAddress & 0x00FF)); +#elif (AT24C_DATA_ADDR_LEN == AT24C_DATA_ADDR_16B) + LL_I2C_TransmitData8(I2C1, (uint8_t)((memAddress & 0xFF00) >> 8)); + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); + + LL_I2C_TransmitData8(I2C1, (uint8_t)(memAddress & 0x00FF)); +#endif + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); + + /* Transfer data */ + while (len > 0) + { + while (LL_I2C_IsActiveFlag_TXE(I2C1) != 1); + LL_I2C_TransmitData8(I2C1, *pData++); + len--; + + if ((LL_I2C_IsActiveFlag_BTF(I2C1) == 1) && (len != 0U)) + { + LL_I2C_TransmitData8(I2C1, *pData++); + len--; + } + + while (LL_I2C_IsActiveFlag_BTF(I2C1) != 1); + } + + /* Stop */ + LL_I2C_GenerateStopCondition(I2C1); + i2cState = I2C_STATE_READY; +} + +uint8_t APP_I2C_ReceiveByte(uint16_t devAddress, uint16_t memAddress) +{ + uint8_t temp = 0; + + LL_I2C_DisableBitPOS(I2C1); + i2cState = I2C_STATE_BUSY_RX; + + /* Start */ + LL_I2C_GenerateStartCondition(I2C1); + while(LL_I2C_IsActiveFlag_SB(I2C1) != 1); + + /* Send slave address */ + LL_I2C_TransmitData8(I2C1, (devAddress & (uint8_t)(~0x01))); + while(LL_I2C_IsActiveFlag_ADDR(I2C1) != 1); + LL_I2C_ClearFlag_ADDR(I2C1); + + /* Send memory address */ + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); +#if (AT24C_DATA_ADDR_LEN == AT24C_DATA_ADDR_8B) + LL_I2C_TransmitData8(I2C1, (uint8_t)(memAddress & 0x00FF)); + +#elif (AT24C_DATA_ADDR_LEN == AT24C_DATA_ADDR_16B) + LL_I2C_TransmitData8(I2C1, (uint8_t)((memAddress & 0xFF00) >> 8)); + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); + + LL_I2C_TransmitData8(I2C1, (uint8_t)(memAddress & 0x00FF)); +#endif + while(LL_I2C_IsActiveFlag_TXE(I2C1) != 1); + + /* Start */ + LL_I2C_GenerateStartCondition(I2C1); + while(LL_I2C_IsActiveFlag_SB(I2C1) != 1); + + /* Send slave address(read) */ + LL_I2C_TransmitData8(I2C1, (devAddress | 0x1)); + while(LL_I2C_IsActiveFlag_ADDR(I2C1) != 1); + LL_I2C_ClearFlag_ADDR(I2C1); + + while(LL_I2C_IsActiveFlag_RXNE(I2C1) != 1); + LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_NACK); + temp = LL_I2C_ReceiveData8(I2C1); + LL_I2C_GenerateStopCondition(I2C1); + + i2cState = I2C_STATE_READY; + return temp; +} + +static void APP_SystemClockConfig(void) +{ + LL_UTILS_ClkInitTypeDef UTILS_ClkInitStruct; + + LL_RCC_HSI_Enable(); + /* Change this value to adjust frequency */ + LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz + 15); + while (LL_RCC_HSI_IsReady() != 1); + + UTILS_ClkInitStruct.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; + UTILS_ClkInitStruct.APB1CLKDivider = LL_RCC_APB1_DIV_1; + LL_PLL_ConfigSystemClock_HSI(&UTILS_ClkInitStruct); + + /* Re-init frequency of SysTick source, reload = freq/ticks = 48000000/1000 = 48000 */ + LL_InitTick(48000000, 1000U); +} +// static void APP_SystemClockConfig(void) +// { +// LL_RCC_HSI_Enable(); +// LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_8MHz); +// while(LL_RCC_HSI_IsReady() != 1); + +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + +// LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSISYS); +// while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS); + +// LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); + +// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); +// /* Update global SystemCoreClock(or through SystemCoreClockUpdate function) */ +// LL_SetSystemCoreClock(8000000); +// /* Re-init frequency of SysTick source, reload = freq/ticks = 48000000/1000 = 48000 */ +// LL_InitTick(8000000, 1000U); +// } + +void APP_ErrorHandler(void) +{ + while (1); +} + +#ifdef USE_FULL_ASSERT +void assert_failed(uint8_t *file, uint32_t line) +{ + while (1); +} +#endif /* USE_FULL_ASSERT */ diff --git a/Examples/LL/I2C/AT24C32/main.h b/Examples/LL/I2C/AT24C32/main.h new file mode 100644 index 0000000..6e3c2ea --- /dev/null +++ b/Examples/LL/I2C/AT24C32/main.h @@ -0,0 +1,27 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "py32f0xx_ll_bus.h" +#include "py32f0xx_ll_cortex.h" +#include "py32f0xx_ll_dma.h" +#include "py32f0xx_ll_exti.h" +#include "py32f0xx_ll_gpio.h" +#include "py32f0xx_ll_pwr.h" +#include "py32f0xx_ll_rcc.h" +#include "py32f0xx_ll_i2c.h" +#include "py32f0xx_ll_system.h" +#include "py32f0xx_ll_tim.h" +#include "py32f0xx_ll_utils.h" + + +void APP_ErrorHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Examples/LL/I2C/AT24C32/py32f0xx_it.c b/Examples/LL/I2C/AT24C32/py32f0xx_it.c new file mode 100644 index 0000000..3a10d14 --- /dev/null +++ b/Examples/LL/I2C/AT24C32/py32f0xx_it.c @@ -0,0 +1,40 @@ +#include "main.h" +#include "py32f0xx_it.h" + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ +} diff --git a/Examples/LL/I2C/AT24C32/py32f0xx_it.h b/Examples/LL/I2C/AT24C32/py32f0xx_it.h new file mode 100644 index 0000000..76b3dad --- /dev/null +++ b/Examples/LL/I2C/AT24C32/py32f0xx_it.h @@ -0,0 +1,19 @@ +#ifndef __PY32F0XX_IT_H +#define __PY32F0XX_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +void NMI_Handler(void); +void HardFault_Handler(void); +void SVC_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __PY32F0XX_IT_H */