#include <AP_HAL.h>
#include "I2CDriver.h"
extern const AP_HAL::HAL& hal;
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
((PERIPH) == GPIOB) || \
((PERIPH) == GPIOC) || \
((PERIPH) == GPIOD) || \
((PERIPH) == GPIOE) || \
((PERIPH) == GPIOF) || \
((PERIPH) == GPIOG) || \
((PERIPH) == GPIOH) || \
((PERIPH) == GPIOI))
typedef enum
{
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode 输入模式*/
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode 输出模式*/
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode 复用模式*/
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode 模拟输入模式*/
}GPIOMode_TypeDef;
typedef enum
{
GPIO_OType_PP = 0x00,/*推挽输出方式,不用接上拉电阻,驱动能力大,可以直接输出单片机高电平,低电平时接地,不可直接接地,否则高电平输出时会使单片机运行不稳定甚至烧坏引脚*/
GPIO_OType_OD = 0x01/*开漏输出方式,不输出电压,低电平时接地,高电平时不接地,如有上拉电阻,高电平时电压会上拉到电阻的电源电压*/
}GPIOOType_TypeDef;
#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))
typedef enum
{
GPIO_Speed_2MHz = 0x00, /*!< Low speed 低速模式*/
GPIO_Speed_25MHz = 0x01, /*!< Medium speed 中速模式*/
GPIO_Speed_50MHz = 0x02, /*!< Fast speed 快速模式*/
GPIO_Speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF)高速模式 */
}GPIOSpeed_TypeDef;
typedef enum
{
GPIO_PuPd_NOPULL = 0x00,/*无上下拉,浮空模式*/
GPIO_PuPd_UP = 0x01,/*上拉*/
GPIO_PuPd_DOWN = 0x02/*下拉*/
}GPIOPuPd_TypeDef;
#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \
((PUPD) == GPIO_PuPd_DOWN))
using namespace STM32F4xx;
//static uint8_t fac_us=0;
//static uint16_t fac_ms=0;
void STM32F4xx_I2CDriver::init()
{
GPIO_TypeDef* GPIOx = GPIOB;
RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOBEN);
// GPIOSpeed_TypeDef GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_InitStructure.Pin = GPIO_PIN_8|GPIO_PIN_9 ;
//****************有毛病
//uint32_t GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9;
//********************
GPIOMode_TypeDef GPIO_Mode = GPIO_Mode_OUT;
GPIOSpeed_TypeDef GPIO_Speed = GPIO_Speed_50MHz;
GPIOOType_TypeDef GPIO_OType = GPIO_OType_PP;
/*
if(active){
GPIO_Speed = GPIO_Speed_100MHz;
}
else{
GPIO_Speed = GPIO_Speed_50MHz;
}
*/
GPIOPuPd_TypeDef GPIO_PuPd = GPIO_PuPd_UP;
uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
//assert_param(IS_GPIO_PIN(GPIO_Pin1));
//assert_param(IS_GPIO_PIN(GPIO_Pin2));
assert_param(IS_GPIO_MODE(GPIO_Mode));
assert_param(IS_GPIO_PUPD(GPIO_PuPd));
//for (pinpos = 0x00; pinpos < 0x10; pinpos++)
//{
//pos = ((uint32_t)0x01) << pinpos;
/* Get the port pins position */
// currentpin = (GPIO_Pin) & pos;
// if (currentpin == pos)
//{
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (8 * 2));
GPIOx->MODER |= (((uint32_t)GPIO_Mode) << (8 * 2));
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (9 * 2));
GPIOx->MODER |= (((uint32_t)GPIO_Mode) << (9 * 2));
//if ((GPIO_Mode == GPIO_Mode_OUT) || (GPIO_Mode == GPIO_Mode_AF))
//{
/* Check Speed mode parameters */
//assert_param(IS_GPIO_SPEED(GPIO_Speed));
/* Speed mode configuration */
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (8 * 2));
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (8 * 2));
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (9 * 2));
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (9 * 2));
/* Check Output mode parameters */
assert_param(IS_GPIO_OTYPE(GPIO_OType));
/* Output mode configuration*/
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)8)) ;
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_OType) << ((uint16_t)8));
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)9)) ;
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_OType) << ((uint16_t)9));
//}
/* Pull-up Pull down resistor configuration*/
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)8 * 2));
GPIOx->PUPDR |= (((uint32_t)GPIO_PuPd) << (8 * 2));
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)9 * 2));
GPIOx->PUPDR |= (((uint32_t)GPIO_PuPd) << (9 * 2));
//}
// }
//GPIO_Init(GPIOB, &GPIO_InitStructure);
//IIC1_SCL=1;
IIC_SCL(1);
//IIC1_SDAOUT=1;
IIC_SDAOUT(1);
}
//没毛病
void STM32F4xx_I2CDriver::begin() {
SDA_OUT();
IIC_SDAOUT(1);
IIC_SCL(1);
setTimeout(4);
IIC_SDAOUT(0);
setTimeout(4);
IIC_SCL(0);
}
//没毛病
void STM32F4xx_I2CDriver::end() {
SDA_OUT();
IIC_SCL(0);
IIC_SDAOUT(0);
setTimeout(4);
IIC_SCL(1);
setTimeout(4);
IIC_SDAOUT(1);
//setTimeout(4);
}
/*
void MCU_Send_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDAOUT=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
void MCU_NOAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDAOUT=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}*/
void STM32F4xx_I2CDriver::setTimeout(uint32_t ms) {
//delay_us();
//SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource_HCLK_Div8));
// if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
// {
// SysTick->CTRL |= SysTick_CLKSource_HCLK;
//}
//else
//{
/*
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
//}
fac_us=SYSCLK/8;
fac_ms=(uint16_t)fac_us*1000;
uint32_t midtime;
SysTick->LOAD=ms*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
midtime=SysTick->CTRL;
}
while((midtime&0x01)&&!(midtime&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
*/
// uint32_t start = _timer.millis();
// while (ms > 0) {
// while ((_timer.micros() - start) >= 1000) {
// while ((_timer.millis() - start) >= 1) {
// ms--;
// if (ms == 0) break;
// start += 1000;
// start += 1;
// }
// if (_min_delay_cb_ms <= ms) {
// if (_delay_cb) {
// _delay_cb();
// }
// }
// }
hal.scheduler->delay(ms);
}
void STM32F4xx_I2CDriver::setHighSpeed(bool active) {
if(active){
GPIOSpeed_TypeDef GPIO_Speed = GPIO_Speed_100MHz;
GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (8 * 2));
GPIOB->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (8 * 2));
GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (9 * 2));
GPIOB->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (9 * 2));
}
else{
GPIOSpeed_TypeDef GPIO_Speed = GPIO_Speed_50MHz;
GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (8 * 2));
GPIOB->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (8 * 2));
GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (9 * 2));
GPIOB->OSPEEDR |= ((uint32_t)(GPIO_Speed) << (9 * 2));
}
}
uint8_t STM32F4xx_I2CDriver::write(uint8_t addr, uint8_t len, uint8_t* data)
{
uint8_t t, y;
uint8_t WaitTime = 0;
for (t = 0; t < 8; t++) {
IIC_SDAOUT(((addr & 0x80) >> 7)) ;
addr <<= 1;
setTimeout(4);
IIC_SCL(1);
setTimeout(4);
IIC_SCL(0);
}
IIC_SDAOUT(1);
SDA_IN();
setTimeout(4);
IIC_SCL(1);
//setTimeout(4);
while (IIC_SDAIN) {
WaitTime++;
if (WaitTime > 250) {
end();
return 1;
}
}
IIC_SCL(0);
setTimeout(3);
///