github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/soc/nxp/tempmon/tempmon.go (about) 1 // NXP Temperature Monitor (TEMPMON) driver 2 // https://github.com/usbarmory/tamago 3 // 4 // Copyright (c) WithSecure Corporation 5 // https://foundry.withsecure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 // Package bee implements a driver for the NXP Temperature Monitor (TEMPMON) 11 // adopting the following reference specifications: 12 // - IMX6ULLRM - i.MX 6ULL Applications Processor Reference Manual - Rev 1 2017/11 13 // 14 // This package is only meant to be used with `GOOS=tamago GOARCH=arm` as 15 // supported by the TamaGo framework for bare metal Go on ARM SoCs, see 16 // https://github.com/usbarmory/tamago. 17 package tempmon 18 19 import ( 20 "sync" 21 22 "github.com/usbarmory/tamago/bits" 23 "github.com/usbarmory/tamago/internal/reg" 24 ) 25 26 // TEMPMON registers 27 const ( 28 TEMPMON_TEMPSENSE0 = 0x00 29 TEMPMON_TEMPSENSE0_SET = 0x04 30 TEMPMON_TEMPSENSE0_CLR = 0x08 31 32 TEMPSENSE0_TEMP_CNT = 8 33 TEMPSENSE0_FINISHED = 2 34 TEMPSENSE0_MEASURE_TEMP = 1 35 TEMPSENSE0_POWER_DOWN = 0 36 37 TEMPMON_TEMPSENSE1 = 0x10 38 TEMPMON_TEMPSENSE1_SET = 0x14 39 TEMPMON_TEMPSENSE1_CLR = 0x18 40 41 TEMPSENSE1_MEASURE_FREQ = 0 42 ) 43 44 // TEMPMON represents the Temperature Monitor instance. 45 type TEMPMON struct { 46 sync.Mutex 47 48 // Base register 49 Base uint32 50 51 // control registers 52 sense0 uint32 53 sense0_set uint32 54 sense0_clr uint32 55 sense1 uint32 56 sense1_clr uint32 57 58 // calibration points 59 hotTemp uint32 60 hotCount uint32 61 roomCount uint32 62 } 63 64 // Init initializes the Temperature Monitor instance, the calibration data is 65 // fused individually for each part and is required for correct measurements. 66 func (hw *TEMPMON) Init(calibrationData uint32) { 67 hw.Lock() 68 defer hw.Unlock() 69 70 if hw.Base == 0 { 71 panic("invalid TEMPMON instance") 72 } 73 74 hw.sense0 = hw.Base + TEMPMON_TEMPSENSE0 75 hw.sense0_set = hw.Base + TEMPMON_TEMPSENSE0_SET 76 hw.sense0_clr = hw.Base + TEMPMON_TEMPSENSE0_CLR 77 78 hw.sense1 = hw.Base + TEMPMON_TEMPSENSE1 79 hw.sense1_clr = hw.Base + TEMPMON_TEMPSENSE1_CLR 80 81 hw.hotTemp = bits.Get(&calibrationData, 0, 0xff) 82 hw.hotCount = bits.Get(&calibrationData, 8, 0xfff) 83 hw.roomCount = bits.Get(&calibrationData, 20, 0xfff) 84 } 85 86 // Read performs a single on-die temperature measurement. 87 func (hw *TEMPMON) Read() float32 { 88 hw.Lock() 89 defer hw.Unlock() 90 91 if hw.sense0 == 0 { 92 return 0 93 } 94 95 // enable sensor only during single measurement 96 reg.Set(hw.sense0_clr, TEMPSENSE0_POWER_DOWN) 97 defer reg.Set(hw.sense0_set, TEMPSENSE0_POWER_DOWN) 98 99 // start and wait for a single measurement 100 reg.SetN(hw.sense1_clr, TEMPSENSE1_MEASURE_FREQ, 0xffff, 0xffff) 101 reg.Set(hw.sense0_set, TEMPSENSE0_MEASURE_TEMP) 102 reg.Wait(hw.sense0, TEMPSENSE0_FINISHED, 1, 1) 103 104 cnt := reg.Get(hw.sense0, TEMPSENSE0_TEMP_CNT, 0xfff) 105 106 return temp(cnt, hw.hotTemp, hw.hotCount, hw.roomCount) 107 } 108 109 // p3531, 52.2 Software Usage Guidelines, IMX6ULLRM 110 func temp(cnt, hotTemp, hotCount, roomCount uint32) float32 { 111 nm := float32(cnt) 112 t1 := float32(25.0) 113 t2 := float32(hotTemp) 114 n1 := float32(roomCount) 115 n2 := float32(hotCount) 116 117 return t2 - (nm-n2)*((t2-t1)/(n1-n2)) 118 }