lpcmanager

Parents 998c52331037
Children 71b964068f20
Replaced RS485 RTS with GPIO. Added delay after transmit's write to cope with non blocking write, read received buffer in a loop until completion or timeout. NOTE : non realtime behavior of Linux UART driver may lead to write error since write may not finish befor receive mode is set again.
  • +208 -47
    LPCBus.py
  • --- a/LPCBus.py Wed Dec 10 18:32:59 2014 +0100
    +++ b/LPCBus.py Thu Dec 11 17:54:34 2014 +0100
    @@ -210,26 +210,155 @@
    perror("closeserial()");
    }
    -int setRTS(int fd)
    +/*------------------------- 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 *RS485_GPIO_dev;
    +
    +int write_file_bool(int fd, int value)
    {
    - int bit = TIOCM_RTS;
    - if (ioctl(fd, TIOCMBIS, &bit) == -1) {
    - perror("setRTS(): TIOCMGET");
    - return 0;
    + int ret;
    +
    + ret = write(fd, value?"1":"0", 1);
    + if (ret < 0) {
    + ERROR("write error\\n");
    + return ret;
    }
    - return 1;
    + if (lseek(fd, 0, SEEK_SET) < 0) {
    + ERROR("lseek error\\n");
    + return ret;
    + }
    +
    + return ret;
    }
    -int clearRTS(int fd)
    +#define BUFF_SIZE 256
    +struct gpio_device *gpio_open(int aGpioNum)
    {
    - int bit = TIOCM_RTS;
    - if (ioctl(fd, TIOCMBIC, &bit) == -1) {
    - perror("clearRTS(): TIOCMGET");
    - return 0;
    + 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;
    }
    - return 1;
    +
    + dev->port_num = aGpioNum;
    + dev->pin_file = pin_file;
    +
    + return dev;
    }
    +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;
    +}
    +
    +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;
    +}
    +
    +int TransmitMode(int fd)
    +{
    + return gpio_set_pin_value(RS485_GPIO_dev, 1);
    +}
    +
    +int RecieveMode(int fd)
    +{
    + return gpio_set_pin_value(RS485_GPIO_dev, 0);
    +}
    +
    +/*------------------------------------------------------------------------------*/
    +
    int openserial(char *devicename)
    {
    int fd;
    @@ -246,16 +375,17 @@
    }
    attr = oldterminfo;
    attr.c_oflag = 0;
    + attr.c_iflag = 0;
    + attr.c_lflag = 0;
    - // attr.c_cflag |= CRTSCTS | CLOCAL;
    + attr.c_cflag = 0;
    + attr.c_cflag |= CREAD;
    attr.c_cflag |= CLOCAL;
    - attr.c_cflag &= ~CRTSCTS;
    - attr.c_cflag &= ~PARENB; /* no parity */
    - attr.c_cflag &= ~CSTOPB; /* 1 stop bit */
    - attr.c_cflag &= ~CSIZE;
    attr.c_cflag |= CS8 ; /* 8 bits */
    + /* no parity, 1 stop bit */
    - cfsetospeed(&attr, baud); /* baud rate */
    + cfsetspeed(&attr, baud); /* baud rate */
    +
    if (tcflush(fd, TCIOFLUSH) == -1) {
    perror("openserial(): tcflush()");
    return 0;
    @@ -265,8 +395,7 @@
    return 0;
    }
    - /* Turn to write mode*/
    - setRTS(fd);
    + TransmitMode(fd);
    return fd;
    }
    @@ -330,7 +459,6 @@
    {
    int i;
    while (rt_task_sleep_until(TM_INFINITE) == -EINTR){
    - printf("Hellllo world\\n");
    if(!rt_mutex_acquire(&UART_WriteMutex, TM_INFINITE )){
    if(uartDevWriteBuf_plc_state == FULL){
    uartDevWriteBuf_t *uartDevWriteBuf_tmp;
    @@ -459,6 +587,8 @@
    fd_set set;
    struct timeval timeout;
    int rv;
    + RTIME now;
    + int count = 0;
    // writeBuf[45] = address;
    writeBuf[45] = 2;
    @@ -466,41 +596,66 @@
    Checksum((unsigned char*)writeBuf+1);
    writeBuf[0] = 'S';
    - //{
    - // int i;
    - // for (i=0; i<UART_BUFSIZE; i++){
    - // printf("|%%c:%%d", writeBuf[i], writeBuf[i]);
    - // }
    - // printf("\\n");
    - //}
    - //rt_task_sleep(rt_timer_ns2ticks(500000));
    +
    + tcflush(UART_fd, TCIOFLUSH);
    +
    + now = rt_timer_read();
    if(write(UART_fd, writeBuf, UART_BUFSIZE) != UART_BUFSIZE){
    goto UARTDevfail;
    }
    - FD_ZERO(&set); /* clear the set */
    - FD_SET(UART_fd, &set); /* add our file descriptor to the set */
    -
    - timeout.tv_sec = 0;
    - timeout.tv_usec = 50000;
    -
    + /* Sleep until transmission completes + 0.5ms safety */
    + rt_task_sleep_until(
    + now + rt_timer_ns2ticks(
    + 1000000000LL * UART_BUFSIZE * 10 / 115200
    + + 500000));
    +
    /* Turn to listen mode*/
    - clearRTS(UART_fd);
    + RecieveMode(UART_fd);
    +
    + while(count < UART_BUFSIZE){
    - rv = select(UART_fd + 1, &set, NULL, NULL, &timeout);
    - if(rv == -1)
    - perror("select"); /* an error accured */
    - else if(rv == 0)
    - printf("timeout"); /* a timeout occured */
    - else if(read(UART_fd, tmp, UART_BUFSIZE) == UART_BUFSIZE){
    - memcpy(readBuf,tmp,UART_BUFSIZE);
    + FD_ZERO(&set); /* clear the set */
    + FD_SET(UART_fd, &set); /* add our file descriptor to the set */
    +
    + timeout.tv_sec = 0;
    + timeout.tv_usec = 50000;
    +
    + rv = select(UART_fd + 1, &set, NULL, NULL, &timeout);
    + if(rv == -1)
    + printf("select error\\n");
    + else if(rv == 0)
    + {
    + printf("timeout\\n");
    + break;
    + }
    + else {
    + int rr = read(UART_fd, tmp + count, UART_BUFSIZE - count);
    + if(rr > 0){
    + count += rr;
    + }else{
    + printf("read error %%d\\n",rr);
    + }
    + }
    + }
    +
    + // {
    + // int i;
    + // for (i=0; i<UART_BUFSIZE; i++){
    + // printf("|%%c:%%d", tmp[i], tmp[i]);
    + // }
    + // printf("\\n");
    + // }
    +
    + /* Turn to transmit mode*/
    + TransmitMode(UART_fd);
    +
    + if(count == UART_BUFSIZE){
    + memcpy(readBuf,tmp+1,UART_BUFSIZE-1);
    return;
    }
    - /* Turn to transmit mode*/
    - setRTS(UART_fd);
    -
    UARTDevfail:
    tcflush(UART_fd, TCIOFLUSH);
    }
    @@ -589,6 +744,7 @@
    "init":"""
    int err;
    char *serialdev = "/dev/ttyAPP1";
    +int RS485_GPIO_NUM = 103;
    uartDevWriteBuf_plc_state = EMPTY;
    uartDevReadBuf_plc_state = EMPTY;
    @@ -612,9 +768,13 @@
    if((err = rt_mutex_create (&UART_ReadMutex, "UART_ReadMutex")))
    return err;
    +RS485_GPIO_dev = gpio_open(RS485_GPIO_NUM);
    +if (!RS485_GPIO_dev) {
    + fprintf(stderr, "Error while initializing RS485 GPIO.\\n");
    + return 1;
    +}
    UART_fd = openserial(serialdev);
    -
    if (!UART_fd) {
    fprintf(stderr, "Error while initializing %%s.\\n", serialdev);
    return 1;
    @@ -672,6 +832,7 @@
    rt_task_delete(&UART_task);
    rt_task_join(&UART_task);
    closeserial(UART_fd);
    +gpio_close(RS485_GPIO_dev);
    rt_mutex_delete(&UART_WriteMutex);
    rt_mutex_delete(&UART_ReadMutex);
    """,