Index

MicroWorks 30B4 board

  1. Datasheets 30B4
    1. STM32F103
      1. ADC
      2. STM32 EEPROM
    2. MPU6050
      1. DMA
      2. Issue communications
        1. 01
    3. MPU6050 freq
  2. firmware motor control
  3. Implementations with MicroWorks 30B4 board
  4. Links to sellers

MicroWorks 500W 30km/h motor

  1. BEMF measurements

Flash and Debug STM32

  1. Eclipse IDE and JTAG
  2. Unlock STM32F103 with JTAG
  3. Flash firmware using Bluetooth
    1. STM32F103C6T8 bootloader
    2. ZS-040 Bluetooth module
      1. HC-06 hc01.comV2.0
  4. Serial Port Bluetooth
  5. Serial Port Plot
  6. SM32F103C8T6 use 128kbytes flash

FOC

  1. Observer
  2. Shane Colton documentation and firmware
    1. Firmware
    2. Part 1: Field-Oriented
    3. Part 2: Field-Oriented
    4. Sensorless Pneu Scooter - part 1
    5. Sensorless Pneu Scooter - part 2
    6. Sensorless Pneu Scooter - part 3
  3. Texas Instruments videos
  4. Chinese controllers code

Balance controller

  1. Chinese balance group reference design
  2. Kerry D. Wong -- A Self-Balancing Robot
    1. A Self-Balancing Robot – I
    2. A Self-Balancing Robot – II
    3. A Self-Balancing Robot – III
  3. Self balance bicycle
  4. PID
  5. LQR
    1. Stages of development of the robot-balancer
  6. PID and LQR, MATLAB
  7. Steve Brunton videos

Mechanical parts

  1. Pedals

Various

  1. C language for critical systems
  2. Hall effect sensor placement
  3. The brilliant idea of slow rotating motors
    1. Why does the Torquemax rotate so slowly and so forcefully
  4. Finding Motor Phase-Sensor Combinations

Clipping

  1. Hackaday - 2017.05.07 - opensource firmware for hoverboards

01

https://electronics.stackexchange.com/questions/267972/i2c-busy-flag-strange-behaviour

ST has released an errata sheet called:
STM32F100xC, STM32F10 0xD and STM32F100xE high-density value line device limitations
http://www.st.com/content/ccc/resource/technical/document/errata_sheet/7f/05/b0/bc/34/2f/4c/21/CD00288116.pdf/files/CD00288116.pdf/jcr:content/translations/en.CD00288116.pdf
The interesting point here is:
2.9.7 I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry
There is a detailed 15 step workaround that worked for me, surprisingly for an STM32F446, so I2C peripherals of every STM32 CORTEX-M series might be affected.
During this operation, the lines must not be actively pulled up or down by a bus member. So if you connect two I2C interfaces of the same MCU to the bus, first set up the pins of both to Alternate Function/Open Drain, then call the routine, as a transition of logical levels is required.
Here is an example with HAL libraries I use after the first initialization and during runtime, if an error occurs. As said above, this is for STM32F4, libraries for SMT32F1 might differ a bit.

struct I2C_Module
{
I2C_HandleTypeDef instance;
uint16_t sdaPin;
GPIO_TypeDef* sdaPort;
uint16_t sclPin;
GPIO_TypeDef* sclPort;
};

void I2C_ClearBusyFlagErratum(struct I2C_Module* i2c)
{
GPIO_InitTypeDef GPIO_InitStructure;

// 1. Clear PE bit.
i2c->instance.Instance->CR1 &= ~(0x0001);

// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Alternate = I2C_PIN_MAP;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

GPIO_InitStructure.Pin = i2c->sclPin;
HAL_GPIO_Init(i2c->sclPort, &GPIO_InitStructure);
HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET);

GPIO_InitStructure.Pin = i2c->sdaPin;
HAL_GPIO_Init(i2c->sdaPort, &GPIO_InitStructure);
HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET);

// 3. Check SCL and SDA High level in GPIOx_IDR.
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(i2c->sclPort, i2c->sclPin))
{
asm("nop");
}

while (GPIO_PIN_SET != HAL_GPIO_ReadPin(i2c->sdaPort, i2c->sdaPin))
{
asm("nop");
}

// 4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_RESET);

// 5. Check SDA Low level in GPIOx_IDR.
while (GPIO_PIN_RESET != HAL_GPIO_ReadPin(i2c->sdaPort, i2c->sdaPin))
{
asm("nop");
}

// 6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_RESET);

// 7. Check SCL Low level in GPIOx_IDR.
while (GPIO_PIN_RESET != HAL_GPIO_ReadPin(i2c->sclPort, i2c->sclPin))
{
asm("nop");
}

// 8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET);

// 9. Check SCL High level in GPIOx_IDR.
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(i2c->sclPort, i2c->sclPin))
{
asm("nop");
}

// 10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET);

// 11. Check SDA High level in GPIOx_IDR.
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(i2c->sdaPort, i2c->sdaPin))
{
asm("nop");
}

// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
GPIO_InitStructure.Alternate = I2C_PIN_MAP;

GPIO_InitStructure.Pin = i2c->sclPin;
HAL_GPIO_Init(i2c->sclPort, &GPIO_InitStructure);

GPIO_InitStructure.Pin = i2c->sdaPin;
HAL_GPIO_Init(i2c->sdaPort, &GPIO_InitStructure);

// 13. Set SWRST bit in I2Cx_CR1 register.
i2c->instance.Instance->CR1 |= 0x8000;

asm("nop");

// 14. Clear SWRST bit in I2Cx_CR1 register.
i2c->instance.Instance->CR1 &= ~0x8000;

asm("nop");

// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
i2c->instance.Instance->CR1 |= 0x0001;

// Call initialization function.
HAL_I2C_Init(&(i2c->instance));
}