9 changed files with 224 additions and 60 deletions
@ -0,0 +1,46 @@ |
|||
/*
|
|||
* dac101c085.c |
|||
* |
|||
* Created on: 21 Jul 2019 |
|||
* Author: maximilian |
|||
*/ |
|||
|
|||
#include "dac101c085.h" |
|||
|
|||
static uint8_t i2c_initialized = 0; |
|||
|
|||
void init(void) |
|||
{ |
|||
if (!i2c_initialized) { |
|||
i2cInit(I2Cx_DAC); |
|||
i2c_initialized = 1; |
|||
} |
|||
} |
|||
|
|||
void setDAC(uint16_t new_value) |
|||
{ |
|||
uint8_t ub = (new_value >> 6) & 0x0F; |
|||
//uint8_t ub = 0x10;
|
|||
uint8_t lb = (new_value << 2) & 0xFF; |
|||
init(); |
|||
osPrintf("Upper %d\n", ub); |
|||
osPrintf("Lower %d\n", lb); |
|||
i2cStartTransmission(I2Cx_DAC, I2C_Direction_Transmitter, DAC_ADDR); |
|||
i2cWrite(I2Cx_DAC, &ub); |
|||
i2cWrite(I2Cx_DAC, &lb); |
|||
i2cEndTransmission(I2Cx_DAC); |
|||
} |
|||
|
|||
uint16_t readDAC(void) |
|||
{ |
|||
uint16_t dac_val = 1; |
|||
i2cStartTransmission(I2Cx_DAC, I2C_Direction_Receiver, DAC_ADDR); |
|||
i2cAckOn(I2Cx_DAC); |
|||
dac_val = i2cRead(I2Cx_DAC); |
|||
i2cAckOff(I2Cx_DAC); |
|||
dac_val = (dac_val<<8); |
|||
dac_val |= i2cRead(I2Cx_DAC); |
|||
i2cEndTransmission(I2Cx_DAC); |
|||
return dac_val>>2; |
|||
} |
|||
|
@ -0,0 +1,32 @@ |
|||
/*
|
|||
* dac101c085.h |
|||
* |
|||
* Created on: 21 Jul 2019 |
|||
* Author: maximilian |
|||
*/ |
|||
|
|||
#ifndef DRIVERS_DAC101C085_H_ |
|||
#define DRIVERS_DAC101C085_H_ |
|||
|
|||
#include <stdlib.h> |
|||
#include "../platform/i2c.h" |
|||
#include "../os/error.h" |
|||
|
|||
#define DAC_ADDR 78 |
|||
#define I2Cx_DAC I2C1 |
|||
|
|||
/** Enum for power down mode.
|
|||
* |
|||
*/ |
|||
typedef enum |
|||
{ |
|||
S_PD_2K5, |
|||
S_PD_100K, |
|||
S_HIGH_IMP |
|||
} powerDown_t; |
|||
|
|||
void setDAC(uint16_t new_value); |
|||
uint16_t readDAC(void); |
|||
void powerDown(powerDown_t state); |
|||
|
|||
#endif /* DRIVERS_DAC101C085_H_ */ |
@ -1,48 +1,121 @@ |
|||
#include <stm32f10x_i2c.h> |
|||
#include "i2c.h" |
|||
#include "stm32f10x_i2c.h" |
|||
#include "stm32f10x_gpio.h" |
|||
#include "porting.h" |
|||
|
|||
void initI2C(I2C_TypeDef* i2cx , uint32_t speed, uint16_t own_address) |
|||
void i2cInit(I2C_TypeDef* I2Cx) |
|||
{ |
|||
GPIO_InitTypeDef GPIO_InitStructure; |
|||
I2C_InitTypeDef I2C_InitStructure; |
|||
// Enable GPIOB clocks
|
|||
if (I2Cx == I2C1) { |
|||
i2c1Init(); |
|||
} |
|||
else { |
|||
THROW_ERROR(E_I2C_NON_EXISTANT); |
|||
} |
|||
} |
|||
|
|||
void i2c1Init(void) |
|||
{ |
|||
// Initialization structs
|
|||
GPIO_InitTypeDef i2c_gpio; |
|||
I2C_InitTypeDef i2c; |
|||
// Turn on clocks
|
|||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); |
|||
// Configure I2C clock and GPIO
|
|||
GPIO_StructInit (& GPIO_InitStructure); |
|||
if (i2cx == I2C1){ |
|||
// I2C1 clock enable
|
|||
RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C1 , ENABLE); |
|||
// I2C1 SDA and SCL configuration
|
|||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ; |
|||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ; |
|||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ; |
|||
GPIO_Init(GPIOB, &GPIO_InitStructure ); |
|||
// I2C1 Reset
|
|||
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); |
|||
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); |
|||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); |
|||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); |
|||
//Configure I2C module
|
|||
i2c.I2C_ClockSpeed = 100000; |
|||
i2c.I2C_Mode = I2C_Mode_I2C; |
|||
i2c.I2C_DutyCycle = I2C_DutyCycle_2; |
|||
i2c.I2C_OwnAddress1 = 0x15; |
|||
i2c.I2C_Ack = I2C_Ack_Enable; |
|||
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
|||
I2C_Init(I2C1, &i2c); |
|||
//Additionally we need to initialize corresponding GPIOs
|
|||
i2c_gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; |
|||
i2c_gpio.GPIO_Mode = GPIO_Mode_AF_OD; // Open drain only if you have pull-up resistors
|
|||
i2c_gpio.GPIO_Speed = GPIO_Speed_50MHz; |
|||
GPIO_Init(GPIOB, &i2c_gpio); |
|||
// Enable I2C 1
|
|||
I2C_Cmd(I2C1, ENABLE); |
|||
DEBUG_MSG("I2C1 initialized."); |
|||
} |
|||
|
|||
uint8_t i2cPing(I2C_TypeDef* I2Cx, uint8_t slave_addr) |
|||
{ |
|||
DEBUG_MSG("Searching for: %d\n", slave_addr); |
|||
// Wait until I2Cx is not busy anymore
|
|||
while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); |
|||
// Generate start condition
|
|||
I2C_GenerateSTART(I2Cx, ENABLE); |
|||
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); |
|||
// Send slave address
|
|||
I2C_Send7bitAddress(I2Cx, slave_addr<<1, I2C_Direction_Transmitter); |
|||
// Wait for I2C EV5.
|
|||
volatile uint32_t timeout = 0xFFFF; |
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { |
|||
if (timeout == 0) { |
|||
break; |
|||
} else { |
|||
timeout--; |
|||
} |
|||
else { // I2C2 ...
|
|||
} |
|||
// I2C configuration
|
|||
I2C_StructInit(&I2C_InitStructure); |
|||
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; |
|||
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; |
|||
I2C_InitStructure.I2C_OwnAddress1 = own_address; |
|||
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; |
|||
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
|||
I2C_InitStructure.I2C_ClockSpeed = speed; |
|||
I2C_Init(i2cx, &I2C_InitStructure); |
|||
I2C_Cmd(i2cx, ENABLE); |
|||
} |
|||
|
|||
//uint8_t pingI2C (I2C_TypeDef* i2cx, uint8_t SlaveAddress)
|
|||
//{
|
|||
// __IO uint32_t Timeout = 0;
|
|||
// Timed ( I2C_GetFlagStatus (I2Cx , I2C_FLAG_BUSY ));
|
|||
// // Intiate Start Sequence
|
|||
// I2C_GenerateSTART (I2Cx , ENABLE );
|
|||
// Timed (! I2C_CheckEvent (I2Cx , I2C_EVENT_MASTER_MODE_SELECT));
|
|||
// // Send Address EV5
|
|||
// I2C_Send7bitAddress (I2Cx , SlaveAddress, I2C_Direction_Transmitter);
|
|||
// Timed (! I2C_CheckEvent (I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
|
|||
// return 0;
|
|||
//}
|
|||
I2C_GenerateSTOP(I2Cx, ENABLE); |
|||
if (timeout > 0) { |
|||
DEBUG_MSG("Slave found\n\r"); |
|||
return 1; |
|||
} else { |
|||
DEBUG_MSG("Slave not found\n\r"); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
void i2cStartTransmission(I2C_TypeDef* I2Cx, uint8_t dir, uint8_t slave_addr) |
|||
{ |
|||
// Wait for I2C module to become ready
|
|||
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); |
|||
// Generate I2C start condition
|
|||
I2C_GenerateSTART(I2Cx, ENABLE); |
|||
// Waiting for EV5
|
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); |
|||
// The 7 bit address needs to be shifted by 1
|
|||
I2C_Send7bitAddress(I2Cx, slave_addr<<1, dir); |
|||
// Depending on whether the master is reading or writing another event is triggered
|
|||
if(dir== I2C_Direction_Transmitter) |
|||
{ |
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); |
|||
} |
|||
if(dir== I2C_Direction_Receiver) |
|||
{ |
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); |
|||
} |
|||
} |
|||
|
|||
void i2cWrite(I2C_TypeDef* I2Cx, uint8_t* data) |
|||
{ |
|||
I2C_SendData(I2Cx, *data); |
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); |
|||
//while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF));
|
|||
} |
|||
|
|||
void i2cAckOn(I2C_TypeDef* I2Cx) |
|||
{ |
|||
I2C_AcknowledgeConfig(I2Cx, ENABLE); |
|||
} |
|||
|
|||
void i2cAckOff(I2C_TypeDef* I2Cx) |
|||
{ |
|||
I2C_AcknowledgeConfig(I2Cx, DISABLE); |
|||
} |
|||
|
|||
uint8_t i2cRead(I2C_TypeDef* I2Cx) |
|||
{ |
|||
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); |
|||
uint8_t data = I2C_ReceiveData(I2Cx); |
|||
return data; |
|||
} |
|||
|
|||
void i2cEndTransmission(I2C_TypeDef* I2Cx) |
|||
{ |
|||
I2C_GenerateSTOP(I2Cx, ENABLE); |
|||
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)); |
|||
} |
|||
|
Loading…
Reference in new issue