lpcmanager

d6237f99a4cf
New version of GOT changes needed on LPCManager.
#include <native/task.h>
#include <native/mutex.h>
#include <native/timer.h>
#include <unistd.h>
#include <fcntl.h>
#include <rtdm/rtdm.h>
#include "beremiz.h"
/*------------------------- GPIO -------------------------------------*/
/* from armadeus/target/packages/as_devices/c/as_gpio* */
//#ifdef DEBUG
# define ERROR(fmt, ...) printf(fmt, ##__VA_ARGS__)
//#else
//# define ERROR(fmt, ...) /*fmt, ##__VA_ARGS__*/
//#endif
struct gpio_device {
int port_num;
int pin_file; /* pin file for 2.6.29 interface*/
};
struct gpio_device *RTU_GPIO_dev;
#if defined MC9 || defined GOT
struct gpio_device *RUN_LED_dev;
#endif /* MC9/GOT */
#ifdef MC9
struct gpio_device *CAN0_EN_dev;
struct gpio_device *CAN1_EN_dev;
#endif /* MC9 */
static int write_file_bool(int fd, int value)
{
int ret;
ret = write(fd, value?"1":"0", 1);
if (ret < 0) {
ERROR("write error\n");
return ret;
}
if (lseek(fd, 0, SEEK_SET) < 0) {
ERROR("lseek error\n");
return ret;
}
return ret;
}
#define BUFF_SIZE 256
static int gpio_set_pin_value(struct gpio_device *aDev, int aValue)
{
int pin_file = aDev->pin_file;
int retval;
retval = write_file_bool(pin_file, aValue);
if (retval < 0) {
ERROR("Can't write value\n");
close(pin_file);
return -1;
}
return aValue;
}
static struct gpio_device *gpio_open(int aGpioNum)
{
struct gpio_device *dev;
int pin_file;
int export_file;
int gpio_dir_fd;
int retval;
char buf[BUFF_SIZE];
int ret = 0;
export_file = open("/sys/class/gpio/export", O_WRONLY);
if (export_file < 0) {
ERROR("Can't open /sys/class/gpio/export\nBe sure that gpiolib is under your kernel\n");
return NULL;
}
snprintf(buf, BUFF_SIZE, "%%d", aGpioNum);
retval = write(export_file, buf, strlen(buf));
close(export_file);
if (retval < 0) {
ERROR("/sys/class/gpio/export can't be written\n");
return NULL;
}
snprintf(buf, BUFF_SIZE, "/sys/class/gpio/gpio%%d/direction", aGpioNum);
gpio_dir_fd = open(buf, O_WRONLY);
if (gpio_dir_fd < 0) {
ERROR("Can't open gpio%%d direction\n", aGpioNum);
return NULL;
}
ret = write(gpio_dir_fd, "out", 3);
close(gpio_dir_fd);
if (ret < 0){
ERROR("Error writing direction\n");
return NULL;
}
snprintf(buf, BUFF_SIZE, "/sys/class/gpio/gpio%%d/value", aGpioNum);
pin_file = open(buf, O_RDWR);
if (pin_file < 0) {
ERROR("Can't export gpio number %%d\n", aGpioNum);
return NULL;
}
dev = malloc(sizeof(struct gpio_device));
if (dev == NULL) {
ERROR("Can't allocate gpio_device structure\n");
close(pin_file);
return NULL;
}
dev->port_num = aGpioNum;
dev->pin_file = pin_file;
gpio_set_pin_value(dev, 1);
return dev;
}
static int gpio_close(struct gpio_device *aDev)
{
int unexport_file;
char buf[BUFF_SIZE];
int retval;
if(aDev == NULL){
ERROR("device is NULL\n");
return -1;
}
unexport_file = open("/sys/class/gpio/unexport", O_WRONLY);
if (unexport_file < 0) {
ERROR("Can't open /sys/class/gpio/unexport\nBe sure that gpiolib is under your kernel\n");
return -1;
}
snprintf(buf, BUFF_SIZE, "%%d", aDev->port_num);
retval = write(unexport_file, buf, strlen(buf));
close(unexport_file);
if (retval < 0) {
ERROR("/sys/class/gpio/unexport can't be written\n");
return -1;
}
close(aDev->pin_file);
return 0;
}
#define REG_DISCRETE_START 0 /**< Input discrete start address */
#define REG_DISCRETE_NREGS 1024 /**< 1024 bits (type: single bit, Read only) */
#define REG_COILS_START 0 /**< Coils start address */
#define REG_COILS_NREGS 1024 /**< 1024 bits (type: single bit, Read/Write) */
#define REG_INPUT_START 0 /**< Input registers start address */
#define REG_INPUT_NREGS 1024 /**< 1024 words (type: 16-bit word, Read only) */
#define REG_HOLDING_START 0 /**< Holding registers start address */
#define REG_HOLDING_NREGS 1024 /**< 1024 words (type: 16-bit word, Read/Write) */
#define MAX_MOD_RTU_DEVICES 16
typedef struct _mbRtuRdHoldingRegs {
unsigned int use;
unsigned short startAddr;
unsigned char length;
short* buffer;
} mbRtuRdHoldingRegs;
typedef struct _mbRtuRdDiscInputs {
unsigned int use;
unsigned short startAddr;
unsigned short length;
char* buffer;
// unsigned short* buffer;
} mbRtuRdDiscInputs;
typedef struct _mbRtuRdCoils {
unsigned int use;
unsigned short startAddr;
unsigned short length;
char* buffer;
} mbRtuRdCoils;
typedef struct _mbRtuWrSingleCoil {
unsigned int use;
unsigned short startAddr;
char* buffer;
} mbRtuWrSingleCoil;
typedef struct _mbRtuWrCoils {
unsigned int use;
unsigned short startAddr;
unsigned short length;
char* buffer;
} mbRtuWrCoils;
typedef struct _mbRtuRdInputRegs {
unsigned int use;
unsigned short startAddr;
unsigned char length;
short* buffer;
} mbRtuRdInputRegs;
typedef struct _mbRtuWrSingleReg {
unsigned int use;
unsigned short startAddr;
short* buffer;
} mbRtuWrSingleReg;
typedef struct _mbRtuWrMultiRegs {
unsigned int use;
unsigned short startAddr;
unsigned char length;
short* buffer;
} mbRtuWrMultiRegs;
typedef struct _mbRtuSlaveConfig {
unsigned char slaveAddr;
mbRtuRdDiscInputs rdDiscInputs;
mbRtuRdCoils rdCoils;
mbRtuWrSingleCoil wrSingleCoil;
mbRtuWrCoils wrCoils;
mbRtuRdInputRegs rdInputRegs;
mbRtuRdHoldingRegs rdHoldingRegs;
mbRtuWrSingleReg wrSingleReg;
mbRtuWrMultiRegs wrMultiRegs;
} mbRtuSlaveConfig;
typedef enum
{
MB_PAR_ODD = 0, /**< ODD parity. */
MB_PAR_EVEN = 1, /**< Even parity. */
MB_PAR_NONE = 2 /**< No parity. */
} eMBSerialParity;
mbRtuSlaveConfig mbRtuSlaveDev[MAX_MOD_RTU_DEVICES];/**< Tables containing information about connected Modbus network devices (initialized by Composer) */
commTimer mbRtuDevTim[MAX_MOD_RTU_DEVICES]; /**< Table of timers (one for each position) */
short usRegInputValue[REG_INPUT_NREGS]; /**< Array of Modbus input registers */
short usRegHoldingValue[REG_HOLDING_NREGS]; /**< Array of Modbus holding registers */
char ubCoilValue[REG_COILS_NREGS/8]; /**< Array of Modbus coils (8 coils per byte) */
char ubRegDiscreteValue[REG_DISCRETE_NREGS/8]; /**< Array of Modbus discrete inputs (8 inputs per byte) */
unsigned long mbBaudRate = 115200; /**< Modbus baud-rate setting: 9600, 19200, 38400, 57600, 115200 */
eMBSerialParity mbParity = MB_PAR_NONE; /**< Modbus parity setting: odd, even, none */
/* prototypes for functions defined in shared library */
int mbmrtu_init(unsigned long ulBaudRate, eMBSerialParity eParity);
void mbmrtu_BusUpdate(int);
int mbmrtu_cleanup(void);
static RT_TASK RTU_UART_task;
static RT_TASK RTU_task;
static RT_MUTEX RTU_BuffMutex;
void LockMBRTUBuffer(void){
while ( rt_mutex_acquire(&RTU_BuffMutex, TM_INFINITE ) == -EINTR);
}
void UnLockMBRTUBuffer(void){
rt_mutex_release(&RTU_BuffMutex);
}
typedef struct {
void*(*RTU_UART_task_proc)(void *);
void* xSerHdl;
} MB_xeno_task_adaptor_t;
static MB_xeno_task_adaptor_t MB_xeno_task_adaptor_data;
void MB_xeno_task_adaptor(void* param)
{
MB_xeno_task_adaptor_t *d = param;
d->RTU_UART_task_proc(d->xSerHdl);
}
int CreateMBRTUSerialTask(
void*(*RTU_UART_task_proc)(void *),
void* param)
{
int err;
MB_xeno_task_adaptor_data.RTU_UART_task_proc = RTU_UART_task_proc;
MB_xeno_task_adaptor_data.xSerHdl = param;
if((err = rt_task_start(&RTU_UART_task,
MB_xeno_task_adaptor,
&MB_xeno_task_adaptor_data)) != 0)
return err;
return 0;
}
#define nsTOus(ns) (ns/1000L)
#define nsTOms(ns) (ns/1000000L)
#define INVALID_RTU_ADDR 255 /* Used when no Modbus RTU slave device is present */
static void mbmrtu_BusUpdate_proc(void *param){
uint64_t actTime;
while (rt_task_sleep_until(TM_INFINITE) == -EINTR){
int i;
for(i=0;i<MAX_MOD_RTU_DEVICES;i++)
{
if(mbRtuSlaveDev[i].slaveAddr != INVALID_RTU_ADDR)
{
if(mbRtuDevTim[i].status != TIM_DISABLED)
{
actTime = (uint64_t)nsTOms(rt_timer_read());
mbRtuDevTim[i].actValue += actTime - mbRtuDevTim[i].oldTime;
mbRtuDevTim[i].oldTime = actTime;
if(mbRtuDevTim[i].actValue < mbRtuDevTim[i].toValue)
mbRtuDevTim[i].status = TIM_EN_RUNNING;
else
mbRtuDevTim[i].status = TIM_EN_EXPIRED;
}
/* Check if communication depends on timer - if it does, check timer status */
if((mbRtuDevTim[i].status == TIM_DISABLED) || (mbRtuDevTim[i].status == TIM_EN_EXPIRED))
{
mbmrtu_BusUpdate(i);
/* If timer is enabled, reset it's value, otherwise keep it disabled */
if(mbRtuDevTim[i].status != TIM_DISABLED)
{
mbRtuDevTim[i].actValue = 0; /* Reset timer value */
mbRtuDevTim[i].status = TIM_EN_RUNNING;
}
else /* Keep timer disabled */
mbRtuDevTim[i].status = TIM_DISABLED;
}
}
}
}
}
RTIME now;
void TransmitMode(void){
gpio_set_pin_value(RTU_GPIO_dev, 1);
now = rt_timer_read();
}
void RecieveMode(int us){
while(rt_task_sleep_until(
now + rt_timer_ns2ticks(1000LL*us)
) == -EINTR);
gpio_set_pin_value(RTU_GPIO_dev, 0);
}
#ifdef GOT
#define MAX_ONBOARD_DEVICES 2
#define ONBOARD_READ_BUFSIZE 30
#define ONBOARD_WRITE_BUFSIZE 30
typedef char onBoardReadBuf_t[MAX_ONBOARD_DEVICES][ONBOARD_READ_BUFSIZE];
typedef char onBoardWriteBuf_t[MAX_ONBOARD_DEVICES][ONBOARD_WRITE_BUFSIZE];
typedef char onBoardDev_t[MAX_ONBOARD_DEVICES][2];
typedef struct {
onBoardDev_t onBoardDev;
unsigned long long common_ticktime__;
} onBoardBusInit_t;
#define RTIOC_TYPE_SMT_ONBOARD RTDM_CLASS_EXPERIMENTAL
#define RTSMT_ONBOARD_RTIOC_INIT _IOR(RTIOC_TYPE_SMT_ONBOARD, 0x00, onBoardBusInit_t)
#define RTSMT_ONBOARD_RTIOC_READ _IOR(RTIOC_TYPE_SMT_ONBOARD, 0x01, onBoardReadBuf_t)
#define RTSMT_ONBOARD_RTIOC_WRITE _IOR(RTIOC_TYPE_SMT_ONBOARD, 0x02, onBoardWriteBuf_t)
static onBoardReadBuf_t onBoardReadBuf;
static onBoardWriteBuf_t onBoardWriteBuf;
static onBoardBusInit_t onBoardBusInit;
static int onboardbusfd = -1;
#endif /* GOT */