1.1 --- a/Hardware/LPC/W836XX.cs Sat Mar 27 13:04:34 2010 +0000
1.2 +++ b/Hardware/LPC/W836XX.cs Sat Mar 27 19:55:09 2010 +0000
1.3 @@ -90,7 +90,7 @@
1.4 (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
1.5 return WinRing0.ReadIoPortByte(
1.6 (ushort)(address + DATA_REGISTER_OFFSET));
1.7 - }
1.8 + }
1.9
1.10 private void WriteByte(byte bank, byte register, byte value) {
1.11 WinRing0.WriteIoPortByte(
1.12 @@ -195,6 +195,17 @@
1.13 return vendorId == WINBOND_VENDOR_ID;
1.14 }
1.15
1.16 + private ulong SetBit(ulong target, int bit, int value) {
1.17 + if ((value & 1) != value)
1.18 + throw new ArgumentException("Value must be one bit only.");
1.19 +
1.20 + if (bit < 0 || bit > 63)
1.21 + throw new ArgumentException("Bit out of range.");
1.22 +
1.23 + ulong mask = (((ulong)1) << bit);
1.24 + return value > 0 ? target | mask : target & ~mask;
1.25 + }
1.26 +
1.27 public void Update() {
1.28
1.29 foreach (Sensor sensor in voltages) {
1.30 @@ -244,22 +255,49 @@
1.31 }
1.32 }
1.33
1.34 - long bits = 0;
1.35 + ulong bits = 0;
1.36 for (int i = 0; i < FAN_BIT_REG.Length; i++)
1.37 bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
1.38 + ulong newBits = bits;
1.39 foreach (Sensor sensor in fans) {
1.40 int count = ReadByte(FAN_TACHO_BANK[sensor.Index],
1.41 FAN_TACHO_REG[sensor.Index]);
1.42 +
1.43 + // assemble fan divisor
1.44 int divisorBits = (int)(
1.45 (((bits >> FAN_DIV_BIT2[sensor.Index]) & 1) << 2) |
1.46 (((bits >> FAN_DIV_BIT1[sensor.Index]) & 1) << 1) |
1.47 ((bits >> FAN_DIV_BIT0[sensor.Index]) & 1));
1.48 int divisor = 1 << divisorBits;
1.49 +
1.50 float value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
1.51 sensor.Value = value;
1.52 if (value > 0)
1.53 - ActivateSensor(sensor);
1.54 - }
1.55 + ActivateSensor(sensor);
1.56 +
1.57 + // update fan divisor
1.58 + if (count > 192 && divisorBits < 7)
1.59 + divisorBits++;
1.60 + if (count < 96 && divisorBits > 0)
1.61 + divisorBits--;
1.62 +
1.63 + newBits = SetBit(newBits, FAN_DIV_BIT2[sensor.Index],
1.64 + (divisorBits >> 2) & 1);
1.65 + newBits = SetBit(newBits, FAN_DIV_BIT1[sensor.Index],
1.66 + (divisorBits >> 1) & 1);
1.67 + newBits = SetBit(newBits, FAN_DIV_BIT0[sensor.Index],
1.68 + divisorBits & 1);
1.69 + }
1.70 +
1.71 + // write new fan divisors
1.72 + for (int i = FAN_BIT_REG.Length - 1; i >= 0; i--) {
1.73 + byte oldByte = (byte)(bits & 0xFF);
1.74 + byte newByte = (byte)(newBits & 0xFF);
1.75 + bits = bits >> 8;
1.76 + newBits = newBits >> 8;
1.77 + if (oldByte != newByte)
1.78 + WriteByte(0, FAN_BIT_REG[i], newByte);
1.79 + }
1.80 }
1.81
1.82 public string GetReport() {