Working DAC lib

This commit is contained in:
2024-03-21 13:57:22 +01:00
parent 3466632ec4
commit fef30d070c
2 changed files with 299 additions and 0 deletions

168
DAC7578.c Normal file
View File

@@ -0,0 +1,168 @@
/**
* @file DAC7578.c
* @brief
* @author sanderspeetjens
*/
#include "DAC7578.h"
#define DAC7578_TIMEOUT 100
void DAC7578_Init(DAC7578_HandleTypeDef *hdac, I2C_HandleTypeDef *hi2c, uint8_t address, GPIO_TypeDef *ldac_port, uint16_t ldac_pin) {
hdac->hi2c = hi2c;
address &= 0b1110;
hdac->address = (0b1001 << 4) | address;
hdac->ldac_port = ldac_port;
hdac->ldac_pin = ldac_pin;
}
/**
* @brief Set the byte in the designated register to value.
* @param regAddr Register address to write.
* @param val Value to set, 0 to 255.
*/
void DAC7578_SetRegByte(DAC7578_HandleTypeDef *hdac, uint8_t regAddr, uint16_t val) {
uint8_t bytes[3] = { regAddr, val >> 8, val & 0xff };
HAL_I2C_Master_Transmit(hdac->hi2c, hdac->address, bytes, 3, DAC7578_TIMEOUT);
}
/**
* @brief Gets the byte in the designated register.
* @param regAddr Register address to read.
* @return Value stored in the register, 0 to 255.
*/
uint16_t DAC7578_GetRegByte(DAC7578_HandleTypeDef *hdac, uint8_t regAddr) {
uint8_t val[2];
HAL_I2C_Master_Transmit(hdac->hi2c, hdac->address, &regAddr, 1, DAC7578_TIMEOUT);
HAL_I2C_Master_Receive(hdac->hi2c, hdac->address, val, 2, DAC7578_TIMEOUT);
return val[1] + (val[0] << 8);
}
/**
* @brief This function sets the output of a DAC
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
* @param value The 10-bit value to set the DAC to
* @return HAL_StatusTypeDef HAL_OK if successful, HAL_ERROR or HAL_BUSY otherwise
*/
void DAC7578_set_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t value, bool update) {
uint8_t regAddr = 0x00;
// limit value to 10 bits
value &= 0xFFF;
value = (value << 4);
// set input register of dac n_dac to value
// register is 0x00 + n_dac
regAddr = 0b0111 & chan;
if (update) {
regAddr |= 0x30;
}
DAC7578_SetRegByte(hdac, regAddr, value);
}
void DAC7578_update_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan) {
uint8_t regAddr = 0x00;
// update dac chan
// register is 0x00 + n_dac
regAddr = 0b1111 & chan;
regAddr |= 0x10;
HAL_GPIO_WritePin(hdac->ldac_port, hdac->ldac_pin, GPIO_PIN_RESET);
DAC7578_SetRegByte(hdac, regAddr, 0xFFFF);
HAL_GPIO_WritePin(hdac->ldac_port, hdac->ldac_pin, GPIO_PIN_SET);
}
void DAC7578_set_dac_output_all(DAC7578_HandleTypeDef *hdac, uint16_t value, bool update) {
// set input register of all dacs to value
// register is 0x00 and broadcast address is 0x0F
uint8_t regAddr = 0x0F;
// limit value to 12 bits
value &= 0xFFF;
value = (value << 4);
if (update) {
regAddr |= 0x30;
}
DAC7578_SetRegByte(hdac, regAddr, value);
}
void DAC7578_update_dac_output_all(DAC7578_HandleTypeDef *hdac) {
uint8_t regAddr = 0x00;
// update all dacs
// register is 0x00 and broadcast address is 0x0F
regAddr = 0x0F;
regAddr |= 0x10;
HAL_GPIO_WritePin(hdac->ldac_port, hdac->ldac_pin, GPIO_PIN_RESET);
DAC7578_SetRegByte(hdac, regAddr, 0);
HAL_GPIO_WritePin(hdac->ldac_port, hdac->ldac_pin, GPIO_PIN_SET);
}
void DAC7578_read_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t *value) {
uint8_t regAddr = 0x00;
uint16_t ret;
// read input register of dac chan
// register is 0x10 + chan
regAddr = 0b1111 & chan;
regAddr |= 0x10;
ret = DAC7578_GetRegByte(hdac, regAddr);
ret >>= 4;
if (value != NULL)
*value = ret;
}
void DAC7578_read_dac_input(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t *value) {
uint8_t regAddr = 0x00;
uint16_t ret;
// read input register of dac chan
// register is 0x10 + chan
regAddr = 0b1111 & chan;
ret = DAC7578_GetRegByte(hdac, regAddr);
ret >>= 4;
if (value != NULL)
*value = ret;
}
void DAC7578_write_dac_power(DAC7578_HandleTypeDef* hdac, uint8_t chan, DAC7578_power_t power) {
uint8_t regAddr = 0x40;
uint16_t pd_config = ((uint16_t) power) << 13; // PD1, PD0
uint16_t chan_config = ((uint16_t) chan) << 5; // DACH ~ DACA
DAC7578_SetRegByte(hdac, regAddr, pd_config | chan_config);
}
void DAC7578_write_dac_power_all(DAC7578_HandleTypeDef* hdac, DAC7578_power_t power) {
uint8_t regAddr = 0x40;
uint16_t val = 0x1FE;
val |= (power & 0x3) << 1;
DAC7578_SetRegByte(hdac, regAddr, val);
}
void DAC7578_dac_ignore_ldac_pin(DAC7578_HandleTypeDef* hdac, uint8_t chan)
{
uint8_t regAddr = 0x60;
uint16_t val = chan << 8;
DAC7578_SetRegByte(hdac, regAddr, val);
}
void DAC7578_all_dac_ignore_ldac_pin(DAC7578_HandleTypeDef* hdac) {
uint8_t regAddr = 0x60;
uint16_t val = 0xFF00;
DAC7578_SetRegByte(hdac, regAddr, val);
}
//
//void DAC7578_read_dac_power(DAC7578_HandleTypeDef* hdac, uint8_t n_dac, DAC7578_power_t *power) {
// uint8_t regAddr = 0x40;
// uint16_t val = DAC7578_GetRegByte(hdac, regAddr);
// val >>= (n_dac + 5);
// *power = val & 0x03;
//}
//HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
// uint16_t Size, uint32_t Timeout);
//HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
// uint16_t Size, uint32_t Timeout);

131
DAC7578.h Normal file
View File

@@ -0,0 +1,131 @@
/**
The MIT License (MIT)
Copyright (c) 2024 Sani7
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef DAC_DAC7578_H
#define DAC_DAC7578_H
#include "stm32f0xx_hal.h"
#include <stdint.h>
#include <stdbool.h>
typedef struct {
I2C_HandleTypeDef *hi2c;
uint16_t address;
GPIO_TypeDef *ldac_port;
uint16_t ldac_pin;
} DAC7578_HandleTypeDef;
typedef enum {
power_on = 0x00,
power_off_1k = 0x01,
power_off_100k = 0x02,
power_off_high_impedance = 0x03
} DAC7578_power_t;
/**
* @brief This function initializes the DAC handle
* @param hdac The DAC handle
* @param hi2c The I2C handle the DAC is connected to
* @param address The I2C address of the DAC (via hardware jumpers)
*/
void DAC7578_Init(DAC7578_HandleTypeDef *hdac, I2C_HandleTypeDef *hi2c, uint8_t address, GPIO_TypeDef *ldac_port, uint16_t ldac_pin);
/**
* @brief Set the output of a DAC
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
* @param value The 10-bit value to set the DAC to
* @param update True to update the DAC output, false to only set the input register
*/
void DAC7578_set_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t value, bool update);
/**
* @brief Update one DAC output
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
*/
void DAC7578_update_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan);
/**
* @brief Set all dac outputs globally
* @param hdac The DAC handle
* @param value The 10-bit value to set the DAC to
* @param update True to update the DAC output, false to only set the input register
*/
void DAC7578_set_dac_output_all(DAC7578_HandleTypeDef *hdac, uint16_t value, bool update);
/**
* @brief Update all DAC ouputs
* @param hdac The DAC handle
*/
void DAC7578_update_dac_output_all(DAC7578_HandleTypeDef *hdac);
/**
* @brief Read one dac output register
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
* @param value The pointer to the output value
*/
void DAC7578_read_dac_output(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t *value);
/**
* @brief Read one dac input register
*
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
* @param value The pointer to the output value
*/
void DAC7578_read_dac_input(DAC7578_HandleTypeDef *hdac, uint8_t chan, uint16_t *value);
/**
* @brief Set the power mode of a dac
* @param hdac The DAC handle
* @param chan The DAC number (0-7)
* @param power The power mode to set the dac to
*/
void DAC7578_write_dac_power(DAC7578_HandleTypeDef* hdac, uint8_t chan, DAC7578_power_t power);
/**
* @brief Set the power mode of all dacs
* @param hdac The DAC handle
* @param power The power mode to set all dacs to
*/
void DAC7578_write_dac_power_all(DAC7578_HandleTypeDef* hdac, DAC7578_power_t power);
/**
* @brief This function makes the provided dac channels ignore the ldac pin
*
* @param hdac This function makes all dac channels ignore the ldac pin
* @param chan The channel(s) that have to ignore the ldac pin
*/
void DAC7578_dac_ignore_ldac_pin(DAC7578_HandleTypeDef* hdac, uint8_t chan);
/**
* @brief This function makes all dac channels ignore the ldac pin
*
* @param hdac
*/
void DAC7578_all_dac_ignore_ldac_pin(DAC7578_HandleTypeDef* hdac);
#endif //DAC_DAC7578_H