Home | History | Annotate | Download | only in stm32_flash
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <string.h>
     18 #include <stdio.h>
     19 #include <stdint.h>
     20 #include <termios.h>
     21 #include <unistd.h>
     22 #include <sys/fcntl.h>
     23 #include <sys/ioctl.h>
     24 #include <linux/i2c-dev.h>
     25 
     26 #include "stm32_bl.h"
     27 #include "uart.h"
     28 
     29 uint8_t uart_write_data(handle_t *handle, uint8_t *buffer, int length)
     30 {
     31     uart_handle_t *uart_handle = (uart_handle_t *)handle;
     32 
     33     buffer[length] = checksum(handle, buffer, length);
     34 
     35     if (write(uart_handle->fd, buffer, length + 1) == (length + 1))
     36         return CMD_ACK;
     37     else
     38         return CMD_NACK;
     39 }
     40 
     41 uint8_t uart_write_cmd(handle_t *handle, uint8_t cmd)
     42 {
     43     uart_handle_t *uart_handle = (uart_handle_t *)handle;
     44     uint8_t buffer[2 * sizeof(uint8_t)] = { cmd, ~cmd };
     45     int length = 2 * sizeof(uint8_t);
     46 
     47     if (cmd == CMD_UART_ENABLE)
     48         length--;
     49 
     50     if (write(uart_handle->fd, buffer, length) == length)
     51         return CMD_ACK;
     52     else
     53         return CMD_NACK;
     54 }
     55 
     56 uint8_t uart_read_data(handle_t *handle, uint8_t *data, int length)
     57 {
     58     uart_handle_t *uart_handle = (uart_handle_t *)handle;
     59     int ret;
     60 
     61     while (length > 0) {
     62         ret = read(uart_handle->fd, data, length);
     63         if (ret <= 0)
     64             return CMD_NACK;
     65         data += ret;
     66         length -= ret;
     67     }
     68 
     69     return CMD_ACK;
     70 }
     71 
     72 uint8_t uart_read_ack(handle_t *handle)
     73 {
     74     uint8_t buffer;
     75 
     76     if (handle->read_data(handle, &buffer, sizeof(uint8_t)) == CMD_ACK)
     77         return buffer;
     78     else
     79         return CMD_BUSY;
     80 }
     81 
     82 int uart_init(handle_t *handle)
     83 {
     84     uart_handle_t *uart_handle = (uart_handle_t *)handle;
     85     struct termios tio;
     86     int fl;
     87 
     88     handle->cmd_erase = CMD_ERASE;
     89     handle->cmd_read_memory = CMD_READ_MEMORY;
     90     handle->cmd_write_memory = CMD_WRITE_MEMORY;
     91 
     92     handle->no_extra_sync = 1;
     93 
     94     handle->write_data = uart_write_data;
     95     handle->write_cmd = uart_write_cmd;
     96     handle->read_data = uart_read_data;
     97     handle->read_ack = uart_read_ack;
     98 
     99     /* then switch the fd to blocking */
    100     fl = fcntl(uart_handle->fd, F_GETFL, 0);
    101     if (fl < 0)
    102         return fl;
    103     fl = fcntl(uart_handle->fd, F_SETFL,  fl & ~O_NDELAY);
    104     if (fl < 0)
    105         return fl;
    106     if (tcgetattr(uart_handle->fd, &tio))
    107         memset(&tio, 0, sizeof(tio));
    108 
    109     tio.c_cflag = CS8 | CLOCAL | CREAD | PARENB;
    110     cfsetospeed(&tio, B57600);
    111     cfsetispeed(&tio, B57600);
    112     tio.c_iflag = 0; /* turn off IGNPAR */
    113     tio.c_oflag = 0; /* turn off OPOST */
    114     tio.c_lflag = 0; /* turn off CANON, ECHO*, etc */
    115     tio.c_cc[VTIME] = 5;
    116     tio.c_cc[VMIN] = 0;
    117     tcflush(uart_handle->fd, TCIFLUSH);
    118     tcsetattr(uart_handle->fd, TCSANOW, &tio);
    119 
    120     /* Init USART */
    121     uart_write_cmd(handle, CMD_UART_ENABLE);
    122     if (uart_read_ack(handle) == CMD_ACK)
    123         return 0;
    124 
    125     return -1;
    126 }
    127