parent
6440543da1
commit
1315d5c5fa
@ -0,0 +1,283 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <libopencm3/cm3/common.h> |
||||||
|
#include <libopencm3/stm32/f3/memorymap.h> |
||||||
|
|
||||||
|
|
||||||
|
// Opamp base address (just one register)
|
||||||
|
#define OPAMP1_BASE OPAMP_BASE + 0x38 |
||||||
|
#define OPAMP2_BASE OPAMP_BASE + 0x3C |
||||||
|
#define OPAMP3_BASE OPAMP_BASE + 0x40 |
||||||
|
#define OPAMP4_BASE OPAMP_BASE + 0x44 |
||||||
|
|
||||||
|
// opamp constants
|
||||||
|
#define OPAMP1 OPAMP1_BASE |
||||||
|
#define OPAMP2 OPAMP2_BASE |
||||||
|
#define OPAMP3 OPAMP3_BASE |
||||||
|
#define OPAMP4 OPAMP4_BASE |
||||||
|
|
||||||
|
#define OPAMP_CSR(opamp_base) MMIO32(opamp_base + 0) |
||||||
|
|
||||||
|
|
||||||
|
#define OPAMP_CSR_LOCK (1 << 31) |
||||||
|
|
||||||
|
|
||||||
|
#define OPAMP_CSR_OUTCAL (1 << 30) |
||||||
|
|
||||||
|
|
||||||
|
#define OPAMP_CSR_TSTREF (1 << 29) |
||||||
|
|
||||||
|
|
||||||
|
// trim registers
|
||||||
|
#define OPAMP_CSR_TRIMOFFSETN_SHIFT 24 |
||||||
|
#define OPAMP_CSR_TRIMOFFSETP_SHIFT 19 |
||||||
|
|
||||||
|
#define OPAMP_CSR_TRIMOFFSETN_MSK (0x1F << OPAMP_CSR_TRIMOFFSETN_SHIFT) |
||||||
|
#define OPAMP_CSR_TRIMOFFSETP_MSK (0x1F << OPAMP_CSR_TRIMOFFSETP_SHIFT) |
||||||
|
|
||||||
|
|
||||||
|
// user trim
|
||||||
|
#define OPAMP_CSR_USER_TRIM (1 << 18) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// PGA gain
|
||||||
|
#define OPAMP_CSR_PGA_GAIN_SHIFT 14 |
||||||
|
#define OPAMP_CSR_PGA_GAIN_MSK (0b0011 << OPAMP_CSR_PGA_GAIN_SHIFT) |
||||||
|
#define OPAMP_CSR_PGA_MIDPOINT_MSK (0b1100 << OPAMP_CSR_PGA_GAIN_SHIFT) |
||||||
|
|
||||||
|
|
||||||
|
// lower two bits
|
||||||
|
enum OPAMP_PGA_GAIN { |
||||||
|
OPAMP_PGA_GAIN_2 = (0 << OPAMP_CSR_PGA_GAIN_SHIFT), |
||||||
|
OPAMP_PGA_GAIN_4 = (1 << OPAMP_CSR_PGA_GAIN_SHIFT), |
||||||
|
OPAMP_PGA_GAIN_8 = (2 << OPAMP_CSR_PGA_GAIN_SHIFT), |
||||||
|
OPAMP_PGA_GAIN_16 = (3 << OPAMP_CSR_PGA_GAIN_SHIFT) |
||||||
|
}; |
||||||
|
|
||||||
|
// Masks that can be used to adjust PGA value
|
||||||
|
enum OPAMP_PGA_MIDPOINT { |
||||||
|
OPAMP_PGA_MIDPOINT_NONE = 0, |
||||||
|
OPAMP_PGA_MIDPOINT_VM0 = (0b1000 << OPAMP_CSR_PGA_GAIN_SHIFT), |
||||||
|
OPAMP_PGA_MIDPOINT_VM1 = (0b1100 << OPAMP_CSR_PGA_GAIN_SHIFT) |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Calibration select
|
||||||
|
#define OPAMP_CSR_CALSEL_SHIFT 12 |
||||||
|
#define OPAMP_CSR_CALSEL_MSK (0b11 << OPAMP_CSR_CALSEL_SHIFT) |
||||||
|
|
||||||
|
enum OPAMP_CALSEL { |
||||||
|
OPAMP_CALSEL_3P3 = (0 << OPAMP_CSR_CALSEL_SHIFT), |
||||||
|
OPAMP_CALSEL_10 = (1 << OPAMP_CSR_CALSEL_SHIFT), |
||||||
|
OPAMP_CALSEL_50 = (2 << OPAMP_CSR_CALSEL_SHIFT), |
||||||
|
OPAMP_CALSEL_90 = (3 << OPAMP_CSR_CALSEL_SHIFT), |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Cal On
|
||||||
|
#define OPAMP_CSR_CALON (1 << 11) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Non-inverting input, secondary
|
||||||
|
#define OPAMP_CSR_VPS_SEL_SHIFT 9 |
||||||
|
#define OPAMP_CSR_VPS_SEL_MSK (0b11 << OPAMP_CSR_VPS_SEL_SHIFT) |
||||||
|
|
||||||
|
enum OPAMP_VPS_SEL { |
||||||
|
OPAMP_VPS_SEL_VP0 = (0 << OPAMP_CSR_VPS_SEL_SHIFT), |
||||||
|
OPAMP_VPS_SEL_VP1 = (1 << OPAMP_CSR_VPS_SEL_SHIFT), |
||||||
|
OPAMP_VPS_SEL_VP2 = (2 << OPAMP_CSR_VPS_SEL_SHIFT), |
||||||
|
OPAMP_VPS_SEL_VP3 = (3 << OPAMP_CSR_VPS_SEL_SHIFT), |
||||||
|
|
||||||
|
OPAMP1_VPS_SEL_PA7 = OPAMP_VPS_SEL_VP0, |
||||||
|
OPAMP1_VPS_SEL_PA5 = OPAMP_VPS_SEL_VP1, |
||||||
|
OPAMP1_VPS_SEL_PA3 = OPAMP_VPS_SEL_VP2, |
||||||
|
OPAMP1_VPS_SEL_PA1 = OPAMP_VPS_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP2_VPS_SEL_PD14 = OPAMP_VPS_SEL_VP0, |
||||||
|
OPAMP2_VPS_SEL_PB14 = OPAMP_VPS_SEL_VP1, |
||||||
|
OPAMP2_VPS_SEL_PB0 = OPAMP_VPS_SEL_VP2, |
||||||
|
OPAMP2_VPS_SEL_PA7 = OPAMP_VPS_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP3_VPS_SEL_PB13 = OPAMP_VPS_SEL_VP0, |
||||||
|
OPAMP3_VPS_SEL_PA5 = OPAMP_VPS_SEL_VP1, |
||||||
|
OPAMP3_VPS_SEL_PA1 = OPAMP_VPS_SEL_VP2, |
||||||
|
OPAMP3_VPS_SEL_PB0 = OPAMP_VPS_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP4_VPS_SEL_PD11 = OPAMP_VPS_SEL_VP0, |
||||||
|
OPAMP4_VPS_SEL_PB11 = OPAMP_VPS_SEL_VP1, |
||||||
|
OPAMP4_VPS_SEL_PA4 = OPAMP_VPS_SEL_VP2, |
||||||
|
OPAMP4_VPS_SEL_PB13 = OPAMP_VPS_SEL_VP3 |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Inverting input, secondary
|
||||||
|
#define OPAMP_CSR_VMS_SEL_SHIFT 8 |
||||||
|
#define OPAMP_CSR_VMS_SEL_MSK (1 << OPAMP_CSR_VMS_SEL_SHIFT) |
||||||
|
|
||||||
|
enum OPAMP_VMS_SEL { |
||||||
|
OPAMP_VMS_SEL_VM0 = (0 << OPAMP_CSR_VMS_SEL_SHIFT), |
||||||
|
OPAMP_VMS_SEL_VM1 = (1 << OPAMP_CSR_VMS_SEL_SHIFT), |
||||||
|
|
||||||
|
OPAMP1_VMS_SEL_PC5 = OPAMP_VMS_SEL_VM0, |
||||||
|
OPAMP1_VMS_SEL_PA3 = OPAMP_VMS_SEL_VM1, |
||||||
|
|
||||||
|
OPAMP2_VMS_SEL_PC5 = OPAMP_VMS_SEL_VM0, |
||||||
|
OPAMP2_VMS_SEL_PA5 = OPAMP_VMS_SEL_VM1, |
||||||
|
|
||||||
|
OPAMP3_VMS_SEL_PB10 = OPAMP_VMS_SEL_VM0, |
||||||
|
OPAMP3_VMS_SEL_PB2 = OPAMP_VMS_SEL_VM1, |
||||||
|
|
||||||
|
OPAMP4_VMS_SEL_PB10 = OPAMP_VMS_SEL_VM0, |
||||||
|
OPAMP4_VMS_SEL_PD8 = OPAMP_VMS_SEL_VM1, |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Cal On
|
||||||
|
#define OPAMP_CSR_TCM_EN (1 << 7) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Inverting input, primary
|
||||||
|
#define OPAMP_CSR_VM_SEL_SHIFT 5 |
||||||
|
#define OPAMP_CSR_VM_SEL_MSK (0b11 << OPAMP_CSR_VM_SEL_SHIFT) |
||||||
|
|
||||||
|
enum OPAMP_VM_SEL { |
||||||
|
OPAMP_VM_SEL_VM0 = (0 << OPAMP_CSR_VM_SEL_SHIFT), |
||||||
|
OPAMP_VM_SEL_VM1 = (1 << OPAMP_CSR_VM_SEL_SHIFT), |
||||||
|
OPAMP_VM_SEL_PGA = (2 << OPAMP_CSR_VM_SEL_SHIFT), |
||||||
|
OPAMP_VM_SEL_FLW = (3 << OPAMP_CSR_VM_SEL_SHIFT), |
||||||
|
|
||||||
|
OPAMP1_VM_SEL_PC5 = OPAMP_VM_SEL_VM0, |
||||||
|
OPAMP1_VM_SEL_PA3 = OPAMP_VM_SEL_VM1, |
||||||
|
OPAMP1_VM_SEL_PGA = OPAMP_VM_SEL_PGA, |
||||||
|
OPAMP1_VM_SEL_FLW = OPAMP_VM_SEL_FLW, |
||||||
|
|
||||||
|
OPAMP2_VM_SEL_PC5 = OPAMP_VM_SEL_VM0, |
||||||
|
OPAMP2_VM_SEL_PA5 = OPAMP_VM_SEL_VM1, |
||||||
|
OPAMP2_VM_SEL_PGA = OPAMP_VM_SEL_PGA, |
||||||
|
OPAMP2_VM_SEL_FLW = OPAMP_VM_SEL_FLW, |
||||||
|
|
||||||
|
OPAMP3_VM_SEL_PB10 = OPAMP_VM_SEL_VM0, |
||||||
|
OPAMP3_VM_SEL_PB2 = OPAMP_VM_SEL_VM1, |
||||||
|
OPAMP3_VM_SEL_PGA = OPAMP_VM_SEL_PGA, |
||||||
|
OPAMP3_VM_SEL_FLW = OPAMP_VM_SEL_FLW, |
||||||
|
|
||||||
|
OPAMP4_VM_SEL_PB10 = OPAMP_VM_SEL_VM0, |
||||||
|
OPAMP4_VM_SEL_PD8 = OPAMP_VM_SEL_VM1, |
||||||
|
OPAMP4_VM_SEL_PGA = OPAMP_VM_SEL_PGA, |
||||||
|
OPAMP4_VM_SEL_FLW = OPAMP_VM_SEL_FLW, |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Non-inverting input, primary
|
||||||
|
#define OPAMP_CSR_VP_SEL_SHIFT 2 |
||||||
|
#define OPAMP_CSR_VP_SEL_MSK (0b11 << OPAMP_CSR_VP_SEL_SHIFT) |
||||||
|
|
||||||
|
enum OPAMP_VP_SEL { |
||||||
|
OPAMP_VP_SEL_VP0 = (0 << OPAMP_CSR_VP_SEL_SHIFT), |
||||||
|
OPAMP_VP_SEL_VP1 = (1 << OPAMP_CSR_VP_SEL_SHIFT), |
||||||
|
OPAMP_VP_SEL_VP2 = (2 << OPAMP_CSR_VP_SEL_SHIFT), |
||||||
|
OPAMP_VP_SEL_VP3 = (3 << OPAMP_CSR_VP_SEL_SHIFT), |
||||||
|
|
||||||
|
OPAMP1_VP_SEL_PA7 = OPAMP_VP_SEL_VP0, |
||||||
|
OPAMP1_VP_SEL_PA5 = OPAMP_VP_SEL_VP1, |
||||||
|
OPAMP1_VP_SEL_PA3 = OPAMP_VP_SEL_VP2, |
||||||
|
OPAMP1_VP_SEL_PA1 = OPAMP_VP_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP2_VP_SEL_PD14 = OPAMP_VP_SEL_VP0, |
||||||
|
OPAMP2_VP_SEL_PB14 = OPAMP_VP_SEL_VP1, |
||||||
|
OPAMP2_VP_SEL_PB0 = OPAMP_VP_SEL_VP2, |
||||||
|
OPAMP2_VP_SEL_PA7 = OPAMP_VP_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP3_VP_SEL_PB13 = OPAMP_VP_SEL_VP0, |
||||||
|
OPAMP3_VP_SEL_PA5 = OPAMP_VP_SEL_VP1, |
||||||
|
OPAMP3_VP_SEL_PA1 = OPAMP_VP_SEL_VP2, |
||||||
|
OPAMP3_VP_SEL_PB0 = OPAMP_VP_SEL_VP3, |
||||||
|
|
||||||
|
OPAMP4_VP_SEL_PD11 = OPAMP_VP_SEL_VP0, |
||||||
|
OPAMP4_VP_SEL_PB11 = OPAMP_VP_SEL_VP1, |
||||||
|
OPAMP4_VP_SEL_PA4 = OPAMP_VP_SEL_VP2, |
||||||
|
OPAMP4_VP_SEL_PB13 = OPAMP_VP_SEL_VP3 |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Forve VP - VP connected to calibration reference
|
||||||
|
#define OPAMP_CSR_FORCE_VP (1 << 1) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Enable opamp
|
||||||
|
#define OPAMP_CSR_OPAMPEN (1 << 0) |
||||||
|
|
||||||
|
|
||||||
|
// -------------- Functions ----------------
|
||||||
|
|
||||||
|
/** Lock the opamp config. No way to unlock until restart. */ |
||||||
|
void opamp_lock(uint32_t opamp); |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable OPAMP |
||||||
|
* Must also enable RCC_SYSCFG_COMP in RCC |
||||||
|
*/ |
||||||
|
void opamp_enable(uint32_t opamp); |
||||||
|
|
||||||
|
|
||||||
|
/** Disable OPAMP */ |
||||||
|
void opamp_disable(uint32_t opamp); |
||||||
|
|
||||||
|
|
||||||
|
/** Send reference to ADC input channel */ |
||||||
|
void opamp_ref_to_adc(uint32_t opamp, bool yes); |
||||||
|
|
||||||
|
|
||||||
|
/** Send reference to non-inverting input */ |
||||||
|
void opamp_ref_to_vp(uint32_t opamp, bool yes); |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set PGA gain. |
||||||
|
* To use PGA, call opamp_mode_pga() first. |
||||||
|
*/ |
||||||
|
void opamp_pga_set_gain(uint32_t opamp, enum OPAMP_PGA_GAIN gain); |
||||||
|
|
||||||
|
|
||||||
|
/** Set PGA midpoint routing */ |
||||||
|
void opamp_pga_set_midpoint(uint32_t opamp, enum OPAMP_PGA_MIDPOINT midpoint); |
||||||
|
|
||||||
|
|
||||||
|
/** Connect VM pin (can be used to select follower and PGA mode) */ |
||||||
|
void opamp_vm_select(uint32_t opamp, enum OPAMP_VM_SEL vm); |
||||||
|
|
||||||
|
|
||||||
|
/** Connect the VP pin */ |
||||||
|
void opamp_vp_select(uint32_t opamp, enum OPAMP_VP_SEL vp); |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set opamp to PGA mode (shortcut function) |
||||||
|
* Midpoint can be connected to VM pins with opamp_pga_set_midpoint() |
||||||
|
*/ |
||||||
|
void opamp_mode_pga(uint32_t opamp); |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set opamp to follower mode (shortcut function). |
||||||
|
* VM is not connected to GPIO in this mode. |
||||||
|
*/ |
||||||
|
void opamp_mode_follower(uint32_t opamp); |
||||||
|
|
||||||
|
|
||||||
|
/** Select reference value to use */ |
||||||
|
void opamp_ref_select(uint32_t opamp, enum OPAMP_CALSEL ref); |
||||||
|
|
||||||
|
|
||||||
|
/** Calibrate an OpAmp */ |
||||||
|
bool opamp_calibrate(uint32_t opamp); |
Loading…
Reference in new issue