summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2017-07-11 22:04:07 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-07-11 22:04:07 +0000
commit1372a8e7ddfadb429dac5d5aa8cf45a89db38cac (patch)
treed217636b10c934bd8d189be7f6e594dbb5e8b033
parent26300862413fadf6aec6397af8eb036244a36a54 (diff)
parent4e48ddb4f112c22691b41af8095cc163aa2e71e2 (diff)
downloadcontexthub-1372a8e7ddfadb429dac5d5aa8cf45a89db38cac.tar.gz
stm32_flash: Add UART support am: 6b28f6924b am: 65120a08d9
am: 4e48ddb4f1 Change-Id: Ia6a95e4aa69f55ae305874fe53cea640990d9a7c
-rw-r--r--util/stm32_flash/Android.mk3
-rw-r--r--util/stm32_flash/flash.c32
-rw-r--r--util/stm32_flash/stm32_bl.c9
-rw-r--r--util/stm32_flash/stm32_bl.h1
-rw-r--r--util/stm32_flash/uart.c117
-rw-r--r--util/stm32_flash/uart.h35
6 files changed, 185 insertions, 12 deletions
diff --git a/util/stm32_flash/Android.mk b/util/stm32_flash/Android.mk
index 79a51659..3063c0ca 100644
--- a/util/stm32_flash/Android.mk
+++ b/util/stm32_flash/Android.mk
@@ -25,7 +25,8 @@ LOCAL_SRC_FILES := \
i2c.c \
spi.c \
stm32_bl.c \
- stm32f4_crc.c
+ stm32f4_crc.c \
+ uart.c
LOCAL_CFLAGS := -Wall -Werror -Wextra
diff --git a/util/stm32_flash/flash.c b/util/stm32_flash/flash.c
index 3f3ab24c..6a1adb8d 100644
--- a/util/stm32_flash/flash.c
+++ b/util/stm32_flash/flash.c
@@ -31,6 +31,13 @@
#include "stm32f4_crc.h"
#include "i2c.h"
#include "spi.h"
+#include "uart.h"
+
+enum USE_INTERFACE {
+ USE_SPI,
+ USE_I2C,
+ USE_UART,
+};
static inline size_t pad(ssize_t length)
{
@@ -65,8 +72,9 @@ int main(int argc, char *argv[])
uint32_t crc;
i2c_handle_t i2c_handle;
spi_handle_t spi_handle;
+ uart_handle_t uart_handle;
handle_t *handle;
- char options[] = "d:e:w:a:t:r:l:g:csi";
+ char options[] = "d:e:w:a:t:r:l:g:csiu";
char *dev = device;
int opt;
uint32_t address = 0x08000000;
@@ -77,7 +85,7 @@ int main(int argc, char *argv[])
uint8_t type = 0x11;
ssize_t length = 0;
uint8_t ret;
- bool use_spi = true;
+ int use_iface = USE_SPI;
int fd;
int gpio;
FILE *file;
@@ -88,6 +96,7 @@ int main(int argc, char *argv[])
printf("Usage: %s\n", argv[0]);
printf(" -s (use spi. default)\n");
printf(" -i (use i2c)\n");
+ printf(" -u (use uart)\n");
printf(" -g <gpio> (reset gpio. default: %d)\n", gpio_nreset);
printf(" -d <device> (device. default: %s)\n", device);
printf(" -e <sector> (sector to erase)\n");
@@ -128,10 +137,13 @@ int main(int argc, char *argv[])
type = strtol(optarg, NULL, 0);
break;
case 's':
- use_spi = true;
+ use_iface = USE_SPI;
break;
case 'i':
- use_spi = false;
+ use_iface = USE_I2C;
+ break;
+ case 'u':
+ use_iface = USE_UART;
break;
case 'g':
gpio_nreset = strtol(optarg, NULL, 0);
@@ -139,7 +151,10 @@ int main(int argc, char *argv[])
}
}
- fd = open(dev, O_RDWR);
+ if (use_iface == USE_UART)
+ fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
+ else
+ fd = open(dev, O_RDWR);
if (fd < 0) {
perror("Error opening dev");
return -1;
@@ -158,11 +173,16 @@ int main(int argc, char *argv[])
nanosleep(&ts, NULL);
}
- if (use_spi) {
+ if (use_iface == USE_SPI) {
handle = &spi_handle.handle;
spi_handle.fd = fd;
val = spi_init(handle);
+ } else if (use_iface == USE_UART) {
+ handle = &uart_handle.handle;
+ uart_handle.fd = fd;
+
+ val = uart_init(handle);
} else {
handle = &i2c_handle.handle;
i2c_handle.fd = fd;
diff --git a/util/stm32_flash/stm32_bl.c b/util/stm32_flash/stm32_bl.c
index 8be1a802..9f651d36 100644
--- a/util/stm32_flash/stm32_bl.c
+++ b/util/stm32_flash/stm32_bl.c
@@ -104,15 +104,14 @@ uint8_t erase_sector(handle_t *handle, uint16_t sector)
handle->write_cmd(handle, handle->cmd_erase);
ret = handle->read_ack(handle);
- if (ret == CMD_ACK)
+ if (sector < 0xFFF0 && ret == CMD_ACK) {
write_cnt(handle, 0x0000);
- if (ret == CMD_ACK)
ret = read_ack_loop(handle);
- if (ret == CMD_ACK)
+ }
+ if (ret == CMD_ACK) {
write_cnt(handle, sector);
- if (ret == CMD_ACK)
ret = read_ack_loop(handle);
-
+ }
return ret;
}
diff --git a/util/stm32_flash/stm32_bl.h b/util/stm32_flash/stm32_bl.h
index 5e396b72..19b9573f 100644
--- a/util/stm32_flash/stm32_bl.h
+++ b/util/stm32_flash/stm32_bl.h
@@ -67,6 +67,7 @@ uint8_t write_memory(handle_t *handle, uint32_t addr, uint32_t length, uint8_t *
#define CMD_WRITE_UNPROTECT_NS 0x74
#define CMD_BUSY 0x76
#define CMD_ACK 0x79
+#define CMD_UART_ENABLE 0x7F
#define CMD_READOUT_PROTECT 0x82
#define CMD_READOUT_PROTECT_NS 0x83
#define CMD_READOUT_UNPROTECT 0x92
diff --git a/util/stm32_flash/uart.c b/util/stm32_flash/uart.c
new file mode 100644
index 00000000..4ea08995
--- /dev/null
+++ b/util/stm32_flash/uart.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/i2c-dev.h>
+
+#include "stm32_bl.h"
+#include "uart.h"
+
+uint8_t uart_write_data(handle_t *handle, uint8_t *buffer, int length)
+{
+ uart_handle_t *uart_handle = (uart_handle_t *)handle;
+
+ buffer[length] = checksum(handle, buffer, length);
+
+ if (write(uart_handle->fd, buffer, length + 1) == (length + 1))
+ return CMD_ACK;
+ else
+ return CMD_NACK;
+}
+
+uint8_t uart_write_cmd(handle_t *handle, uint8_t cmd)
+{
+ uart_handle_t *uart_handle = (uart_handle_t *)handle;
+ uint8_t buffer[2 * sizeof(uint8_t)] = { cmd, ~cmd };
+ int length = 2 * sizeof(uint8_t);
+
+ if (cmd == CMD_UART_ENABLE)
+ length--;
+
+ if (write(uart_handle->fd, buffer, length) == length)
+ return CMD_ACK;
+ else
+ return CMD_NACK;
+}
+
+uint8_t uart_read_data(handle_t *handle, uint8_t *data, int length)
+{
+ uart_handle_t *uart_handle = (uart_handle_t *)handle;
+
+ if (read(uart_handle->fd, data, length) == length)
+ return CMD_ACK;
+ else
+ return CMD_NACK;
+}
+
+uint8_t uart_read_ack(handle_t *handle)
+{
+ uint8_t buffer;
+
+ if (handle->read_data(handle, &buffer, sizeof(uint8_t)) == CMD_ACK)
+ return buffer;
+ else
+ return CMD_BUSY;
+}
+
+int uart_init(handle_t *handle)
+{
+ uart_handle_t *uart_handle = (uart_handle_t *)handle;
+ struct termios tio;
+ int fl;
+
+ handle->cmd_erase = CMD_ERASE;
+ handle->cmd_read_memory = CMD_READ_MEMORY;
+ handle->cmd_write_memory = CMD_WRITE_MEMORY;
+
+ handle->write_data = uart_write_data;
+ handle->write_cmd = uart_write_cmd;
+ handle->read_data = uart_read_data;
+ handle->read_ack = uart_read_ack;
+
+ /* then switch the fd to blocking */
+ fl = fcntl(uart_handle->fd, F_GETFL, 0);
+ if (fl < 0)
+ return fl;
+ fl = fcntl(uart_handle->fd, F_SETFL, fl & ~O_NDELAY);
+ if (fl < 0)
+ return fl;
+ if (tcgetattr(uart_handle->fd, &tio))
+ memset(&tio, 0, sizeof(tio));
+
+ tio.c_cflag = CS8 | CLOCAL | CREAD | PARENB;
+ cfsetospeed(&tio, B57600);
+ cfsetispeed(&tio, B57600);
+ tio.c_iflag = 0; /* turn off IGNPAR */
+ tio.c_oflag = 0; /* turn off OPOST */
+ tio.c_lflag = 0; /* turn off CANON, ECHO*, etc */
+ tio.c_cc[VTIME] = 5;
+ tio.c_cc[VMIN] = 0;
+ tcflush(uart_handle->fd, TCIFLUSH);
+ tcsetattr(uart_handle->fd, TCSANOW, &tio);
+
+ /* Init USART */
+ uart_write_cmd(handle, CMD_UART_ENABLE);
+ if (uart_read_ack(handle) == CMD_ACK)
+ return 0;
+
+ return -1;
+}
diff --git a/util/stm32_flash/uart.h b/util/stm32_flash/uart.h
new file mode 100644
index 00000000..f701d36a
--- /dev/null
+++ b/util/stm32_flash/uart.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UART_H_
+#define _UART_H_
+
+#include "stm32_bl.h"
+
+typedef struct uart_handle
+{
+ handle_t handle;
+ int fd;
+ uint8_t addr;
+} uart_handle_t;
+
+uint8_t uart_write_data(handle_t *handle, uint8_t *buffer, int length);
+uint8_t uart_write_cmd(handle_t *handle, uint8_t cmd);
+uint8_t uart_read_data(handle_t *handle, uint8_t *data, int length);
+uint8_t uart_read_ack(handle_t *handle);
+int uart_init(handle_t *handle);
+
+#endif /* _UART_H_ */