From 6e12d2aaf45fba981f2f03fa9f95c3206ce9f06f Mon Sep 17 00:00:00 2001
From: dwf1m12 <d.w.flynn@soton.ac.uk>
Date: Wed, 10 Jan 2024 21:24:07 +0000
Subject: [PATCH] testbench and code updated for 38K4 UART2 @240MHz

---
 .../ARM/CMSDK_CM0/Source/system_CMSDK_CM0.c   |  2 +-
 software/common/bootloader/bootloader.c       | 32 +++++-----
 software/common/retarget/uart_stdout.c        | 59 +++++++++++++++----
 software/common/retarget/uart_stdout.h        |  1 +
 verif/tb/verilog/nanosoc_tb.v                 | 14 ++---
 5 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/software/cmsis/Device/ARM/CMSDK_CM0/Source/system_CMSDK_CM0.c b/software/cmsis/Device/ARM/CMSDK_CM0/Source/system_CMSDK_CM0.c
index 9056bf4..5dc5d7c 100644
--- a/software/cmsis/Device/ARM/CMSDK_CM0/Source/system_CMSDK_CM0.c
+++ b/software/cmsis/Device/ARM/CMSDK_CM0/Source/system_CMSDK_CM0.c
@@ -35,7 +35,7 @@
   Define clocks
  *----------------------------------------------------------------------------*/
 
-#define XTAL    (100000000UL)            /* Oscillator frequency               */
+#define XTAL    (240000000UL)            /* Oscillator frequency 240MHz       */
 
 
 /*----------------------------------------------------------------------------
diff --git a/software/common/bootloader/bootloader.c b/software/common/bootloader/bootloader.c
index fed5b51..c1b3664 100644
--- a/software/common/bootloader/bootloader.c
+++ b/software/common/bootloader/bootloader.c
@@ -54,23 +54,26 @@
 
 void UartStdOutInit(void)
 {
-//  CMSDK_UART2->BAUDDIV = 16;
-//  CMSDK_UART2->CTRL    = 0x41; // High speed test mode, TX only
-  CMSDK_UART2->BAUDDIV = 2080; //(20MHz/9600)
-  CMSDK_UART2->CTRL    = 0x01; //TX only, standard UART
-  CMSDK_USRT2->CTRL    = 0x01; //TX only, FT1248 USRT
+  CMSDK_UART2->CTRL    = 0x00; // re-init
+  CMSDK_UART2->BAUDDIV = 6250; //(240MHz/384000) in 16.4 format
+  CMSDK_UART2->CTRL    = 0x01; //TX, UART2
+  CMSDK_USRT2->CTRL    = 0x00; //re-init
+  CMSDK_USRT2->CTRL    = 0x03; //RX+TX, FT1248 USRT
   CMSDK_GPIO1->ALTFUNCSET = (1<<5);
+  if ((CMSDK_USRT2->STATE & 1)==0) CMSDK_USRT2->DATA    = 0x23; // write 8'b01000011 / "#"
+  if ((CMSDK_UART2->STATE & 1)==0) CMSDK_UART2->DATA    = 0x7e; // write 8'b01111110 / "~"
   return;
 }
+
 // Output a character
 unsigned char UartPutc(unsigned char my_ch)
 {
-///  while ((CMSDK_UART2->STATE & 1)); // Wait if Transmit Holding register is full
-///  CMSDK_UART2->DATA = my_ch; // write to transmit holding register
-///  if ((CMSDK_USRT2->STATE & 1) == 0)
-  while ((CMSDK_USRT2->STATE & 1)); // Wait if Transmit Holding register is full
-  if ((CMSDK_USRT2->STATE & 1) == 0)
-    CMSDK_USRT2->DATA = my_ch; // write to transmit holding register
+//  while ((CMSDK_UART2->STATE & 1)); // Wait if Transmit Holding register is full
+//  CMSDK_UART2->DATA = my_ch; // write to transmit holding register
+//  return (my_ch);
+  while (((CMSDK_USRT2->STATE & 1)==1) && ((CMSDK_UART2->STATE & 1)==1)); // Wait if both Transmit Holding registers full
+  if ((CMSDK_USRT2->STATE & 1)==0) CMSDK_USRT2->DATA = my_ch; // write to transmit holding register
+  if ((CMSDK_UART2->STATE & 1)==0) CMSDK_UART2->DATA = my_ch; // write to transmit holding register
   return (my_ch);
 }
 // Uart string output
@@ -118,11 +121,11 @@ void FlashLoader(void)
     Likely that the user is trying to run bootloader as a test,
      which is not what this program is for.
     */
-    UartPuts("@Error: REMAP cleared\n");
+    UartPuts("!REMAP!\n");
     UartPutc(0x4); // Terminate simulation
     while (1);
     }
-  UartPuts("** Remap->IMEM0\n"); // CMSDK boot loader\n");
+  UartPuts("REMAP->IMEM0\n"); // CMSDK boot loader\n");
   CMSDK_SYSCON->REMAP = 0;  // Clear remap
   __DSB();
   __ISB();
@@ -135,7 +138,8 @@ int main (void)
   // UART init
   UartStdOutInit();
 
-  UartPuts("\n\n\nSoCLabs NanoSoC\n");
+  UartPuts("\nSoCLabs NanoSoC ARM-CM0+ADP+FT1+U38400 20240110\n");
+//  UartPuts("\nSoCLabs NanoSoC\n");
   FlashLoader();
   return 0;
 }
diff --git a/software/common/retarget/uart_stdout.c b/software/common/retarget/uart_stdout.c
index 7fff7ea..17257a0 100644
--- a/software/common/retarget/uart_stdout.c
+++ b/software/common/retarget/uart_stdout.c
@@ -43,31 +43,64 @@
 #include "CMSDK_CM4.h"
 #endif
 
+
+#define CLKFREQ    240000000
+#define BAUDRATE   38400
+#define BAUDCLKDIV (CLKFREQ / BAUDRATE)
+
 void UartStdOutInit(void)
 {
-//  CMSDK_UART2->BAUDDIV = 16;
-//  CMSDK_UART2->CTRL    = 0x41; // High speed test mode, TX only
-  CMSDK_UART2->BAUDDIV = 2080; //(1MHz/9600)
-  CMSDK_UART2->CTRL    = 0x01; //TX only, standard UART
-  CMSDK_USRT2->BAUDDIV = 2080; //(1MHz/9600)
-  CMSDK_USRT2->CTRL    = 0x03; //RX+TX, standard UART
-  CMSDK_GPIO1->ALTFUNCSET = (1<<5);
+  CMSDK_UART2->CTRL    = 0x00;       // disable whie reprogramming
+  CMSDK_UART2->BAUDDIV = BAUDCLKDIV; // (240MHz/BAUDRATE) in 16.4 format
+  CMSDK_UART2->CTRL    = 0x01;       // TX, standard UART2
+  CMSDK_USRT2->BAUDDIV =    3;       // (prescaler value)
+  CMSDK_USRT2->CTRL    = 0x03;       // RX+TX, FT1248 USRT
+  CMSDK_GPIO1->ALTFUNCSET = (1<<5);  // UART2 mapped to GP1[5,4]
   return;
 }
+
+void Uart2StdOutInit(void)
+{
+// ensure full character shift before reprogramming UART2
+  CMSDK_DUALTIMER->Timer1Load = (11 * BAUDCLKDIV); // 10+1 x baud tick clock
+  CMSDK_DUALTIMER->Timer1BGLoad = (10 * BAUDCLKDIV); // 10 x baud tick clock
+  CMSDK_DUALTIMER->Timer1IntClr = 1;
+  CMSDK_DUALTIMER->Timer1Control = 0xC3; // enable, periodic, 32-bit
+  while ((CMSDK_DUALTIMER->Timer1RIS & 1)== 0) ; // wait until any UART character time
+// reinitialize UART2
+///  CMSDK_UART2->CTRL    = 0x00;       // disable whie reprogramming
+///  CMSDK_UART2->BAUDDIV = BAUDCLKDIV; // (240MHz/BAUDRATE) in 16.4 format
+///  CMSDK_UART2->CTRL    = 0x01;       // RX+TX, standard UART2
+  CMSDK_GPIO1->ALTFUNCSET = (1<<5);  // UART2 mapped to GP1[5,4]
+  CMSDK_USRT2->CTRL    = 0x00;       // RX+TX, FT1248 USRT disabled
+  CMSDK_USRT2->BAUDDIV = 0x30;       // (prescaler low value)
+  CMSDK_USRT2->CTRL    = 0x03;       // RX+TX, FT1248 USRT disabled
+  return;
+}
+
 // Output a character
 unsigned char UartPutc(unsigned char my_ch)
 {
-//  while ((CMSDK_UART2->STATE & 1)); // Wait if Transmit Holding register is full
-//  CMSDK_UART2->DATA = my_ch; // write to transmit holding register
-  while ((CMSDK_USRT2->STATE & 1)); // Wait if Transmit Holding register is full
-  CMSDK_USRT2->DATA = my_ch; // write to transmit holding register
+  if ((CMSDK_USRT2->CTRL & 1)==0) {
+    while (CMSDK_UART2->STATE & 1); // Wait if Transmit Holding register full
+    CMSDK_UART2->DATA = my_ch; // write to transmit holding register
+    CMSDK_USRT2->DATA = my_ch; // (also write to transmit holding register)
+  } else {
+    while (CMSDK_USRT2->STATE & 1); // Wait if Transmit Holding register full
+    CMSDK_USRT2->DATA = my_ch; // write to transmit holding register
+  }
   return (my_ch);
 }
 // Get a character
 unsigned char UartGetc(void)
 {
-  while ((CMSDK_USRT2->STATE & 2)==0); // Wait if Receive Holding register is empty
-  return (CMSDK_USRT2->DATA);
+  if ((CMSDK_USRT2->CTRL & 1)==0) {
+    while ((CMSDK_UART2->STATE & 2)==0);
+    return (CMSDK_UART2->DATA);
+  } else {
+    while ((CMSDK_USRT2->STATE & 2)==0);
+    return (CMSDK_USRT2->DATA);
+  }
 }
 
 void UartEndSimulation(void)
diff --git a/software/common/retarget/uart_stdout.h b/software/common/retarget/uart_stdout.h
index ec0f88b..e6d40ee 100644
--- a/software/common/retarget/uart_stdout.h
+++ b/software/common/retarget/uart_stdout.h
@@ -25,6 +25,7 @@
 /* The functions are implemented in shared/software/common/uart_stdout.c */
 
 extern void UartStdOutInit(void);
+extern void Uart2StdOutInit(void);
 extern unsigned char UartPutc(unsigned char my_ch);
 extern unsigned char UartGetc(void);
 extern unsigned char UartEndSimulation(void);
diff --git a/verif/tb/verilog/nanosoc_tb.v b/verif/tb/verilog/nanosoc_tb.v
index e8b272e..7028c23 100644
--- a/verif/tb/verilog/nanosoc_tb.v
+++ b/verif/tb/verilog/nanosoc_tb.v
@@ -229,20 +229,20 @@ initial begin
 // seem unable to use the following (due to generate instance naming?)
 //  wire baudx16_clk = u_cmsdk_mcu.u_cmsdk_mcu.u_cmsdk_mcu_system.u_apb_subsystem.u_apb_uart_2.BAUDTICK;
 
-// 2000000/208 = 9615 baud (+0.16%)
-// 208 / 16
-`define BAUDPROG 130
+// 240000000/6250 = 38400 baud
+// 6250/16 = 390.625
+`define BAUDPROGDIV16 389
 
- reg [7:0] bauddiv;
- wire    baudclken = (bauddiv == 8'b00000000);
+ reg [8:0] bauddiv;
+ wire    baudclken = (bauddiv == 9'b0);
 
   always @(negedge NRST or posedge PCLK)
     if (!NRST)
       bauddiv <=0;
     else
-      bauddiv <= (baudclken) ? (`BAUDPROG-1) : (bauddiv -1) ;   // count down of BAUDPROG
+      bauddiv <= (baudclken) ? (`BAUDPROGDIV16-1) : (bauddiv -1) ;   // count down of BAUDPROG
 
-  wire baudx16_clk = bauddiv[7]; //prefer:// !baudclken;
+  wire baudx16_clk = bauddiv[8]; //prefer:// !baudclken;
 
   wire UARTXD =  P1[5];
   reg  UARTXD_del;
-- 
GitLab