From 147e8ea538c3c0766f7ffc9df93ef4739b45dd3c Mon Sep 17 00:00:00 2001
From: Adam Wujek <adam.wujek@cern.ch>
Date: Tue, 17 Feb 2015 17:02:20 +0100
Subject: [PATCH] userspace: export temperature from sensors to HAL's shmem

HAL at update of fan speed reads Switch's temperature sensors.
Sensors read:
-FPGA
-PLL (was read before to drive PWM for fan)
-Power supply left
-Power supply right

Additionally:
-add hal_temp_sensors structure to hal shmem, add current temperature and
 threshold values (to be implemented in later commits)
-increment HAL_SHMEM_VERSION
-update hal_shmem.h in ppsi
-update dump_shmem with new structure, add specific type for temperature
 sensors
-in hal_ports.c
 --rename struct wrs_shm_head *head to struct wrs_shm_head *hal_shmem_hdr
 --remove void *hal_port_shmem as not needed,
 --make struct hal_shmem_header *hal_shmem extern, defined in hal_main.c

Signed-off-by: Adam Wujek <adam.wujek@cern.ch>
---
 userspace/libwr/fan.c                     | 25 ++++++++++++++++++-----
 userspace/libwr/include/libwr/fan.h       |  5 +++--
 userspace/libwr/include/libwr/hal_shmem.h | 16 +++++++++++++--
 userspace/ppsi                            |  2 +-
 userspace/tools/wrs_dump_shmem.c          | 22 ++++++++++++++++++++
 userspace/wrsw_hal/hal_main.c             |  5 ++++-
 userspace/wrsw_hal/hal_ports.c            | 24 ++++++++++------------
 7 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/userspace/libwr/fan.c b/userspace/libwr/fan.c
index c2ec431e7..ffa32fa6f 100644
--- a/userspace/libwr/fan.c
+++ b/userspace/libwr/fan.c
@@ -28,6 +28,7 @@
 
 #include <libwr/pio.h>
 #include <libwr/fan.h>
+#include <libwr/hal_shmem.h>
 
 #include <at91_softpwm.h>
 
@@ -39,7 +40,10 @@
 #include "spwm-regs.h"
 #include <libwr/util.h>
 
-#define FAN_TEMP_SENSOR_ADDR 0x4c
+#define TEMP_SENSOR_ADDR_FPGA	0x4A /* (7bits addr) IC19 Below FPGA */
+#define TEMP_SENSOR_ADDR_PLL	0x4C /* (7bits addr) IC18 PLLs */
+#define TEMP_SENSOR_ADDR_PSL	0x49 /* (7bits addr) IC20 Power supply left */
+#define TEMP_SENSOR_ADDR_PSR	0x4D /* (7bits addr) IC17 Power supply right */
 
 #define DESIRED_TEMPERATURE 55.0
 
@@ -204,7 +208,7 @@ static int shw_init_i2c_sensors()
 	return 0;
 }
 
-int shw_init_fans()
+int shw_init_fans(void)
 {
 	uint32_t val = 0;
 
@@ -250,7 +254,11 @@ int shw_init_fans()
 
 	shw_init_i2c_sensors();
 
-	tmp100_write_reg(FAN_TEMP_SENSOR_ADDR, 1, 0x60);	// 12-bit resolution
+	/* set all to 12-bit resolution */
+	tmp100_write_reg(TEMP_SENSOR_ADDR_FPGA, 1, 0x60);
+	tmp100_write_reg(TEMP_SENSOR_ADDR_PLL, 1, 0x60);
+	tmp100_write_reg(TEMP_SENSOR_ADDR_PSL, 1, 0x60);
+	tmp100_write_reg(TEMP_SENSOR_ADDR_PSR, 1, 0x60);
 
 	pi_init(&fan_pi);
 
@@ -263,17 +271,24 @@ int shw_init_fans()
  * Reads out the temperature and drives the fan accordingly
  * note: This call is done by hal_main.c:hal_update()
  */
-void shw_update_fans()
+void shw_update_fans(struct hal_temp_sensors *sensors)
 {
 	static int64_t last_tics = -1;
 	int64_t cur_tics = shw_get_tics();
 
 	if (fan_update_timeout > 0
 	    && (last_tics < 0 || (cur_tics - last_tics) > fan_update_timeout)) {
-		float t_cur = tmp100_read_temp(FAN_TEMP_SENSOR_ADDR);
+		/* drive fan based on PLL temperature */
+		float t_cur = tmp100_read_temp(TEMP_SENSOR_ADDR_PLL);
 		float drive = pi_update(&fan_pi, t_cur - DESIRED_TEMPERATURE);
 		//pr_info("t=%f,pwm=%f\n",t_cur , drive);
 		shw_pwm_speed(0xFF, drive / 1000);	//enable two and one
+
+		/* update sensor values */
+		sensors->fpga = tmp100_read_reg(TEMP_SENSOR_ADDR_FPGA, 0, 2);
+		sensors->pll = tmp100_read_reg(TEMP_SENSOR_ADDR_PLL, 0, 2);
+		sensors->psl = tmp100_read_reg(TEMP_SENSOR_ADDR_PSL, 0, 2);
+		sensors->psr = tmp100_read_reg(TEMP_SENSOR_ADDR_PSR, 0, 2);
 		last_tics = cur_tics;
 	}
 }
diff --git a/userspace/libwr/include/libwr/fan.h b/userspace/libwr/include/libwr/fan.h
index 285bb5472..b4fac9169 100644
--- a/userspace/libwr/include/libwr/fan.h
+++ b/userspace/libwr/include/libwr/fan.h
@@ -1,9 +1,10 @@
 #ifndef __LIBWR_FAN_H
 #define __LIBWR_FAN_H
+#include <libwr/hal_shmem.h>
 
 #define SHW_FAN_UPDATETO_DEFAULT 5
 
-int shw_init_fans();
-void shw_update_fans();
+int shw_init_fans(void);
+void shw_update_fans(struct hal_temp_sensors *sensors);
 
 #endif /* __LIBWR_FAN_H */
diff --git a/userspace/libwr/include/libwr/hal_shmem.h b/userspace/libwr/include/libwr/hal_shmem.h
index 15d831e04..45289483c 100644
--- a/userspace/libwr/include/libwr/hal_shmem.h
+++ b/userspace/libwr/include/libwr/hal_shmem.h
@@ -102,12 +102,24 @@ struct hal_port_state {
 	uint32_t ep_base;
 };
 
+struct hal_temp_sensors {
+	int fpga;	/* IC19 */
+	int pll;	/* IC18 */
+	int psl;	/* IC20 Power Supply Left (PSL) */
+	int psr;	/* IC17 Power Supply Right (PSR) */
+	int fpga_thold;	/* Threshold value for FPGA temperature */
+	int pll_thold;	/* Threshold value for PLL temperature */
+	int psl_thold;	/* Threshold value for PSL temperature */
+	int psr_thold;	/* Threshold value for PSR temperature */
+};
+
 /* This is the overall structure stored in shared memory */
-#define HAL_SHMEM_VERSION 5 /* Version 5 because of new field vendor_name in
-			     * struct shw_sfp_caldata */
+#define HAL_SHMEM_VERSION 6 /* Version 6 because of new structure
+			     * hal_temp_sensors in hal_shmem_header */
 struct hal_shmem_header {
 	int nports;
 	struct hal_port_state *ports;
+	struct hal_temp_sensors temp;
 };
 
 static inline int state_up(int state)
diff --git a/userspace/ppsi b/userspace/ppsi
index c22cd7cb6..d04c7c28c 160000
--- a/userspace/ppsi
+++ b/userspace/ppsi
@@ -1 +1 @@
-Subproject commit c22cd7cb69cacc5053f3306aa17d5ef30dc05330
+Subproject commit d04c7c28cfcca35fd5d21f4f288ed1fd14318984
diff --git a/userspace/tools/wrs_dump_shmem.c b/userspace/tools/wrs_dump_shmem.c
index 9d2e2fe81..d7476aee2 100644
--- a/userspace/tools/wrs_dump_shmem.c
+++ b/userspace/tools/wrs_dump_shmem.c
@@ -67,6 +67,7 @@ enum dump_type {
 	dump_type_ip_address,
 	dump_type_sfp_flags,
 	dump_type_port_mode,
+	dump_type_sensor_temp,
 };
 
 static int dump_all_rtu_entries = 0; /* rtu exports 4096 vlans and 2048 htab
@@ -201,6 +202,9 @@ void dump_one_field(void *addr, struct dump_info *info)
 			break;
 		}
 		break;
+	case dump_type_sensor_temp:
+		printf("%f\n", ((float)(*(int *)p >> 4)) / 16.0);
+		break;
 	}
 }
 void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
@@ -228,6 +232,20 @@ void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
 	.size = _size, \
 }
 
+#undef DUMP_STRUCT
+#define DUMP_STRUCT struct hal_shmem_header
+struct dump_info hal_shmem_info [] = {
+	DUMP_FIELD(int, nports),
+	DUMP_FIELD(sensor_temp, temp.fpga),
+	DUMP_FIELD(sensor_temp, temp.pll),
+	DUMP_FIELD(sensor_temp, temp.psl),
+	DUMP_FIELD(sensor_temp, temp.psr),
+	DUMP_FIELD(int, temp.fpga_thold),
+	DUMP_FIELD(int, temp.pll_thold),
+	DUMP_FIELD(int, temp.psl_thold),
+	DUMP_FIELD(int, temp.psr_thold),
+};
+
 /* map for fields of hal_port_state (hal_shmem.h) */
 #undef DUMP_STRUCT
 #define DUMP_STRUCT struct hal_port_state
@@ -287,6 +305,10 @@ int dump_hal_mem(struct wrs_shm_head *head)
 		return -1;
 	}
 	h = (void *)head + head->data_off;
+
+	/* dump hal's shmem */
+	dump_many_fields(h, hal_shmem_info, ARRAY_SIZE(hal_shmem_info));
+
 	n = h->nports;
 	p = wrs_shm_follow(head, h->ports);
 
diff --git a/userspace/wrsw_hal/hal_main.c b/userspace/wrsw_hal/hal_main.c
index 0287ebfed..b3b2200d5 100644
--- a/userspace/wrsw_hal/hal_main.c
+++ b/userspace/wrsw_hal/hal_main.c
@@ -16,6 +16,7 @@
 #include <libwr/shw_io.h>
 #include <libwr/sfp_lib.h>
 #include <libwr/config.h>
+#include <libwr/hal_shmem.h>
 
 #include "wrsw_hal.h"
 #include <rt_ipc.h>
@@ -26,6 +27,7 @@
 
 static int daemon_mode = 0;
 static hal_cleanup_callback_t cleanup_cb[MAX_CLEANUP_CALLBACKS];
+struct hal_shmem_header *hal_shmem;
 
 /* Adds a function to be called during the HAL shutdown. */
 int hal_add_cleanup_callback(hal_cleanup_callback_t cb)
@@ -235,7 +237,8 @@ int main(int argc, char *argv[])
 		}
 
 		hal_port_update_all();
-		shw_update_fans();
+		/* update fans and temperatures in shmem */
+		shw_update_fans(&hal_shmem->temp);
 		t1 = t2;
 	}
 
diff --git a/userspace/wrsw_hal/hal_ports.c b/userspace/wrsw_hal/hal_ports.c
index f730f6eea..c82b39002 100644
--- a/userspace/wrsw_hal/hal_ports.c
+++ b/userspace/wrsw_hal/hal_ports.c
@@ -33,7 +33,7 @@
 #define RTS_POLL_INTERVAL 200 /* ms */
 #define SFP_POLL_INTERVAL 1000 /* ms */
 
-static void *hal_port_shmem;
+extern struct hal_shmem_header *hal_shmem;
 
 /* Port table: the only item which is not "hal_port_*", as it's much used */
 static struct hal_port_state *ports;
@@ -184,8 +184,7 @@ static int hal_port_init(int index)
 int hal_port_init_all()
 {
 	int index;
-	struct hal_shmem_header *hal_hdr;
-	struct wrs_shm_head *head;
+	struct wrs_shm_head *hal_shmem_hdr;
 
 	pr_info("Initializing switch ports...\n");
 
@@ -202,24 +201,23 @@ int hal_port_init_all()
 	}
 	/* Allocate the ports in shared memory, so wr_mon etc can see them
 	   Use lock since some (like rtud) wait for hal to be available */
-	hal_port_shmem = wrs_shm_get(wrs_shm_hal, "wrsw_hal",
+	hal_shmem_hdr = wrs_shm_get(wrs_shm_hal, "wrsw_hal",
 				WRS_SHM_WRITE | WRS_SHM_LOCKED);
-	if (!hal_port_shmem) {
+	if (!hal_shmem_hdr) {
 		fprintf(stderr, "%s: Can't join shmem: %s\n", __func__,
 			strerror(errno));
 		return -1;
 	}
-	head = hal_port_shmem;
-	hal_hdr = wrs_shm_alloc(hal_port_shmem, sizeof(*hal_hdr));
-	ports = wrs_shm_alloc(hal_port_shmem,
+	hal_shmem = wrs_shm_alloc(hal_shmem_hdr, sizeof(*hal_shmem));
+	ports = wrs_shm_alloc(hal_shmem_hdr,
 			      sizeof(struct hal_port_state)
 			      * HAL_MAX_PORTS);
-	if (!hal_hdr ||  !ports) {
+	if (!hal_shmem || !ports) {
 		fprintf(stderr, "%s: can't allocate in shmem\n", __func__);
 		return -1;
 	}
 
-	hal_hdr->ports = ports;
+	hal_shmem->ports = ports;
 
 	for (index = 0; index < HAL_MAX_PORTS; index++)
 		if (hal_port_init(index) < 0)
@@ -230,14 +228,14 @@ int hal_port_init_all()
 	      hal_port_nports);
 
 	/* We are done, mark things as valid */
-	hal_hdr->nports = hal_port_nports;
-	head->version = HAL_SHMEM_VERSION;
+	hal_shmem->nports = hal_port_nports;
+	hal_shmem_hdr->version = HAL_SHMEM_VERSION;
 
 	/* Release processes waiting for HAL's to fill shm with correct data
 	   When shm is opened successfully data in shm is still not populated!
 	   Read data with wrs_shm_seqbegin and wrs_shm_seqend!
 	   Especially for nports it is important */
-	wrs_shm_write(head, WRS_SHM_WRITE_END);
+	wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
 
 	/* Create a WRIPC server for HAL public API */
 	return hal_init_wripc(ports);
-- 
GitLab