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; |
if (I2Cx == I2C1) { |
||||
I2C_InitTypeDef I2C_InitStructure; |
i2c1Init(); |
||||
// Enable GPIOB clocks
|
} |
||||
|
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); |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); |
||||
// Configure I2C clock and GPIO
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); |
||||
GPIO_StructInit (& GPIO_InitStructure); |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); |
||||
if (i2cx == I2C1){ |
//Configure I2C module
|
||||
// I2C1 clock enable
|
i2c.I2C_ClockSpeed = 100000; |
||||
RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C1 , ENABLE); |
i2c.I2C_Mode = I2C_Mode_I2C; |
||||
// I2C1 SDA and SCL configuration
|
i2c.I2C_DutyCycle = I2C_DutyCycle_2; |
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ; |
i2c.I2C_OwnAddress1 = 0x15; |
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ; |
i2c.I2C_Ack = I2C_Ack_Enable; |
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ; |
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
||||
GPIO_Init(GPIOB, &GPIO_InitStructure ); |
I2C_Init(I2C1, &i2c); |
||||
// I2C1 Reset
|
//Additionally we need to initialize corresponding GPIOs
|
||||
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); |
i2c_gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; |
||||
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); |
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_GenerateSTOP(I2Cx, ENABLE); |
||||
I2C_StructInit(&I2C_InitStructure); |
if (timeout > 0) { |
||||
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; |
DEBUG_MSG("Slave found\n\r"); |
||||
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; |
return 1; |
||||
I2C_InitStructure.I2C_OwnAddress1 = own_address; |
} else { |
||||
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; |
DEBUG_MSG("Slave not found\n\r"); |
||||
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
} |
||||
I2C_InitStructure.I2C_ClockSpeed = speed; |
return 0; |
||||
I2C_Init(i2cx, &I2C_InitStructure); |
} |
||||
I2C_Cmd(i2cx, ENABLE); |
|
||||
} |
void i2cStartTransmission(I2C_TypeDef* I2Cx, uint8_t dir, uint8_t slave_addr) |
||||
|
{ |
||||
//uint8_t pingI2C (I2C_TypeDef* i2cx, uint8_t SlaveAddress)
|
// Wait for I2C module to become ready
|
||||
//{
|
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); |
||||
// __IO uint32_t Timeout = 0;
|
// Generate I2C start condition
|
||||
// Timed ( I2C_GetFlagStatus (I2Cx , I2C_FLAG_BUSY ));
|
I2C_GenerateSTART(I2Cx, ENABLE); |
||||
// // Intiate Start Sequence
|
// Waiting for EV5
|
||||
// I2C_GenerateSTART (I2Cx , ENABLE );
|
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); |
||||
// Timed (! I2C_CheckEvent (I2Cx , I2C_EVENT_MASTER_MODE_SELECT));
|
// The 7 bit address needs to be shifted by 1
|
||||
// // Send Address EV5
|
I2C_Send7bitAddress(I2Cx, slave_addr<<1, dir); |
||||
// I2C_Send7bitAddress (I2Cx , SlaveAddress, I2C_Direction_Transmitter);
|
// Depending on whether the master is reading or writing another event is triggered
|
||||
// Timed (! I2C_CheckEvent (I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
|
if(dir== I2C_Direction_Transmitter) |
||||
// return 0;
|
{ |
||||
//}
|
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