27#include "mcci_bootloader_device_internal.h"
39#ifndef MCCI_BOOTLOADER_STM32L0_I2C_TIME_OUT_MS
40# define MCCI_BOOTLOADER_STM32L0_I2C_TIME_OUT_MS 100
43typedef enum McciBootloaderI2cBusStm32l0_Status_e
66McciBootloaderDeviceI2cResult_t
195McciBootloaderDeviceI2cBus_t *
199 const McciBootloaderDeviceI2cBusStm32l0_Config_t *pConfig,
200 uint32_t timingr100k,
201 uint32_t timingr400k,
206 if (sizeForBus <
sizeof(McciBootloaderDeviceI2cBusStm32l0_t))
224 memset(pRamForBus, 0, sizeForBus);
227 McciBootloaderDeviceI2cBusStm32l0_t *
const pI2cBus = pRamForBus;
231 pI2cBus->Stm32l0.pConfig = pConfig;
232 pI2cBus->Stm32l0.timingr[McciBootloaderDeviceI2cSpeed_100k] = timingr100k;
233 pI2cBus->Stm32l0.timingr[McciBootloaderDeviceI2cSpeed_400k] = timingr400k;
234 pI2cBus->Stm32l0.timingr[McciBootloaderDeviceI2cSpeed_1M] = timingr1M;
237 if (! McciBootloaderDevice_begin(&pI2cBus->DeviceCast))
240 return &pI2cBus->I2cBusCast;
271 McciBootloaderDevice_t *pDevice
275 uint32_t
const baseAddress = pI2cBus->Stm32l0.pConfig->baseAddress;
278 if (pI2cBus->Stm32l0.pConfig->CCIPR_select.mask != 0)
282 pI2cBus->Stm32l0.pConfig->CCIPR_select.mask,
283 pI2cBus->Stm32l0.pConfig->CCIPR_select.value
290 pI2cBus->Stm32l0.pConfig->APB1ENR_mask
296 pI2cBus->Stm32l0.pConfig->APB1RSTR_mask
302 pI2cBus->Stm32l0.pConfig->APB1RSTR_mask
308 pI2cBus->Stm32l0.timingr[McciBootloaderDeviceI2cSpeed_100k]
342 McciBootloaderDevice_t *pDevice
351 pI2cBus->Stm32l0.pConfig->APB1RSTR_mask
357 pI2cBus->Stm32l0.pConfig->APB1RSTR_mask
363 pI2cBus->Stm32l0.pConfig->APB1ENR_mask
369static McciBootloaderDeviceI2cResult_t
371 McciBootloaderDeviceI2cBus_t *pBus,
372 McciBootloaderDeviceI2cDevice_t *pDevice,
378 const size_t nBuffer_orig = nBuffer;
380 uint32_t
const baseAddress = pI2cBus->Stm32l0.pConfig->baseAddress;
383 McciBootloaderDeviceI2cAddress_t
const i2cAddress = pDevice->I2cDevice.address;
384 McciBootloaderDeviceI2cSpeed_t
const bSpeed = pDevice->I2cDevice.bSpeed;
386 if (pnActual == NULL)
387 return McciBootloaderDeviceI2cResult_InvalidParameter;
392 return McciBootloaderDeviceI2cResult_InvalidParameter;
409 pI2cBus->Stm32l0.timingr[bSpeed]
454 ++pBuffer, --nBuffer;
491 *pnActual = nBuffer_orig - nBuffer;
495static McciBootloaderDeviceI2cResult_t
497 McciBootloaderDeviceI2cBus_t *pBus,
498 McciBootloaderDeviceI2cDevice_t *pDevice,
499 const uint8_t *pBuffer,
504 const size_t nBuffer_orig = nBuffer;
506 uint32_t
const baseAddress = pI2cBus->Stm32l0.pConfig->baseAddress;
509 McciBootloaderDeviceI2cAddress_t
const i2cAddress = pDevice->I2cDevice.address;
510 McciBootloaderDeviceI2cSpeed_t
const bSpeed = pDevice->I2cDevice.bSpeed;
512 if (pnActual == NULL)
513 return McciBootloaderDeviceI2cResult_InvalidParameter;
518 return McciBootloaderDeviceI2cResult_InvalidParameter;
534 pI2cBus->Stm32l0.timingr[bSpeed]
654 ++pBuffer, --nBuffer;
671 *pnActual = nBuffer_orig - nBuffer;
676McciBootloaderDeviceI2cResult_t
681 static const uint8_t k_map[] =
696 if (status < MCCIADK_LENOF(k_map))
697 return k_map[status];
699 return McciBootloaderDeviceI2cResult_InternalError;
732static McciBootloaderDeviceI2cResult_t
734 McciBootloaderDeviceI2cBus_t *pBusAbstract,
735 McciBootloaderDeviceI2cDevice_t *pDeviceAbstract,
737 McciBootloaderDeviceI2cAddress_t i2cAddress,
738 McciBootloaderDeviceI2cSpeed_t i2cSpeed
741 McciBootloaderDeviceI2cBusStm32l0_t *
const pBus =
743 McciBootloaderDeviceI2cDeviceStm32l0_t *
const pDevice =
746 if (pDevice == NULL || sizeDevice <
sizeof(*pDevice))
747 return McciBootloaderDeviceI2cResult_InvalidParameter;
749 memset(pDevice, 0,
sizeof(*pDevice));
751 if (i2cSpeed >= MCCIADK_LENOF(pBus->Stm32l0.timingr))
752 return McciBootloaderDeviceI2cResult_InvalidParameter;
759 return McciBootloaderDeviceI2cResult_InternalError;
764 if (i2cAddress >= 0x80)
767 return McciBootloaderDeviceI2cResult_InvalidParameter;
777 pDevice->I2cDevice.address = i2cAddress;
778 pDevice->I2cDevice.bSpeed = i2cSpeed;
779 pDevice->I2cDevice.pBus = &pBus->I2cBusCast;
781 return McciBootloaderDeviceI2cResult_OK;
784static McciBootloaderDeviceI2cResult_t
786 McciBootloaderDeviceI2cDevice_t *pI2cDevice,
792 return (*pI2cDevice->I2cDevice.pBus->I2cBus.pMethods->pRead)(
793 pI2cDevice->I2cDevice.pBus,
801static McciBootloaderDeviceI2cResult_t
803 McciBootloaderDeviceI2cDevice_t *pI2cDevice,
804 const uint8_t *pBuffer,
809 return (*pI2cDevice->I2cDevice.pBus->I2cBus.pMethods->pWrite)(
810 pI2cDevice->I2cDevice.pBus,
static uint32_t McciArm_putRegOr(uint32_t reg, uint32_t orVal)
or 32-bit values to a cm0plus register
static uint32_t McciArm_getReg(uint32_t reg)
read a 32-bit value from a cm0plus register
static uint32_t McciArm_putReg(uint32_t reg, uint32_t val)
write a 32-bit value to a cm0plus register
static uint32_t McciArm_putRegClear(uint32_t reg, uint32_t clearVal)
clear out 32-bit values to a cm0plus register
static uint32_t McciArm_putRegMasked(uint32_t reg, uint32_t maskVal, uint32_t modVal)
store to cm0plus register under mask
@ McciBootloaderError_I2cBegin
I2c bus failed begin.
@ McciBootloaderError_InternalConsistency
an internal consistency check failed.
#define MCCI_BOOTLOADER_FIELD_SET_VALUE(fmask, val)
static McciBootloaderDeviceI2cBusStm32l0_t * McciBootloaderDeviceI2cBus_getI2cBusStm32l0(McciBootloaderDeviceI2cBus_t *pDevice)
upcast from i2c controller device to enclosing McciBootloaderDeviceI2cBusStm32l0_t
#define MCCI_BOOTLOADER_STM32L0_I2C_TIMINGR_NOT_SUPPORTED
value to use for timing parameters when a speed is not supported.
static McciBootloaderDeviceI2cBusStm32l0_t * McciBootloaderDevice_getI2cBusStm32l0(McciBootloaderDevice_t *pDevice)
upcast from device to enclosing McciBootloaderDeviceI2cBusStm32l0_t
static McciBootloaderDeviceI2cDeviceStm32l0_t * McciBootloaderDeviceI2cDevice_getI2cDeviceStm32l0(McciBootloaderDeviceI2cDevice_t *pDevice)
upcast from i2c controller device to enclosing McciBootloaderDeviceI2cDeviceStm32l0_t
uint32_t McciBootloader_Milliseconds_t
Time (in milliseconds)
#define MCCI_STM32L0_REG_RCC_APB1RSTR_I2C1RST
#define MCCI_STM32L0_I2C_CR2_NBYTES
number of bytes [7:0]
#define MCCI_STM32L0_REG_RCC_APB1RSTR_I2C2RST
#define MCCI_STM32L0_I2C_ISR_BERR
bus error
#define MCCI_STM32L0_REG_RCC_CCIPR_I2C3SEL
#define MCCI_STM32L0_REG_I2C2
Section 27.7.12: I2C register map (1K)
#define MCCI_STM32L0_REG_RCC_APB1ENR_I2C3EN
#define MCCI_STM32L0_I2C_ISR_STOPF
STOP detection flag.
#define MCCI_STM32L0_I2C_TXDR
Section 27.7.11: transmit data register.
#define MCCI_STM32L0_REG_RCC_APB1RSTR
APB1 peripheral reset.
#define MCCI_STM32L0_I2C_ISR_BUSY
bus busy
#define MCCI_STM32L0_REG_RCC_CCIPR_I2C3SEL_HSI16
#define MCCI_STM32L0_REG_RCC_CCIPR_I2C1SEL_HSI16
#define MCCI_STM32L0_I2C_CR2_AUTOEND
automatic end mode (master)
#define MCCI_STM32L0_REG_I2C3
Section 27.7.12: I2C register map (1K)
#define MCCI_STM32L0_REG_RCC_CCIPR
Clock configuration CCIPR.
#define MCCI_STM32L0_I2C_RXDR
Section 27.7.10: receive data register.
#define MCCI_STM32L0_I2C_CR1
Section 27.7.1: control register 1.
#define MCCI_STM32L0_I2C_TIMINGR
Section 27.7.5: timing register.
#define MCCI_STM32L0_REG_RCC_APB1ENR_I2C2EN
#define MCCI_STM32L0_REG_RCC_APB1RSTR_I2C3RST
#define MCCI_STM32L0_I2C_ISR_ARLO
arbitration lost
#define MCCI_STM32L0_REG_RCC_APB1ENR_I2C1EN
#define MCCI_STM32L0_I2C_ISR_RXNE
receive data register not empty
#define MCCI_STM32L0_I2C_ISR
Section 27.7.7: interrupt and status register.
#define MCCI_STM32L0_I2C_CR2_SADD
slave address [9:0]
#define MCCI_STM32L0_I2C_CR2
Section 27.7.2: control register 2.
#define MCCI_STM32L0_I2C_CR2_START
START generation.
#define MCCI_STM32L0_I2C_CR2_RD_WRN
transfer direction: 1=read, 0=write
#define MCCI_STM32L0_I2C_CR1_PE
peripheral enable
#define MCCI_STM32L0_I2C_ISR_NACKF
not acknowledge received flag
#define MCCI_STM32L0_I2C_ISR_TXE
transmit data register empty
#define MCCI_STM32L0_REG_RCC_APB1ENR
APB1 peripheral clock enable.
#define MCCI_STM32L0_REG_RCC_CCIPR_I2C1SEL
#define MCCI_STM32L0_REG_I2C1
Section 27.7.12: I2C register map (1K)
static McciBootloaderDeviceI2cDevice_ReadFn_t i2cDeviceRead
static const McciBootloaderDeviceMethods_t i2cDevice_deviceMethods
I2C device node methods.
const McciBootloaderDeviceI2cBusStm32l0_Config_t gk_McciBootloaderDeviceI2cBusStm32l0_Config_I2c2
global config for I2C2. Linker discards this if not used.
const McciBootloaderDeviceI2cBusStm32l0_Config_t gk_McciBootloaderDeviceI2cBusStm32l0_Config_I2c3
global config for I2C3. Linker discards this if not used.
#define MCCI_BOOTLOADER_STM32L0_I2C_TIME_OUT_MS
static McciBootloaderDevice_BeginFn_t i2cBusBegin
static McciBootloaderDeviceI2cResult_t status_getResult(McciBootloaderI2cBusStm32l0_Status_t status)
static const McciBootloaderDeviceMethods_t i2cBus_deviceMethods
McciBootloaderI2cBusStm32l0_Status_t
@ McciBootloaderI2cBusStm32l0_Status_Done
@ McciBootloaderI2cBusStm32l0_Status_Timeout
@ McciBootloaderI2cBusStm32l0_Status_ArbitrationLost
@ McciBootloaderI2cBusStm32l0_Status_Busy
@ McciBootloaderI2cBusStm32l0_Status_NotBusy
@ McciBootloaderI2cBusStm32l0_Status_BusError
@ McciBootloaderI2cBusStm32l0_Status_Stopped
@ McciBootloaderI2cBusStm32l0_Status_NackError
@ McciBootloaderI2cBusStm32l0_Status__MAX
muat always be last, for error checking.
static McciBootloaderDeviceI2cBus_WriteFn_t i2cBusWrite
static McciBootloaderDeviceI2cBus_ReadFn_t i2cBusRead
static McciBootloaderDeviceI2cDevice_WriteFn_t i2cDeviceWrite
static McciBootloaderDeviceI2cBus_AddDeviceFn_t i2cBusAddDevice
static McciBootloaderDevice_EndFn_t i2cBusEnd
static const McciBootloaderDeviceI2cBusMethods_t i2cBus_i2cBusMethods
static const McciBootloaderDeviceI2cDeviceMethods_t i2cDevice_i2cDeviceMethods
I2C device accessor methods.
McciBootloaderDeviceI2cBus_t * McciBootloader_Stm32L0Interface_initI2cBus(void *pRamForBus, size_t sizeForBus, const McciBootloaderDeviceI2cBusStm32l0_Config_t *pConfig, uint32_t timingr100k, uint32_t timingr400k, uint32_t timingr1M)
Initialize an I2C bus controller driver on an STM32L0.
const McciBootloaderDeviceI2cBusStm32l0_Config_t gk_McciBootloaderDeviceI2cBusStm32l0_Config_I2c1
global config for I2C1. Linker discards this if not used.