From 2d08b2038a5cf14a92d8ca3e10fb3421e73e5b74 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Wed, 1 Jun 2016 13:47:46 +0200 Subject: Move FPGA related commands to mgmt-fpga.c --- projects/cli-test/Makefile | 2 +- projects/cli-test/cli-test.c | 135 +------------------------------- projects/cli-test/mgmt-fpga.c | 174 ++++++++++++++++++++++++++++++++++++++++++ projects/cli-test/mgmt-fpga.h | 50 ++++++++++++ 4 files changed, 226 insertions(+), 135 deletions(-) create mode 100644 projects/cli-test/mgmt-fpga.c create mode 100644 projects/cli-test/mgmt-fpga.h (limited to 'projects/cli-test') diff --git a/projects/cli-test/Makefile b/projects/cli-test/Makefile index 39619fc..2ca61b9 100644 --- a/projects/cli-test/Makefile +++ b/projects/cli-test/Makefile @@ -1,6 +1,6 @@ TEST = cli-test -OBJS = crc32.o mgmt-cli.o test_sdram.o mgmt-dfu.o +OBJS = crc32.o mgmt-cli.o test_sdram.o mgmt-dfu.o mgmt-fpga.o CFLAGS += -I$(LIBCLI_DIR) LIBS += $(LIBCLI_DIR)/libcli.a diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index 84c268b..26ebbc2 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -40,6 +40,7 @@ #include "stm-sdram.h" #include "mgmt-cli.h" #include "mgmt-dfu.h" +#include "mgmt-fpga.h" #include "test_sdram.h" #include @@ -157,124 +158,6 @@ int cmd_show_keystore_data(struct cli_def *cli, const char *command, char *argv[ return CLI_OK; } -/* The chunk size have to be a multiple of the SPI flash page size (256 bytes), - and it has to match the chunk size in the program sending the bitstream over the UART. -*/ -#define BITSTREAM_UPLOAD_CHUNK_SIZE 4096 - -int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0, i; - uint32_t offset = 0, n = BITSTREAM_UPLOAD_CHUNK_SIZE; - uint8_t buf[BITSTREAM_UPLOAD_CHUNK_SIZE]; - - fpgacfg_access_control(ALLOW_ARM); - - cli_print(cli, "Checking if FPGA config memory is accessible"); - if (fpgacfg_check_id() != 1) { - cli_print(cli, "ERROR: FPGA config memory not accessible. Check that jumpers JP7 and JP8 are installed."); - return CLI_ERROR; - } - - cli_print(cli, "OK, write FPGA bitstream file size (4 bytes), data in 4096 byte chunks, CRC-32 (4 bytes)"); - - /* Read file size (4 bytes) */ - uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); - cli_print(cli, "File size %li", filesize); - - while (filesize) { - /* By initializing buf to the same value that erased flash has (0xff), we don't - * have to try and be smart when writing the last page of data to the memory. - */ - memset(buf, 0xff, sizeof(buf)); - - if (filesize < n) { - n = filesize; - } - - if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { - cli_print(cli, "Receive timed out"); - return CLI_ERROR; - } - filesize -= n; - - /* After reception of 4 KB but before ACKing we have "all" the time in the world to - * calculate CRC and write it to flash. - */ - my_crc = update_crc(my_crc, buf, n); - - if ((i = fpgacfg_write_data(offset, buf, BITSTREAM_UPLOAD_CHUNK_SIZE)) != 1) { - cli_print(cli, "Failed writing data at offset %li (counter = %li): %li", offset, counter, i); - return CLI_ERROR; - } - - offset += BITSTREAM_UPLOAD_CHUNK_SIZE; - - /* ACK this chunk by sending the current chunk counter (4 bytes) */ - counter++; - uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); - } - - /* The sending side will now send it's calculated CRC-32 */ - cli_print(cli, "Send CRC-32"); - uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); - cli_print(cli, "CRC-32 %li", crc); - if (crc == my_crc) { - cli_print(cli, "CRC checksum MATCHED"); - } else { - cli_print(cli, "CRC checksum did NOT match"); - } - - fpgacfg_access_control(ALLOW_FPGA); - - return CLI_OK; -} - -int cmd_fpga_bitstream_erase(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - fpgacfg_access_control(ALLOW_ARM); - - cli_print(cli, "Checking if FPGA config memory is accessible"); - if (fpgacfg_check_id() != 1) { - cli_print(cli, "ERROR: FPGA config memory not accessible. Check that jumpers JP7 and JP8 are installed."); - return CLI_ERROR; - } - - /* Erasing the whole config memory takes a while, we just need to erase the first sector. - * The bitstream has an EOF marker, so even if the next bitstream uploaded is shorter than - * the current one there should be no problem. - * - * This command could be made to accept an argument indicating the whole memory should be erased. - */ - if (! fpgacfg_erase_sectors(1)) { - cli_print(cli, "Erasing first sector in FPGA config memory failed"); - return CLI_ERROR; - } - - cli_print(cli, "Erased FPGA config memory"); - fpgacfg_access_control(ALLOW_FPGA); - - return CLI_OK; -} - -int cmd_fpga_reset(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - fpgacfg_access_control(ALLOW_FPGA); - fpgacfg_reset_fpga(RESET_FULL); - cli_print(cli, "FPGA has been reset"); - - return CLI_OK; -} - -int cmd_fpga_reset_registers(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - fpgacfg_access_control(ALLOW_FPGA); - fpgacfg_reset_fpga(RESET_REGISTERS); - cli_print(cli, "FPGA registers have been reset"); - - return CLI_OK; -} - int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "\n\n\nRebooting\n\n\n"); @@ -372,22 +255,6 @@ void configure_cli_show(struct cli_def *cli) cli_command_node(show_keystore, data, "Show the first page of the keystore memory"); } -void configure_cli_fpga(struct cli_def *cli) -{ - /* fpga */ - cli_command_root(fpga); - /* fpga reset */ - cli_command_node(fpga, reset, "Reset FPGA (config reset)"); - /* fpga reset registers */ - cli_command_node(fpga_reset, registers, "Reset FPGA registers (soft reset)"); - - cli_command_branch(fpga, bitstream); - /* fpga bitstream upload */ - cli_command_node(fpga_bitstream, upload, "Upload new FPGA bitstream"); - /* fpga bitstream erase */ - cli_command_node(fpga_bitstream, erase, "Erase FPGA config memory"); -} - void configure_cli_test(struct cli_def *cli) { /* test */ diff --git a/projects/cli-test/mgmt-fpga.c b/projects/cli-test/mgmt-fpga.c new file mode 100644 index 0000000..c20b7b2 --- /dev/null +++ b/projects/cli-test/mgmt-fpga.c @@ -0,0 +1,174 @@ +/* + * mgmt-fpga.c + * ----------- + * CLI code to manage the FPGA configuration etc. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stm-init.h" +#include "stm-uart.h" +#include "stm-fpgacfg.h" +#include "mgmt-cli.h" +#include "mgmt-fpga.h" + +#include + + +extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); + + +int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0, i; + uint32_t offset = 0, n = BITSTREAM_UPLOAD_CHUNK_SIZE; + uint8_t buf[BITSTREAM_UPLOAD_CHUNK_SIZE]; + + fpgacfg_access_control(ALLOW_ARM); + + cli_print(cli, "Checking if FPGA config memory is accessible"); + if (fpgacfg_check_id() != 1) { + cli_print(cli, "ERROR: FPGA config memory not accessible. Check that jumpers JP7 and JP8 are installed."); + return CLI_ERROR; + } + + cli_print(cli, "OK, write FPGA bitstream file size (4 bytes), data in 4096 byte chunks, CRC-32 (4 bytes)"); + + /* Read file size (4 bytes) */ + uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); + cli_print(cli, "File size %li", filesize); + + while (filesize) { + /* By initializing buf to the same value that erased flash has (0xff), we don't + * have to try and be smart when writing the last page of data to the memory. + */ + memset(buf, 0xff, sizeof(buf)); + + if (filesize < n) { + n = filesize; + } + + if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { + cli_print(cli, "Receive timed out"); + return CLI_ERROR; + } + filesize -= n; + + /* After reception of 4 KB but before ACKing we have "all" the time in the world to + * calculate CRC and write it to flash. + */ + my_crc = update_crc(my_crc, buf, n); + + if ((i = fpgacfg_write_data(offset, buf, BITSTREAM_UPLOAD_CHUNK_SIZE)) != 1) { + cli_print(cli, "Failed writing data at offset %li (counter = %li): %li", offset, counter, i); + return CLI_ERROR; + } + + offset += BITSTREAM_UPLOAD_CHUNK_SIZE; + + /* ACK this chunk by sending the current chunk counter (4 bytes) */ + counter++; + uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); + } + + /* The sending side will now send it's calculated CRC-32 */ + cli_print(cli, "Send CRC-32"); + uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); + cli_print(cli, "CRC-32 %li", crc); + if (crc == my_crc) { + cli_print(cli, "CRC checksum MATCHED"); + } else { + cli_print(cli, "CRC checksum did NOT match"); + } + + fpgacfg_access_control(ALLOW_FPGA); + + return CLI_OK; +} + +int cmd_fpga_bitstream_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + fpgacfg_access_control(ALLOW_ARM); + + cli_print(cli, "Checking if FPGA config memory is accessible"); + if (fpgacfg_check_id() != 1) { + cli_print(cli, "ERROR: FPGA config memory not accessible. Check that jumpers JP7 and JP8 are installed."); + return CLI_ERROR; + } + + /* Erasing the whole config memory takes a while, we just need to erase the first sector. + * The bitstream has an EOF marker, so even if the next bitstream uploaded is shorter than + * the current one there should be no problem. + * + * This command could be made to accept an argument indicating the whole memory should be erased. + */ + if (! fpgacfg_erase_sectors(1)) { + cli_print(cli, "Erasing first sector in FPGA config memory failed"); + return CLI_ERROR; + } + + cli_print(cli, "Erased FPGA config memory"); + fpgacfg_access_control(ALLOW_FPGA); + + return CLI_OK; +} + +int cmd_fpga_reset(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + fpgacfg_access_control(ALLOW_FPGA); + fpgacfg_reset_fpga(RESET_FULL); + cli_print(cli, "FPGA has been reset"); + + return CLI_OK; +} + +int cmd_fpga_reset_registers(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + fpgacfg_access_control(ALLOW_FPGA); + fpgacfg_reset_fpga(RESET_REGISTERS); + cli_print(cli, "FPGA registers have been reset"); + + return CLI_OK; +} + +void configure_cli_fpga(struct cli_def *cli) +{ + /* fpga */ + cli_command_root(fpga); + /* fpga reset */ + cli_command_node(fpga, reset, "Reset FPGA (config reset)"); + /* fpga reset registers */ + cli_command_node(fpga_reset, registers, "Reset FPGA registers (soft reset)"); + + cli_command_branch(fpga, bitstream); + /* fpga bitstream upload */ + cli_command_node(fpga_bitstream, upload, "Upload new FPGA bitstream"); + /* fpga bitstream erase */ + cli_command_node(fpga_bitstream, erase, "Erase FPGA config memory"); +} diff --git a/projects/cli-test/mgmt-fpga.h b/projects/cli-test/mgmt-fpga.h new file mode 100644 index 0000000..ce185de --- /dev/null +++ b/projects/cli-test/mgmt-fpga.h @@ -0,0 +1,50 @@ +/* + * mgmt-fpga.h + * ----------- + * Management FPGA related code. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STM32_CLI_MGMT_FPGA_H +#define __STM32_CLI_MGMT_FPGA_H + +#include "stm-init.h" +#include + + +/* The chunk size have to be a multiple of the SPI flash page size (256 bytes), + and it has to match the chunk size in the program sending the bitstream over the UART. +*/ +#define BITSTREAM_UPLOAD_CHUNK_SIZE 4096 + + +extern void configure_cli_fpga(struct cli_def *cli); + +#endif /* __STM32_CLI_MGMT_FPGA_H */ -- cgit v1.2.3 From 9915d1ba46e30990ea149c7a09d1d2ed0d13a331 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Wed, 1 Jun 2016 21:03:05 +0200 Subject: Implement circular buffer UART RX using interrupts. --- projects/cli-test/cli-test.c | 21 +++++++++++++++- projects/cli-test/mgmt-cli.c | 60 +++++++++++++++++++++++++++++++++++++++++--- projects/cli-test/mgmt-cli.h | 4 +++ 3 files changed, 80 insertions(+), 5 deletions(-) (limited to 'projects/cli-test') diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index 26ebbc2..b90d0dd 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -49,6 +49,9 @@ extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); +/* MGMT UART interrupt receive buffer (data will be put in a larger ring buffer) */ +volatile uint8_t uart_rx; + int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) { @@ -286,6 +289,22 @@ void do_early_dfu_jump(void) while (1); } +/* Callback for HAL_UART_Receive_IT(). */ +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == huart_mgmt.Instance) { + mgmt_cli_uart_isr((const uint8_t *) &uart_rx, 1); + + /* Set things up to receive another byte. */ + HAL_UART_Receive_IT(huart, (uint8_t *) &uart_rx, 1); + } +} + +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) +{ + led_on(LED_RED); + led_on(LED_YELLOW); +} int main() @@ -318,7 +337,7 @@ main() /* embedded_cli_loop returns when the user enters 'quit' or 'exit' */ - cli_print(&cli, "Rebooting in 4 seconds"); + cli_print(&cli, "Rebooting in 3 seconds"); HAL_Delay(3000); HAL_NVIC_SystemReset(); diff --git a/projects/cli-test/mgmt-cli.c b/projects/cli-test/mgmt-cli.c index 46faae8..abbd999 100644 --- a/projects/cli-test/mgmt-cli.c +++ b/projects/cli-test/mgmt-cli.c @@ -33,10 +33,27 @@ */ #include "stm-init.h" #include "stm-uart.h" +#include "stm-led.h" #include "mgmt-cli.h" #include +extern uint8_t uart_rx; + +struct uart_ringbuf_t { + uint32_t enabled, ridx, widx, overflow; + uint8_t buf[CLI_UART_RECVBUF_SIZE]; +}; + +volatile struct uart_ringbuf_t uart_ringbuf = {1, 0, 0, 0, {0}}; + +#define RINGBUF_RIDX(rb) (rb.ridx & CLI_UART_RECVBUF_MASK) +#define RINGBUF_WIDX(rb) (rb.widx & CLI_UART_RECVBUF_MASK) +#define RINGBUF_COUNT(rb) ((unsigned)(rb.widx - rb.ridx)) +#define RINGBUF_FULL(rb) (RINGBUF_RIDX(rb) == ((rb.widx + 1) & CLI_UART_RECVBUF_MASK)) +#define RINGBUF_READ(rb, dst) {dst = rb.buf[RINGBUF_RIDX(rb)]; rb.buf[RINGBUF_RIDX(rb)] = '.'; rb.ridx++;} +#define RINGBUF_WRITE(rb, src) {rb.buf[RINGBUF_WIDX(rb)] = src; rb.widx++;} + void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf) { char crlf[] = "\r\n"; @@ -46,8 +63,23 @@ void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *bu int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count) { - if (uart_recv_char2(STM_UART_MGMT, buf, count) != HAL_OK) { - return -1; + uint32_t timeout = 0xffffff; + + /* Always explicitly enable the RX interrupt when we get here. + * Prevents us getting stuck waiting for an interrupt that will never come. + */ + __HAL_UART_FLUSH_DRREGISTER(&huart_mgmt); + HAL_UART_Receive_IT(&huart_mgmt, (uint8_t *) &uart_rx, 1); + + while (count && timeout--) { + if (RINGBUF_COUNT(uart_ringbuf)) { + RINGBUF_READ(uart_ringbuf, *(uint8_t *) buf); + buf++; + count--; + } else { + led_toggle(LED_GREEN); + HAL_Delay(10); + } } return 1; } @@ -83,7 +115,11 @@ int embedded_cli_loop(struct cli_def *cli) n = cli_loop_read_next_char(cli, &ctx, &c); - //cli_print(cli, "Next char: '%c' (n == %i)", c, n); + /* + cli_print(cli, "Next char: '%c'/%i, ringbuf ridx %i, widx %i (%i/%i) - count %i", + c, (int) c, uart_ringbuf.ridx, uart_ringbuf.widx, RINGBUF_RIDX(uart_ringbuf), + RINGBUF_WIDX(uart_ringbuf), RINGBUF_COUNT(uart_ringbuf)); + */ if (n == CLI_LOOP_CTRL_BREAK) break; if (n == CLI_LOOP_CTRL_CONTINUE) @@ -98,7 +134,7 @@ int embedded_cli_loop(struct cli_def *cli) if (ctx.l < 0) break; - //cli_print(cli, "Process command: '%s'", ctx.cmd); + /* cli_print(cli, "Process command: '%s'", ctx.cmd); */ n = cli_loop_process_cmd(cli, &ctx); if (n == CLI_LOOP_CTRL_BREAK) break; @@ -107,6 +143,22 @@ int embedded_cli_loop(struct cli_def *cli) return CLI_OK; } +/* Interrupt service routine to be called when data has been received on the MGMT UART. */ +void mgmt_cli_uart_isr(const uint8_t *buf, size_t count) +{ + if (! uart_ringbuf.enabled) return; + + while (count) { + if (RINGBUF_FULL(uart_ringbuf)) { + uart_ringbuf.overflow++; + return; + } + RINGBUF_WRITE(uart_ringbuf, *buf); + buf++; + count--; + } +} + void mgmt_cli_init(struct cli_def *cli) { cli_init(cli); diff --git a/projects/cli-test/mgmt-cli.h b/projects/cli-test/mgmt-cli.h index dd6a58b..3b7f503 100644 --- a/projects/cli-test/mgmt-cli.h +++ b/projects/cli-test/mgmt-cli.h @@ -68,10 +68,14 @@ cli_register_command2(cli, &cmd_##name##_s, NULL) +#define CLI_UART_RECVBUF_SIZE 256 /* This must be a power of 2 */ +#define CLI_UART_RECVBUF_MASK (CLI_UART_RECVBUF_SIZE - 1) + extern void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf); extern int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count); extern int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count); extern int embedded_cli_loop(struct cli_def *cli); extern void mgmt_cli_init(struct cli_def *cli); +extern void mgmt_cli_uart_isr(const uint8_t *buf, size_t count); #endif /* __STM32_MGMT_CLI_H */ -- cgit v1.2.3 From 1b3870dd4e0429e1809ce40b70a8f558ffb5df3a Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 2 Jun 2016 13:34:04 +0200 Subject: Move the rest of the CLI commands out of cli-test.c. --- projects/cli-test/Makefile | 2 +- projects/cli-test/cli-test.c | 226 +----------------------------------------- projects/cli-test/mgmt-misc.c | 97 ++++++++++++++++++ projects/cli-test/mgmt-misc.h | 43 ++++++++ projects/cli-test/mgmt-show.c | 133 +++++++++++++++++++++++++ projects/cli-test/mgmt-show.h | 43 ++++++++ projects/cli-test/mgmt-test.c | 117 ++++++++++++++++++++++ projects/cli-test/mgmt-test.h | 43 ++++++++ 8 files changed, 481 insertions(+), 223 deletions(-) create mode 100644 projects/cli-test/mgmt-misc.c create mode 100644 projects/cli-test/mgmt-misc.h create mode 100644 projects/cli-test/mgmt-show.c create mode 100644 projects/cli-test/mgmt-show.h create mode 100644 projects/cli-test/mgmt-test.c create mode 100644 projects/cli-test/mgmt-test.h (limited to 'projects/cli-test') diff --git a/projects/cli-test/Makefile b/projects/cli-test/Makefile index 2ca61b9..acf2720 100644 --- a/projects/cli-test/Makefile +++ b/projects/cli-test/Makefile @@ -1,6 +1,6 @@ TEST = cli-test -OBJS = crc32.o mgmt-cli.o test_sdram.o mgmt-dfu.o mgmt-fpga.o +OBJS = crc32.o test_sdram.o mgmt-cli.o mgmt-dfu.c mgmt-fpga.c mgmt-misc.c mgmt-show.c mgmt-test.c CFLAGS += -I$(LIBCLI_DIR) LIBS += $(LIBCLI_DIR)/libcli.a diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index b90d0dd..b6178af 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -31,206 +31,23 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "stm32f4xx_hal.h" #include "stm-init.h" #include "stm-led.h" -#include "stm-uart.h" -#include "stm-fpgacfg.h" -#include "stm-keystore.h" -#include "stm-sdram.h" + #include "mgmt-cli.h" #include "mgmt-dfu.h" #include "mgmt-fpga.h" -#include "test_sdram.h" +#include "mgmt-misc.h" +#include "mgmt-show.h" +#include "mgmt-test.h" #include -#include - -extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); /* MGMT UART interrupt receive buffer (data will be put in a larger ring buffer) */ volatile uint8_t uart_rx; -int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - volatile uint32_t hclk; - - hclk = HAL_RCC_GetHCLKFreq(); - cli_print(cli, "HSE_VALUE: %li", HSE_VALUE); - cli_print(cli, "HCLK: %li (%i MHz)", hclk, (int) hclk / 1000 / 1000); - cli_print(cli, "SystemCoreClock: %li (%i MHz)", SystemCoreClock, (int) SystemCoreClock / 1000 / 1000); - return CLI_OK; -} - -int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - uint32_t filesize = 0, crc = 0, my_crc = 0, n = 256, counter = 0; - uint8_t buf[256]; - - cli_print(cli, "OK, write file size (4 bytes), data in %li byte chunks, CRC-32 (4 bytes)", n); - - uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); - cli_print(cli, "File size %li", filesize); - - while (filesize) { - if (filesize < n) { - n = filesize; - } - - if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { - cli_print(cli, "Receive timed out"); - return CLI_ERROR; - } - filesize -= n; - my_crc = update_crc(my_crc, buf, n); - counter++; - uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); - } - - cli_print(cli, "Send CRC-32"); - uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); - cli_print(cli, "CRC-32 %li", crc); - if (crc == my_crc) { - cli_print(cli, "CRC checksum MATCHED"); - } else { - cli_print(cli, "CRC checksum did NOT match"); - } - - return CLI_OK; -} - -int cmd_show_fpga_status(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - cli_print(cli, "FPGA has %sloaded a bitstream", fpgacfg_check_done() ? "":"NOT "); - return CLI_OK; -} - -int cmd_show_keystore_status(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - cli_print(cli, "Keystore memory is %sonline", (keystore_check_id() != 1) ? "NOT ":""); - return CLI_OK; -} - -int cmd_show_keystore_data(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - uint8_t buf[KEYSTORE_PAGE_SIZE]; - uint32_t i; - - if (keystore_check_id() != 1) { - cli_print(cli, "ERROR: The keystore memory is not accessible."); - } - - memset(buf, 0, sizeof(buf)); - if ((i = keystore_read_data(0, buf, sizeof(buf))) != 1) { - cli_print(cli, "Failed reading first page from keystore memory: %li", i); - return CLI_ERROR; - } - - cli_print(cli, "First page from keystore memory:\r\n"); - uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); - uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\n"); - - for (i = 0; i < 8; i++) { - if (buf[i] == 0xff) break; /* never written */ - if (buf[i] != 0x55) break; /* something other than a tombstone */ - } - /* As a demo, tombstone byte after byte of the first 8 bytes in the keystore memory - * (as long as they do not appear to contain real data). - * If all of them are tombstones, erase the first sector to start over. - */ - if (i < 8) { - if (buf[i] == 0xff) { - cli_print(cli, "Tombstoning byte %li", i); - buf[i] = 0x55; - if ((i = keystore_write_data(0, buf, sizeof(buf))) != 1) { - cli_print(cli, "Failed writing data at offset 0: %li", i); - return CLI_ERROR; - } - } - } else { - cli_print(cli, "Erasing first sector since all the first 8 bytes are tombstones"); - if ((i = keystore_erase_sectors(1)) != 1) { - cli_print(cli, "Failed erasing the first sector: %li", i); - return CLI_ERROR; - } - cli_print(cli, "Erase result: %li", i); - } - - return CLI_OK; -} - -int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - cli_print(cli, "\n\n\nRebooting\n\n\n"); - HAL_NVIC_SystemReset(); - while (1) {}; -} - -int cmd_test_sdram(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - // run external memory initialization sequence - HAL_StatusTypeDef status; - int ok, num_cycles = 1, i, test_completed; - - if (argc == 1) { - num_cycles = strtol(argv[0], NULL, 0); - if (num_cycles > 100) num_cycles = 100; - if (num_cycles < 1) num_cycles = 1; - } - - cli_print(cli, "Initializing SDRAM"); - status = sdram_init(); - if (status != HAL_OK) { - cli_print(cli, "Failed initializing SDRAM: %i", (int) status); - return CLI_OK; - } - - for (i = 1; i <= num_cycles; i++) { - cli_print(cli, "Starting SDRAM test (%i/%i)", i, num_cycles); - test_completed = 0; - // set LFSRs to some initial value, LFSRs will produce - // pseudo-random 32-bit patterns to test our memories - lfsr1 = 0xCCAA5533; - lfsr2 = 0xCCAA5533; - - cli_print(cli, "Run sequential write-then-read test for the first chip"); - ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP1); - if (!ok) break; - - cli_print(cli, "Run random write-then-read test for the first chip"); - ok = test_sdram_random(SDRAM_BASEADDR_CHIP1); - if (!ok) break; - - cli_print(cli, "Run sequential write-then-read test for the second chip"); - ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP2); - if (!ok) break; - - cli_print(cli, "Run random write-then-read test for the second chip"); - ok = test_sdram_random(SDRAM_BASEADDR_CHIP2); - if (!ok) break; - - // turn blue led on (testing two chips at the same time) - led_on(LED_BLUE); - - cli_print(cli, "Run interleaved write-then-read test for both chips at once"); - ok = test_sdrams_interleaved(SDRAM_BASEADDR_CHIP1, SDRAM_BASEADDR_CHIP2); - - led_off(LED_BLUE); - test_completed = 1; - cli_print(cli, "SDRAM test (%i/%i) completed\r\n", i, num_cycles); - } - - if (! test_completed) { - cli_print(cli, "SDRAM test failed (%i/%i)", i, num_cycles); - } else { - cli_print(cli, "SDRAM test completed successfully"); - } - - return CLI_OK; -} - int check_auth(const char *username, const char *password) { if (strcasecmp(username, "ct") != 0) @@ -240,41 +57,6 @@ int check_auth(const char *username, const char *password) return CLI_OK; } -void configure_cli_show(struct cli_def *cli) -{ - /* show */ - cli_command_root(show); - - /* show cpuspeed */ - cli_command_node(show, cpuspeed, "Show the speed at which the CPU currently operates"); - - cli_command_branch(show, fpga); - /* show fpga status*/ - cli_command_node(show_fpga, status, "Show status about the FPGA"); - - cli_command_branch(show, keystore); - /* show keystore status*/ - cli_command_node(show_keystore, status, "Show status of the keystore memory"); - cli_command_node(show_keystore, data, "Show the first page of the keystore memory"); -} - -void configure_cli_test(struct cli_def *cli) -{ - /* test */ - cli_command_root(test); - - /* test sdram */ - cli_command_node(test, sdram, "Run SDRAM tests"); -} - -static void configure_cli_misc(struct cli_def *cli) -{ - /* filetransfer */ - cli_command_root_node(filetransfer, "Test file transfering"); - /* reboot */ - cli_command_root_node(reboot, "Reboot the STM32"); -} - typedef void (*pFunction)(void); /* This is it's own function to make it more convenient to set a breakpoint at it in gdb */ diff --git a/projects/cli-test/mgmt-misc.c b/projects/cli-test/mgmt-misc.c new file mode 100644 index 0000000..a98bf8d --- /dev/null +++ b/projects/cli-test/mgmt-misc.c @@ -0,0 +1,97 @@ +/* + * mgmt-misc.c + * ----------- + * Miscellaneous CLI functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stm-init.h" +#include "stm-uart.h" + +#include "mgmt-cli.h" +#include "mgmt-misc.h" + +#include + + +extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); + +int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint32_t filesize = 0, crc = 0, my_crc = 0, n = 256, counter = 0; + uint8_t buf[256]; + + cli_print(cli, "OK, write file size (4 bytes), data in %li byte chunks, CRC-32 (4 bytes)", n); + + uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); + cli_print(cli, "File size %li", filesize); + + while (filesize) { + if (filesize < n) { + n = filesize; + } + + if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { + cli_print(cli, "Receive timed out"); + return CLI_ERROR; + } + filesize -= n; + my_crc = update_crc(my_crc, buf, n); + counter++; + uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); + } + + cli_print(cli, "Send CRC-32"); + uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); + cli_print(cli, "CRC-32 %li", crc); + if (crc == my_crc) { + cli_print(cli, "CRC checksum MATCHED"); + } else { + cli_print(cli, "CRC checksum did NOT match"); + } + + return CLI_OK; +} + +int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + cli_print(cli, "\n\n\nRebooting\n\n\n"); + HAL_NVIC_SystemReset(); + while (1) {}; +} + +void configure_cli_misc(struct cli_def *cli) +{ + /* filetransfer */ + cli_command_root_node(filetransfer, "Test file transfering"); + /* reboot */ + cli_command_root_node(reboot, "Reboot the STM32"); +} + diff --git a/projects/cli-test/mgmt-misc.h b/projects/cli-test/mgmt-misc.h new file mode 100644 index 0000000..caf7024 --- /dev/null +++ b/projects/cli-test/mgmt-misc.h @@ -0,0 +1,43 @@ +/* + * mgmt-misc.h + * ----------- + * Management CLI miscellaneous functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STM32_CLI_MGMT_MISC_H +#define __STM32_CLI_MGMT_MISC_H + +#include "stm-init.h" +#include + +extern void configure_cli_misc(struct cli_def *cli); + +#endif /* __STM32_CLI_MGMT_MISC_H */ diff --git a/projects/cli-test/mgmt-show.c b/projects/cli-test/mgmt-show.c new file mode 100644 index 0000000..3ae196e --- /dev/null +++ b/projects/cli-test/mgmt-show.c @@ -0,0 +1,133 @@ +/* + * mgmt-show.c + * ----------- + * CLI 'show' functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stm-init.h" +#include "stm-keystore.h" +#include "stm-fpgacfg.h" +#include "stm-uart.h" + +#include "mgmt-cli.h" +#include "mgmt-show.h" + +#include + + +int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + volatile uint32_t hclk; + + hclk = HAL_RCC_GetHCLKFreq(); + cli_print(cli, "HSE_VALUE: %li", HSE_VALUE); + cli_print(cli, "HCLK: %li (%i MHz)", hclk, (int) hclk / 1000 / 1000); + cli_print(cli, "SystemCoreClock: %li (%i MHz)", SystemCoreClock, (int) SystemCoreClock / 1000 / 1000); + return CLI_OK; +} + +int cmd_show_fpga_status(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + cli_print(cli, "FPGA has %sloaded a bitstream", fpgacfg_check_done() ? "":"NOT "); + return CLI_OK; +} + +int cmd_show_keystore_status(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + cli_print(cli, "Keystore memory is %sonline", (keystore_check_id() != 1) ? "NOT ":""); + return CLI_OK; +} + +int cmd_show_keystore_data(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint8_t buf[KEYSTORE_PAGE_SIZE]; + uint32_t i; + + if (keystore_check_id() != 1) { + cli_print(cli, "ERROR: The keystore memory is not accessible."); + } + + memset(buf, 0, sizeof(buf)); + if ((i = keystore_read_data(0, buf, sizeof(buf))) != 1) { + cli_print(cli, "Failed reading first page from keystore memory: %li", i); + return CLI_ERROR; + } + + cli_print(cli, "First page from keystore memory:\r\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\n"); + + for (i = 0; i < 8; i++) { + if (buf[i] == 0xff) break; /* never written */ + if (buf[i] != 0x55) break; /* something other than a tombstone */ + } + /* As a demo, tombstone byte after byte of the first 8 bytes in the keystore memory + * (as long as they do not appear to contain real data). + * If all of them are tombstones, erase the first sector to start over. + */ + if (i < 8) { + if (buf[i] == 0xff) { + cli_print(cli, "Tombstoning byte %li", i); + buf[i] = 0x55; + if ((i = keystore_write_data(0, buf, sizeof(buf))) != 1) { + cli_print(cli, "Failed writing data at offset 0: %li", i); + return CLI_ERROR; + } + } + } else { + cli_print(cli, "Erasing first sector since all the first 8 bytes are tombstones"); + if ((i = keystore_erase_sectors(1)) != 1) { + cli_print(cli, "Failed erasing the first sector: %li", i); + return CLI_ERROR; + } + cli_print(cli, "Erase result: %li", i); + } + + return CLI_OK; +} + +void configure_cli_show(struct cli_def *cli) +{ + /* show */ + cli_command_root(show); + + /* show cpuspeed */ + cli_command_node(show, cpuspeed, "Show the speed at which the CPU currently operates"); + + cli_command_branch(show, fpga); + /* show fpga status*/ + cli_command_node(show_fpga, status, "Show status about the FPGA"); + + cli_command_branch(show, keystore); + /* show keystore status*/ + cli_command_node(show_keystore, status, "Show status of the keystore memory"); + cli_command_node(show_keystore, data, "Show the first page of the keystore memory"); +} diff --git a/projects/cli-test/mgmt-show.h b/projects/cli-test/mgmt-show.h new file mode 100644 index 0000000..0d7ba3a --- /dev/null +++ b/projects/cli-test/mgmt-show.h @@ -0,0 +1,43 @@ +/* + * mgmt-misc.h + * ----------- + * Management CLI 'show' functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STM32_CLI_MGMT_SHOW_H +#define __STM32_CLI_MGMT_SHOW_H + +#include "stm-init.h" +#include + +extern void configure_cli_show(struct cli_def *cli); + +#endif /* __STM32_CLI_MGMT_SHOW_H */ diff --git a/projects/cli-test/mgmt-test.c b/projects/cli-test/mgmt-test.c new file mode 100644 index 0000000..c1f255e --- /dev/null +++ b/projects/cli-test/mgmt-test.c @@ -0,0 +1,117 @@ +/* + * mgmt-test.c + * ----------- + * CLI hardware test functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stm-init.h" +#include "stm-led.h" +#include "stm-sdram.h" + +#include "mgmt-cli.h" +#include "mgmt-test.h" + +#include "test_sdram.h" + +#include + + +int cmd_test_sdram(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + // run external memory initialization sequence + HAL_StatusTypeDef status; + int ok, num_cycles = 1, i, test_completed; + + if (argc == 1) { + num_cycles = strtol(argv[0], NULL, 0); + if (num_cycles > 100) num_cycles = 100; + if (num_cycles < 1) num_cycles = 1; + } + + cli_print(cli, "Initializing SDRAM"); + status = sdram_init(); + if (status != HAL_OK) { + cli_print(cli, "Failed initializing SDRAM: %i", (int) status); + return CLI_OK; + } + + for (i = 1; i <= num_cycles; i++) { + cli_print(cli, "Starting SDRAM test (%i/%i)", i, num_cycles); + test_completed = 0; + // set LFSRs to some initial value, LFSRs will produce + // pseudo-random 32-bit patterns to test our memories + lfsr1 = 0xCCAA5533; + lfsr2 = 0xCCAA5533; + + cli_print(cli, "Run sequential write-then-read test for the first chip"); + ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP1); + if (!ok) break; + + cli_print(cli, "Run random write-then-read test for the first chip"); + ok = test_sdram_random(SDRAM_BASEADDR_CHIP1); + if (!ok) break; + + cli_print(cli, "Run sequential write-then-read test for the second chip"); + ok = test_sdram_sequential(SDRAM_BASEADDR_CHIP2); + if (!ok) break; + + cli_print(cli, "Run random write-then-read test for the second chip"); + ok = test_sdram_random(SDRAM_BASEADDR_CHIP2); + if (!ok) break; + + // turn blue led on (testing two chips at the same time) + led_on(LED_BLUE); + + cli_print(cli, "Run interleaved write-then-read test for both chips at once"); + ok = test_sdrams_interleaved(SDRAM_BASEADDR_CHIP1, SDRAM_BASEADDR_CHIP2); + + led_off(LED_BLUE); + test_completed = 1; + cli_print(cli, "SDRAM test (%i/%i) completed\r\n", i, num_cycles); + } + + if (! test_completed) { + cli_print(cli, "SDRAM test failed (%i/%i)", i, num_cycles); + } else { + cli_print(cli, "SDRAM test completed successfully"); + } + + return CLI_OK; +} + +void configure_cli_test(struct cli_def *cli) +{ + /* test */ + cli_command_root(test); + + /* test sdram */ + cli_command_node(test, sdram, "Run SDRAM tests"); +} diff --git a/projects/cli-test/mgmt-test.h b/projects/cli-test/mgmt-test.h new file mode 100644 index 0000000..3beb2da --- /dev/null +++ b/projects/cli-test/mgmt-test.h @@ -0,0 +1,43 @@ +/* + * mgmt-misc.h + * ----------- + * Management CLI miscellaneous functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STM32_CLI_MGMT_TEST_H +#define __STM32_CLI_MGMT_TEST_H + +#include "stm-init.h" +#include + +extern void configure_cli_test(struct cli_def *cli); + +#endif /* __STM32_CLI_MGMT_TEST_H */ -- cgit v1.2.3 From ae1ecf87f6b8d7c34b32af0547f118ff7697c2ef Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 2 Jun 2016 14:56:56 +0200 Subject: Use DMA for UART RX instead of interrupts. DMA is more efficient and less prone to miss characters than interrupts. An open question is if circular mode is really the best. If someone copy-pastes more than the RX buffer size of configuration into the CLI, we risk the DMA controller catching up with the reader and overwriting data not yet read. Since we don't have flow control back to the users terminal, we will always fail if too much data is entered before we can process it. The question is if failing to stuff new data at the end of a buffer might be better than data being overwritten - thus messing up the commands in unpredictable ways. --- projects/cli-test/cli-test.c | 17 ---------- projects/cli-test/filetransfer | 6 ++-- projects/cli-test/mgmt-cli.c | 71 +++++++++++++++++++++--------------------- projects/cli-test/mgmt-cli.h | 7 ++++- projects/cli-test/mgmt-fpga.c | 64 ++++++++----------------------------- projects/cli-test/mgmt-misc.c | 62 +++++++++++++++++++++++++++++------- projects/cli-test/mgmt-misc.h | 6 ++++ 7 files changed, 113 insertions(+), 120 deletions(-) (limited to 'projects/cli-test') diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index b6178af..ed6aac3 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -71,23 +71,6 @@ void do_early_dfu_jump(void) while (1); } -/* Callback for HAL_UART_Receive_IT(). */ -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) -{ - if (huart->Instance == huart_mgmt.Instance) { - mgmt_cli_uart_isr((const uint8_t *) &uart_rx, 1); - - /* Set things up to receive another byte. */ - HAL_UART_Receive_IT(huart, (uint8_t *) &uart_rx, 1); - } -} - -void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) -{ - led_on(LED_RED); - led_on(LED_YELLOW); -} - int main() { diff --git a/projects/cli-test/filetransfer b/projects/cli-test/filetransfer index 025a6ac..f704e31 100755 --- a/projects/cli-test/filetransfer +++ b/projects/cli-test/filetransfer @@ -77,11 +77,9 @@ def parse_args(): def _write(dst, data): - for i in range(len(data)): - dst.write(data[i]) - time.sleep(0.1) + dst.write(data) if len(data) == 4: - print("Wrote 0x{:02x}{:02x}{:02x}{:02x}".format(ord(data[0]), ord(data[1]), ord(data[2]), ord(data[3]))) + print("Wrote 0x{!s}".format(data.encode('hex'))) else: print("Wrote {!r}".format(data)) diff --git a/projects/cli-test/mgmt-cli.c b/projects/cli-test/mgmt-cli.c index abbd999..3b4ffe9 100644 --- a/projects/cli-test/mgmt-cli.c +++ b/projects/cli-test/mgmt-cli.c @@ -41,18 +41,17 @@ extern uint8_t uart_rx; struct uart_ringbuf_t { - uint32_t enabled, ridx, widx, overflow; + uint32_t enabled, ridx; + enum mgmt_cli_dma_state rx_state; uint8_t buf[CLI_UART_RECVBUF_SIZE]; }; -volatile struct uart_ringbuf_t uart_ringbuf = {1, 0, 0, 0, {0}}; +volatile struct uart_ringbuf_t uart_ringbuf = {1, 0, DMA_RX_STOP, {0}}; #define RINGBUF_RIDX(rb) (rb.ridx & CLI_UART_RECVBUF_MASK) -#define RINGBUF_WIDX(rb) (rb.widx & CLI_UART_RECVBUF_MASK) -#define RINGBUF_COUNT(rb) ((unsigned)(rb.widx - rb.ridx)) -#define RINGBUF_FULL(rb) (RINGBUF_RIDX(rb) == ((rb.widx + 1) & CLI_UART_RECVBUF_MASK)) +#define RINGBUF_WIDX(rb) (sizeof(rb.buf) - __HAL_DMA_GET_COUNTER(huart_mgmt.hdmarx)) +#define RINGBUF_COUNT(rb) ((unsigned)(RINGBUF_WIDX(rb) - RINGBUF_RIDX(rb))) #define RINGBUF_READ(rb, dst) {dst = rb.buf[RINGBUF_RIDX(rb)]; rb.buf[RINGBUF_RIDX(rb)] = '.'; rb.ridx++;} -#define RINGBUF_WRITE(rb, src) {rb.buf[RINGBUF_WIDX(rb)] = src; rb.widx++;} void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf) { @@ -64,23 +63,16 @@ void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *bu int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count) { uint32_t timeout = 0xffffff; - - /* Always explicitly enable the RX interrupt when we get here. - * Prevents us getting stuck waiting for an interrupt that will never come. - */ - __HAL_UART_FLUSH_DRREGISTER(&huart_mgmt); - HAL_UART_Receive_IT(&huart_mgmt, (uint8_t *) &uart_rx, 1); - - while (count && timeout--) { + while (count && timeout) { if (RINGBUF_COUNT(uart_ringbuf)) { RINGBUF_READ(uart_ringbuf, *(uint8_t *) buf); buf++; count--; - } else { - led_toggle(LED_GREEN); - HAL_Delay(10); } + timeout--; } + if (! timeout) return 0; + return 1; } @@ -90,6 +82,26 @@ int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf return (int) count; } +int control_mgmt_uart_dma_rx(enum mgmt_cli_dma_state state) +{ + if (state == DMA_RX_START) { + if (uart_ringbuf.rx_state != DMA_RX_START) { + memset((void *) uart_ringbuf.buf, 0, sizeof(uart_ringbuf.buf)); + + /* Start receiving data from the UART using DMA */ + HAL_UART_Receive_DMA(&huart_mgmt, (uint8_t *) uart_ringbuf.buf, sizeof(uart_ringbuf.buf)); + uart_ringbuf.ridx = 0; + uart_ringbuf.rx_state = DMA_RX_START; + } + return 1; + } else if (state == DMA_RX_STOP) { + if (HAL_UART_DMAStop(&huart_mgmt) != HAL_OK) return 0; + uart_ringbuf.rx_state = DMA_RX_STOP; + return 1; + } + return 0; +} + int embedded_cli_loop(struct cli_def *cli) { unsigned char c; @@ -110,15 +122,18 @@ int embedded_cli_loop(struct cli_def *cli) while (1) { cli_loop_start_new_command(cli, &ctx); + control_mgmt_uart_dma_rx(DMA_RX_START); + while (1) { cli_loop_show_prompt(cli, &ctx); n = cli_loop_read_next_char(cli, &ctx, &c); /* - cli_print(cli, "Next char: '%c'/%i, ringbuf ridx %i, widx %i (%i/%i) - count %i", - c, (int) c, uart_ringbuf.ridx, uart_ringbuf.widx, RINGBUF_RIDX(uart_ringbuf), - RINGBUF_WIDX(uart_ringbuf), RINGBUF_COUNT(uart_ringbuf)); + cli_print(cli, "Next char: '%c'/%i, ringbuf ridx %i, widx %i", + c, (int) c, + uart_ringbuf.ridx, + RINGBUF_WIDX(uart_ringbuf) */ if (n == CLI_LOOP_CTRL_BREAK) break; @@ -143,22 +158,6 @@ int embedded_cli_loop(struct cli_def *cli) return CLI_OK; } -/* Interrupt service routine to be called when data has been received on the MGMT UART. */ -void mgmt_cli_uart_isr(const uint8_t *buf, size_t count) -{ - if (! uart_ringbuf.enabled) return; - - while (count) { - if (RINGBUF_FULL(uart_ringbuf)) { - uart_ringbuf.overflow++; - return; - } - RINGBUF_WRITE(uart_ringbuf, *buf); - buf++; - count--; - } -} - void mgmt_cli_init(struct cli_def *cli) { cli_init(cli); diff --git a/projects/cli-test/mgmt-cli.h b/projects/cli-test/mgmt-cli.h index 3b7f503..16c9fbd98 100644 --- a/projects/cli-test/mgmt-cli.h +++ b/projects/cli-test/mgmt-cli.h @@ -71,11 +71,16 @@ #define CLI_UART_RECVBUF_SIZE 256 /* This must be a power of 2 */ #define CLI_UART_RECVBUF_MASK (CLI_UART_RECVBUF_SIZE - 1) +enum mgmt_cli_dma_state { + DMA_RX_STOP, + DMA_RX_START, +}; + extern void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf); extern int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count); extern int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count); extern int embedded_cli_loop(struct cli_def *cli); extern void mgmt_cli_init(struct cli_def *cli); -extern void mgmt_cli_uart_isr(const uint8_t *buf, size_t count); +extern int control_mgmt_uart_dma_rx(enum mgmt_cli_dma_state state); #endif /* __STM32_MGMT_CLI_H */ diff --git a/projects/cli-test/mgmt-fpga.c b/projects/cli-test/mgmt-fpga.c index c20b7b2..8c1b2a8 100644 --- a/projects/cli-test/mgmt-fpga.c +++ b/projects/cli-test/mgmt-fpga.c @@ -35,21 +35,29 @@ #include "stm-init.h" #include "stm-uart.h" #include "stm-fpgacfg.h" + #include "mgmt-cli.h" #include "mgmt-fpga.h" +#include "mgmt-misc.h" #include -extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); +volatile uint32_t dfu_offset = 0; + +int _flash_write_callback(uint8_t *buf, size_t len) { + int res = fpgacfg_write_data(dfu_offset, buf, BITSTREAM_UPLOAD_CHUNK_SIZE) == 1; + dfu_offset += BITSTREAM_UPLOAD_CHUNK_SIZE; + return res; +} int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *argv[], int argc) { - uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0, i; - uint32_t offset = 0, n = BITSTREAM_UPLOAD_CHUNK_SIZE; uint8_t buf[BITSTREAM_UPLOAD_CHUNK_SIZE]; + dfu_offset = 0; + fpgacfg_access_control(ALLOW_ARM); cli_print(cli, "Checking if FPGA config memory is accessible"); @@ -58,57 +66,11 @@ int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *ar return CLI_ERROR; } - cli_print(cli, "OK, write FPGA bitstream file size (4 bytes), data in 4096 byte chunks, CRC-32 (4 bytes)"); - - /* Read file size (4 bytes) */ - uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); - cli_print(cli, "File size %li", filesize); - - while (filesize) { - /* By initializing buf to the same value that erased flash has (0xff), we don't - * have to try and be smart when writing the last page of data to the memory. - */ - memset(buf, 0xff, sizeof(buf)); - - if (filesize < n) { - n = filesize; - } - - if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { - cli_print(cli, "Receive timed out"); - return CLI_ERROR; - } - filesize -= n; - - /* After reception of 4 KB but before ACKing we have "all" the time in the world to - * calculate CRC and write it to flash. - */ - my_crc = update_crc(my_crc, buf, n); - - if ((i = fpgacfg_write_data(offset, buf, BITSTREAM_UPLOAD_CHUNK_SIZE)) != 1) { - cli_print(cli, "Failed writing data at offset %li (counter = %li): %li", offset, counter, i); - return CLI_ERROR; - } - - offset += BITSTREAM_UPLOAD_CHUNK_SIZE; - - /* ACK this chunk by sending the current chunk counter (4 bytes) */ - counter++; - uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); - } - - /* The sending side will now send it's calculated CRC-32 */ - cli_print(cli, "Send CRC-32"); - uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); - cli_print(cli, "CRC-32 %li", crc); - if (crc == my_crc) { - cli_print(cli, "CRC checksum MATCHED"); - } else { - cli_print(cli, "CRC checksum did NOT match"); - } + cli_receive_data(cli, &buf[0], sizeof(buf), _flash_write_callback); fpgacfg_access_control(ALLOW_FPGA); + cli_print(cli, "DFU offset now: %li (%li chunks)", dfu_offset, dfu_offset / BITSTREAM_UPLOAD_CHUNK_SIZE); return CLI_OK; } diff --git a/projects/cli-test/mgmt-misc.c b/projects/cli-test/mgmt-misc.c index a98bf8d..aea790a 100644 --- a/projects/cli-test/mgmt-misc.c +++ b/projects/cli-test/mgmt-misc.c @@ -43,34 +43,64 @@ extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); -int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) + +volatile uint32_t demo_crc = 0; + + +int _count_bytes_callback(uint8_t *buf, size_t len) { + demo_crc = update_crc(demo_crc, buf, len); + return 1; +} + +int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_callback data_callback) { - uint32_t filesize = 0, crc = 0, my_crc = 0, n = 256, counter = 0; - uint8_t buf[256]; + uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0; + size_t n = len; - cli_print(cli, "OK, write file size (4 bytes), data in %li byte chunks, CRC-32 (4 bytes)", n); + if (! control_mgmt_uart_dma_rx(DMA_RX_STOP)) { + cli_print(cli, "Failed stopping DMA"); + return CLI_OK; + } + + cli_print(cli, "OK, write size (4 bytes), data in %li byte chunks, CRC-32 (4 bytes)", (uint32_t) n); - uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); - cli_print(cli, "File size %li", filesize); + if (uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000) != HAL_OK) { + cli_print(cli, "Receive timed out"); + return CLI_ERROR; + } + + cli_print(cli, "Send %li bytes of data", filesize); while (filesize) { - if (filesize < n) { - n = filesize; - } + /* By initializing buf to the same value that erased flash has (0xff), we don't + * have to try and be smart when writing the last page of data to a flash memory. + */ + memset(buf, 0xff, len); - if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { + if (filesize < n) n = filesize; + + if (uart_receive_bytes(STM_UART_MGMT, (void *) buf, n, 1000) != HAL_OK) { cli_print(cli, "Receive timed out"); return CLI_ERROR; } filesize -= n; my_crc = update_crc(my_crc, buf, n); + + /* After reception of a chunk but before ACKing we have "all" the time in the world to + * calculate CRC and invoke the data_callback. + */ + if (data_callback != NULL && ! data_callback(buf, (size_t) n)) { + cli_print(cli, "Data processing failed"); + return CLI_OK; + } + counter++; uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4); } cli_print(cli, "Send CRC-32"); uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); - cli_print(cli, "CRC-32 %li", crc); + cli_print(cli, "CRC-32 0x%x, calculated CRC 0x%x", (unsigned int) crc, (unsigned int) my_crc); if (crc == my_crc) { cli_print(cli, "CRC checksum MATCHED"); } else { @@ -80,6 +110,16 @@ int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int return CLI_OK; } +int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint8_t buf[FILETRANSFER_UPLOAD_CHUNK_SIZE]; + + demo_crc = 0; + cli_receive_data(cli, &buf[0], sizeof(buf), _count_bytes_callback); + cli_print(cli, "Demo CRC is: %li/0x%x", demo_crc, (unsigned int) demo_crc); + return CLI_OK; +} + int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "\n\n\nRebooting\n\n\n"); diff --git a/projects/cli-test/mgmt-misc.h b/projects/cli-test/mgmt-misc.h index caf7024..b7eb4f4 100644 --- a/projects/cli-test/mgmt-misc.h +++ b/projects/cli-test/mgmt-misc.h @@ -38,6 +38,12 @@ #include "stm-init.h" #include + +#define FILETRANSFER_UPLOAD_CHUNK_SIZE 256 + +typedef int (*cli_data_callback)(uint8_t *, size_t); + extern void configure_cli_misc(struct cli_def *cli); +extern int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_callback data_callback); #endif /* __STM32_CLI_MGMT_MISC_H */ -- cgit v1.2.3