[osmo-bts,v4] misc/sysmobts_misc.c: Read temperature from microcontroller
diff mbox

Message ID 20140312151645.30964.44435.stgit@Ph0enix
State Accepted
Headers show

Commit Message

Alvaro Neira March 12, 2014, 3:19 p.m. UTC
From: Álvaro Neira Ayuso <anayuso@sysmocom.de>

Add function for requesting the temperature information to the
microcontroller. I have added a function that we can extend
for requesting more information but in this case we only need to
know the temperature.
I have added to a microcontroller temperature handling function
in the manager for monitoring this information.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
---
v4: Fixed the configure for considering if we are in a sbts2050 or not
and compile the code that we will use.

 configure.ac                            |   10 ++
 src/osmo-bts-sysmo/misc/sysmobts_mgr.c  |   56 ++++++++++
 src/osmo-bts-sysmo/misc/sysmobts_misc.c |  172 +++++++++++++++++++++++++++++++
 src/osmo-bts-sysmo/misc/sysmobts_misc.h |   15 +++
 4 files changed, 253 insertions(+)

Patch
diff mbox

diff --git a/configure.ac b/configure.ac
index 3411017..fa75274 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,16 @@  AC_CHECK_HEADER([openbsc/gsm_data_shared.h],[],
 	[])
 CPPFLAGS=$oldCPPFLAGS
 
+# Check for the sbts2050_header.h that was added after the 3.6 release
+AC_CHECK_HEADER([sysmocom/femtobts/sbts2050_header.h],
+		[sysmo_uc_header="yes"],[])
+
+if test "$sysmo_uc_header" = "yes" ; then
+	AC_DEFINE(BUILD_SBTS2050, 1, [Define if we want to build SBTS2050])
+fi
+AM_CONDITIONAL(BUILD_SBTS2050, test "x$sysmo_uc_header" = "xyes")
+AM_CONFIG_HEADER(btsconfig.h)
+
 AC_OUTPUT(
     src/Makefile
     src/common/Makefile
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
index 171f79b..3a2c10c 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
@@ -35,6 +35,7 @@ 
 #include <osmocom/core/application.h>
 #include <osmocom/core/timer.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/serial.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 
@@ -53,6 +54,58 @@  void *tall_mgr_ctx;
 /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */
 #define HOURS_TIMER_SECS	(1 * 3600)
 
+#ifdef BUILD_SBTS2050
+static struct osmo_timer_list temp_uc_timer;
+static void check_uctemp_timer_cb(void *data)
+{
+	int temp_pa = 0, temp_board = 0;
+	struct uc *ucontrol0 = data;
+
+	sbts2050_uc_check_temp(ucontrol0, &temp_pa, &temp_board);
+
+	osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0);
+}
+#endif
+
+static void initialize_sbts2050(void)
+{
+#ifdef BUILD_SBTS2050
+	static struct uc ucontrol0 = {
+		.id = 0,
+		.path = "/dev/ttyS0"
+	};
+	int val;
+
+	if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) {
+		LOGP(DFIND, LOGL_ERROR,
+		     "Failed to get Model number\n");
+		return;
+	}
+
+	if (val == 2050) {
+		if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) {
+			LOGP(DFIND, LOGL_ERROR,
+			     "Failed to get the TRX number\n");
+			return;
+		}
+
+		if (val != 0)
+			return;
+	}
+
+	ucontrol0.fd = osmo_serial_init(ucontrol0.path, 115200);
+	if (ucontrol0.fd < 0) {
+		LOGP(DFIND, LOGL_ERROR,
+		     "Failed to open the serial interface\n");
+		return;
+	}
+
+	temp_uc_timer.cb = check_uctemp_timer_cb;
+	temp_uc_timer.data = &ucontrol0;
+	check_uctemp_timer_cb(&ucontrol0);
+#endif
+}
+
 static struct osmo_timer_list temp_timer;
 static void check_temp_timer_cb(void *unused)
 {
@@ -309,6 +362,9 @@  int main(int argc, char **argv)
 	hours_timer.cb = hours_timer_cb;
 	hours_timer_cb(NULL);
 
+	/* start uc temperature check timer */
+	initialize_sbts2050();
+
 	/* handle broadcast messages for ipaccess-find */
 	fd.cb = ipaccess_bcast;
 	rc = osmo_sock_init_ofd(&fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c
index c043045..55a7a2a 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c
@@ -32,14 +32,186 @@ 
 
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
 #include <osmocom/core/application.h>
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 
+#include "btsconfig.h"
 #include "sysmobts_misc.h"
 #include "sysmobts_par.h"
 #include "sysmobts_mgr.h"
 
+#ifdef BUILD_SBTS2050
+#include <sysmocom/femtobts/sbts2050_header.h>
+#endif
+
+#define SERIAL_ALLOC_SIZE	300
+#define SIZE_HEADER_RSP		5
+#define SIZE_HEADER_CMD		4
+
+
+#ifdef BUILD_SBTS2050
+/**********************************************************************
+ *	Functions read/write from serial interface
+ *********************************************************************/
+static int hand_serial_read(int fd, struct msgb *msg, int numbytes)
+{
+	int rc, bread = 0;
+
+	if (numbytes > msgb_tailroom(msg))
+		return -ENOSPC;
+
+	while (bread < numbytes) {
+		rc = read(fd, msg->tail, numbytes - bread);
+		if (rc < 0)
+			return -1;
+		if (rc == 0)
+			break;
+
+		bread += rc;
+		msgb_put(msg, rc);
+	}
+
+	return bread;
+}
+
+static int hand_serial_write(int fd, struct msgb *msg)
+{
+	int rc, bwritten = 0;
+
+	while (msg->len > 0) {
+		rc = write(fd, msg->data, msg->len);
+		if (rc <= 0)
+			return -1;
+
+		msgb_pull(msg, rc);
+		bwritten += rc;
+	}
+
+	return bwritten;
+}
+
+/**********************************************************************
+ *	Functions request information to Microcontroller
+ *********************************************************************/
+static void add_parity(cmdpkt_t *command)
+{
+	int n;
+	uint8_t parity = 0x00;
+	for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++)
+		parity ^= ((uint8_t *)command)[n];
+
+	command->cmd.raw[command->u8Len] = parity;
+}
+
+static struct msgb *sbts2050_ucinfo_get(struct uc *ucontrol, struct ucinfo info)
+{
+	int num, rc;
+	cmdpkt_t *command;
+	rsppkt_t *response;
+	struct msgb *msg;
+	fd_set fdread;
+	struct timeval tout = {
+		.tv_sec = 10,
+	};
+
+	switch (info.id) {
+	case SBTS2050_TEMP_RQT:
+		num = sizeof(command->cmd.tempGet);
+		break;
+	default:
+		return NULL;
+	}
+	num = num + SIZE_HEADER_CMD+1;
+
+	msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller");
+	if (msg == NULL) {
+		LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n");
+		return NULL;
+	}
+	command = (cmdpkt_t *) msgb_put(msg, num);
+
+	command->u16Magic = 0xCAFE;
+	switch (info.id) {
+	case SBTS2050_TEMP_RQT:
+		command->u8Id = info.id;
+		command->u8Len = sizeof(command->cmd.tempGet);
+		break;
+	default:
+		goto err;
+	}
+
+	add_parity(command);
+
+	if (hand_serial_write(ucontrol->fd, msg) < 0)
+		goto err;
+
+	msgb_reset(msg);
+
+	FD_ZERO(&fdread);
+	FD_SET(ucontrol->fd, &fdread);
+
+	num = SIZE_HEADER_RSP;
+	while (1) {
+		rc = select(ucontrol->fd+1, &fdread, NULL, NULL, &tout);
+		if (rc > 0) {
+			if (hand_serial_read(ucontrol->fd, msg, num) < 0)
+				goto err;
+
+			response = (rsppkt_t *)msg->data;
+
+			if (response->u8Id != info.id || msg->len <= 0 ||
+			    response->i8Error != RQT_SUCCESS)
+				goto err;
+
+			if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1)
+				break;
+
+			num = response->u8Len + 1;
+		} else
+			goto err;
+	}
+
+	return msg;
+
+err:
+	msgb_free(msg);
+	return NULL;
+}
+#endif
+
+/**********************************************************************
+ *	Uc temperature handling
+ *********************************************************************/
+void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board)
+{
+#ifdef BUILD_SBTS2050
+	rsppkt_t *response;
+	struct msgb *msg;
+	struct ucinfo info = {
+		.id = SBTS2050_TEMP_RQT,
+	};
+
+	msg = sbts2050_ucinfo_get(ucontrol, info);
+
+	if (msg == NULL) {
+		LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n");
+		return;
+	}
+
+	response = (rsppkt_t *)msg->data;
+
+	*temp_board = response->rsp.tempGet.i8BrdTemp;
+	*temp_pa = response->rsp.tempGet.i8PaTemp;
+
+	LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n"
+				"Tempeture PA: %+3d C\n",
+				 response->rsp.tempGet.i8BrdTemp,
+				 response->rsp.tempGet.i8PaTemp);
+	msgb_free(msg);
+#endif
+}
 
 /*********************************************************************
  * Temperature handling
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
index 8f7da47..3c6513e 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
@@ -13,11 +13,26 @@  enum sysmobts_temp_type {
 	_NUM_TEMP_TYPES
 };
 
+struct uc {
+	int id;
+	int fd;
+	const char *path;
+};
+
+struct ucinfo {
+	uint16_t id;
+	int master;
+	int slave;
+	int pa;
+};
+
 int sysmobts_temp_get(enum sysmobts_temp_sensor sensor,
 		      enum sysmobts_temp_type type);
 
 void sysmobts_check_temp(int no_eeprom_write);
 
+void sbts2050_uc_check_temp(struct uc *ucontrol, int *temp_pa, int *temp_board);
+
 int sysmobts_update_hours(int no_epprom_write);
 
 enum sysmobts_firmware_type {