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 29uint8_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 41uint8_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 56uint8_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 72uint8_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 82int 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