[Cryptech-Commits] [sw/stm32] 02/02: Add code to reset FPGA using FPGA_PROGRAM_B and FPGA_INIT_B.

git at cryptech.is git at cryptech.is
Fri May 20 15:20:25 UTC 2016


This is an automated email from the git hooks/post-receive script.

fredrik at thulin.net pushed a commit to branch master
in repository sw/stm32.

commit fd5774fdebc04f92983e677f4bc210c75e8fcc94
Author: Fredrik Thulin <fredrik at thulin.net>
AuthorDate: Fri May 20 17:19:54 2016 +0200

    Add code to reset FPGA using FPGA_PROGRAM_B and FPGA_INIT_B.
    
    Also add code to erase FPGA config memory and check status of FPGA_DONE.
---
 projects/cli-test/cli-test.c | 68 +++++++++++++++++++++++++++++++++++++
 spiflash_n25q128.c           |  1 -
 stm-fpgacfg.c                | 43 ++++++++++++++++++++++-
 stm-fpgacfg.h                | 51 ++++++++++++++++++++++++----
 stm-init.c                   | 81 ++++++++++++++++++--------------------------
 stm-led.h                    |  2 ++
 6 files changed, 189 insertions(+), 57 deletions(-)

diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c
index e7d49a7..92eb7c0 100644
--- a/projects/cli-test/cli-test.c
+++ b/projects/cli-test/cli-test.c
@@ -92,6 +92,12 @@ int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int
     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;
+}
+
 /* 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.
 */
@@ -165,6 +171,51 @@ int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *ar
     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");
@@ -189,15 +240,27 @@ main()
     struct cli_command cmd_show_cpuspeed_s = {(char *) "cpuspeed", cmd_show_cpuspeed, 0,
                                              (char *) "Show the speed at which the CPU currently operates",
                                              PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+    struct cli_command cmd_show_fpga_s = {(char *) "fpga", NULL, 0, NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+    struct cli_command cmd_show_fpga_status_s = {(char *) "status", cmd_show_fpga_status, 0, NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+
     struct cli_command cmd_filetransfer_s = {(char *) "filetransfer", cmd_filetransfer, 0,
                                              (char *) "Test file transfering",
                                              PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
 
     struct cli_command cmd_fpga_s = {(char *) "fpga", NULL, 0, NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+    struct cli_command cmd_fpga_reset_s = {(char *) "reset", cmd_fpga_reset, 0,
+					   (char *) "Reset FPGA (config reset)",
+					   PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+    struct cli_command cmd_fpga_reset_registerss = {(char *) "registers", cmd_fpga_reset_registers, 0,
+						    (char *) "Reset FPGA registers (soft reset)",
+						    PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
     struct cli_command cmd_fpga_bitstream_s = {(char *) "bitstream", NULL, 0, NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
     struct cli_command cmd_fpga_bitstream_upload_s = {(char *) "upload", cmd_fpga_bitstream_upload, 0,
 						      (char *) "Upload new FPGA bitstream",
 						      PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
+    struct cli_command cmd_fpga_bitstream_erase_s = {(char *) "erase", cmd_fpga_bitstream_erase, 0,
+						     (char *) "Erase FPGA config memory",
+						     PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
     struct cli_command cmd_reboot_s = {(char *) "reboot", cmd_reboot, 0,
 				       (char *) "Reboot the STM32",
 				       PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL};
@@ -212,12 +275,17 @@ main()
 
     cli_register_command2(&cli, &cmd_show_s, NULL);
     cli_register_command2(&cli, &cmd_show_cpuspeed_s, &cmd_show_s);
+    cli_register_command2(&cli, &cmd_show_fpga_s, &cmd_show_s);
+    cli_register_command2(&cli, &cmd_show_fpga_status_s, &cmd_show_fpga_s);
 
     cli_register_command2(&cli, &cmd_filetransfer_s, NULL);
 
     cli_register_command2(&cli, &cmd_fpga_s, NULL);
+    cli_register_command2(&cli, &cmd_fpga_reset_s, &cmd_fpga_s);
+    cli_register_command2(&cli, &cmd_fpga_reset_registerss, &cmd_fpga_reset_s);
     cli_register_command2(&cli, &cmd_fpga_bitstream_s, &cmd_fpga_s);
     cli_register_command2(&cli, &cmd_fpga_bitstream_upload_s, &cmd_fpga_bitstream_s);
+    cli_register_command2(&cli, &cmd_fpga_bitstream_erase_s, &cmd_fpga_bitstream_s);
 
     cli_register_command2(&cli, &cmd_reboot_s, NULL);
 
diff --git a/spiflash_n25q128.c b/spiflash_n25q128.c
index 10f5954..985e727 100644
--- a/spiflash_n25q128.c
+++ b/spiflash_n25q128.c
@@ -317,7 +317,6 @@ int n25q128_write_data(struct spiflash_ctx *ctx, uint32_t offset, const uint8_t
     }
 
     for (page = 0; page < len / N25Q128_PAGE_SIZE; page++) {
-	/* Wait until the flash memory is done writing (wip = Write In Progress) */
 	if (! _wait_while_wip(ctx, 1000)) return -5;
 
 	if (! n25q128_write_page(ctx, offset / N25Q128_PAGE_SIZE, buf)) {
diff --git a/stm-fpgacfg.c b/stm-fpgacfg.c
index f8ff6fa..9e2a307 100644
--- a/stm-fpgacfg.c
+++ b/stm-fpgacfg.c
@@ -1,7 +1,8 @@
 /*
  * stm-fpgacfg.c
  * ----------
- * Functions for accessing the FPGA config memory.
+ * Functions for accessing the FPGA config memory and controlling
+ * the low-level status of the FPGA (reset registers/reboot etc.).
  *
  * Copyright (c) 2016, NORDUnet A/S All rights reserved.
  *
@@ -69,3 +70,43 @@ void fpgacfg_access_control(enum fpgacfg_access_ctrl access)
 	HAL_GPIO_WritePin(GPIOF, PROM_ARM_ENA_Pin, GPIO_PIN_SET);
     }
 }
+
+void fpgacfg_reset_fpga(enum fpgacfg_reset reset)
+{
+    if (reset == RESET_FULL) {
+	/* The delay should be at least 250 uS. With HAL_Delay(1) the pulse is very close
+	 * to that, and With HAL_Delay(3) the pulse is close to 2 ms. */
+	HAL_GPIO_WritePin(FPGA_PROGRAM_Port, FPGA_PROGRAM_Pin, GPIO_PIN_RESET);
+	HAL_Delay(3);
+	HAL_GPIO_WritePin(FPGA_PROGRAM_Port, FPGA_PROGRAM_Pin, GPIO_PIN_SET);
+    } else if (reset == RESET_REGISTERS) {
+	HAL_GPIO_WritePin(FPGA_INIT_Port, FPGA_INIT_Pin, GPIO_PIN_SET);
+	HAL_Delay(3);
+	HAL_GPIO_WritePin(FPGA_INIT_Port, FPGA_INIT_Pin, GPIO_PIN_RESET);
+    }
+}
+
+int fpgacfg_check_done(void)
+{
+    GPIO_PinState status = HAL_GPIO_ReadPin(FPGA_DONE_Port, FPGA_DONE_Pin);
+    return (status == GPIO_PIN_SET);
+}
+
+int fpgacfg_erase_sectors(int num)
+{
+    if (num > N25Q128_NUM_SECTORS - 1 || num < 0) num = N25Q128_NUM_SECTORS - 1;
+    while (num) {
+	int timeout = 1000;
+	while (timeout--) {
+	    int i = n25q128_get_wip_flag(&fpgacfg_ctx);
+	    if (i < 0) return 0;
+	    if (! i) break;
+	    HAL_Delay(10);
+	}
+
+	if (! n25q128_erase_sector(&fpgacfg_ctx, num--)) {
+            return 0;
+        }
+    }
+    return 1;
+}
diff --git a/stm-fpgacfg.h b/stm-fpgacfg.h
index ad86a89..367aa3d 100644
--- a/stm-fpgacfg.h
+++ b/stm-fpgacfg.h
@@ -1,7 +1,8 @@
 /*
  * stm-fpgacfg.h
  * ---------
- * Functions and defines for accessing the FPGA config memory.
+ * Functions and defines for accessing the FPGA config memory and controlling
+ * the low-level status of the FPGA (reset registers/reboot etc.).
  *
  * Copyright (c) 2016, NORDUnet A/S All rights reserved.
  *
@@ -38,24 +39,60 @@
 #include "stm32f4xx_hal.h"
 #include "spiflash_n25q128.h"
 
+/* Pins connected to the FPGA config memory (SPI flash) */
 #define PROM_FPGA_DIS_Pin              GPIO_PIN_14
 #define PROM_FPGA_DIS_GPIO_Port        GPIOI
 #define PROM_ARM_ENA_Pin               GPIO_PIN_6
 #define PROM_ARM_ENA_GPIO_Port         GPIOF
 #define PROM_CS_N_Pin                  GPIO_PIN_12
 #define PROM_CS_N_GPIO_Port            GPIOB
+/* Pins for controlling the FPGA */
+#define FPGA_INIT_Port                 GPIOJ
+#define FPGA_INIT_Pin                  GPIO_PIN_7
+#define FPGA_PROGRAM_Port              GPIOJ
+#define FPGA_PROGRAM_Pin               GPIO_PIN_8
+/* FPGA status */
+#define FPGA_DONE_Port                 GPIOJ
+#define FPGA_DONE_Pin                  GPIO_PIN_15
+
+#define FPGACFG_GPIO_INIT()		\
+    __GPIOI_CLK_ENABLE();		\
+    __GPIOF_CLK_ENABLE();		\
+    __GPIOB_CLK_ENABLE();		\
+    __GPIOJ_CLK_ENABLE();		\
+    /* Configure GPIO pins for FPGA access control: PROM_FPGA_DIS, PROM_ARM_ENA */ \
+    gpio_output(PROM_FPGA_DIS_GPIO_Port, PROM_FPGA_DIS_Pin, GPIO_PIN_RESET);       \
+    gpio_output(PROM_ARM_ENA_GPIO_Port, PROM_ARM_ENA_Pin, GPIO_PIN_RESET);         \
+    /* Configure GPIO pin for FPGA config memory chip select : PROM_CS_N */        \
+    gpio_output(PROM_CS_N_GPIO_Port, PROM_CS_N_Pin, GPIO_PIN_SET);	           \
+    /* Configure GPIO pins FPGA_INIT and FPGA_PROGRAM to reset the FPGA */         \
+    gpio_output(FPGA_INIT_Port, FPGA_INIT_Pin, GPIO_PIN_RESET);			   \
+    gpio_output(FPGA_PROGRAM_Port, FPGA_PROGRAM_Pin, GPIO_PIN_SET);		   \
+    /* Configure FPGA_DONE input pin */   					   \
+    //gpio_input(FPGA_DONE_Port, FPGA_DONE_Pin, GPIO_PULLUP) \
+    1
 
 
 enum fpgacfg_access_ctrl {
-  ALLOW_NONE,
-  ALLOW_FPGA,
-  ALLOW_ARM,
+    ALLOW_NONE,
+    ALLOW_FPGA,
+    ALLOW_ARM,
 };
 
-extern int fpgacfg_check_id();
-extern int fpgacfg_write_data(uint32_t offset, const uint8_t *buf, const uint32_t len);
-extern void fpgacfg_access_control(enum fpgacfg_access_ctrl access);
+enum fpgacfg_reset {
+    RESET_FULL,
+    RESET_REGISTERS,
+};
 
 extern SPI_HandleTypeDef hspi_fpgacfg;
 
+extern int fpgacfg_check_id(void);
+extern int fpgacfg_write_data(uint32_t offset, const uint8_t *buf, const uint32_t len);
+extern int fpgacfg_erase_sectors(int num);
+extern void fpgacfg_access_control(enum fpgacfg_access_ctrl access);
+/* Reset the FPGA */
+extern void fpgacfg_reset_fpga(enum fpgacfg_reset reset);
+/* Check status of FPGA bitstream loading */
+extern int fpgacfg_check_done(void);
+
 #endif /* __STM32_FPGACFG_H */
diff --git a/stm-init.c b/stm-init.c
index 2c19d58..8711cc1 100644
--- a/stm-init.c
+++ b/stm-init.c
@@ -139,65 +139,50 @@ static void MX_USART2_UART_Init(void)
 #endif
 
 #ifdef HAL_GPIO_MODULE_ENABLED
-/** Configure pins as
-        * Analog
-        * Input
-        * Output
-        * EVENT_OUT
-        * EXTI
-*/
+
+#define gpio_output(output_port, output_pins, output_level)	\
+    /* Configure GPIO pin Output Level */			\
+    HAL_GPIO_WritePin(output_port, output_pins, output_level);	\
+    /* Configure pin as output */ 				\
+    GPIO_InitStruct.Pin = output_pins; 				\
+    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP; 		\
+    GPIO_InitStruct.Pull = GPIO_NOPULL; 			\
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW; 			\
+    HAL_GPIO_Init(output_port, &GPIO_InitStruct)
+
+#define gpio_input(input_port, input_pin, input_pull)	\
+    GPIO_InitStruct.Pin = input_pin;			\
+    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;		\
+    GPIO_InitStruct.Pull = input_pull;			\
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;		\
+    HAL_GPIO_Init(input_port, &GPIO_InitStruct)
+
+
+/* Configure General Purpose Input/Output pins */
 static void MX_GPIO_Init(void)
 {
   GPIO_InitTypeDef GPIO_InitStruct;
 
   /* GPIO Ports Clock Enable */
-  __GPIOK_CLK_ENABLE();
-
-  /* Configure LED GPIO pins PJ1==red, PJ2==yellow, PJ3==green, PJ4==blue */
-  GPIO_InitStruct.Pin = LED_RED | LED_YELLOW | LED_GREEN | LED_BLUE;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
-  HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
-
-
+  LED_CLK_ENABLE();
 
+  /* Configure LED GPIO pins */
+  gpio_output(LED_PORT, LED_RED | LED_YELLOW | LED_GREEN | LED_BLUE, GPIO_PIN_RESET);
 
 #ifdef HAL_SPI_MODULE_ENABLED
-  /* Set up GPIOs to manage access to the FPGA config memory. */
-
+  /* Set up GPIOs to manage access to the FPGA config memory.
+   * FPGACFG_GPIO_INIT is defined in stm-fpgacfg.h.
+   */
   /* GPIO Ports Clock Enable */
-  __GPIOI_CLK_ENABLE();
-  __GPIOF_CLK_ENABLE();
-  __GPIOB_CLK_ENABLE();
-
-  /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(PROM_FPGA_DIS_GPIO_Port, PROM_FPGA_DIS_Pin, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(PROM_ARM_ENA_GPIO_Port, PROM_ARM_ENA_Pin, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(PROM_CS_N_GPIO_Port, PROM_CS_N_Pin, GPIO_PIN_SET);	// active-low!!!
-
-  /*Configure GPIO pin : PROM_FPGA_DIS */
-  GPIO_InitStruct.Pin = PROM_FPGA_DIS_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(PROM_FPGA_DIS_GPIO_Port, &GPIO_InitStruct);
-
-  /*Configure GPIO pin : PROM_ARM_ENA */
-  GPIO_InitStruct.Pin = PROM_ARM_ENA_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(PROM_ARM_ENA_GPIO_Port, &GPIO_InitStruct);
-
-  /*Configure GPIO pin : PROM_CS_N */
-  GPIO_InitStruct.Pin = PROM_CS_N_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(PROM_CS_N_GPIO_Port, &GPIO_InitStruct);
+  FPGACFG_GPIO_INIT();
+  /*
+  __GPIOJ_CLK_ENABLE();
+  gpio_output(FPGA_INIT_Port, FPGA_INIT_Pin, GPIO_PIN_RESET);
+  gpio_output(FPGA_PROGRAM_Port, FPGA_PROGRAM_Pin, GPIO_PIN_SET);
+  */
 #endif /* HAL_SPI_MODULE_ENABLED */
 }
+#undef gpio_output
 #endif
 
 #ifdef HAL_I2C_MODULE_ENABLED
diff --git a/stm-led.h b/stm-led.h
index 7c20879..e2453e4 100644
--- a/stm-led.h
+++ b/stm-led.h
@@ -43,6 +43,8 @@
 #define LED_GREEN       GPIO_PIN_5
 #define LED_BLUE        GPIO_PIN_4
 
+#define LED_CLK_ENABLE  __GPIOK_CLK_ENABLE
+
 #define led_on(pin)     HAL_GPIO_WritePin(LED_PORT,pin,SET)
 #define led_off(pin)    HAL_GPIO_WritePin(LED_PORT,pin,RESET)
 #define led_toggle(pin) HAL_GPIO_TogglePin(LED_PORT,pin)



More information about the Commits mailing list