misc/sysmobts_misc.c: Read temperature from microcontroller
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>
This commit is contained in:
parent
21104720f7
commit
e030dfd443
10
configure.ac
10
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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue