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