Merge pull request #1112 from 2a17/option_bytes_for_stm32f0

Support for writing option bytes on STM32F0/F1/F3
pull/1141/head
nightwalker-87 2021-05-10 21:48:08 +02:00 zatwierdzone przez GitHub
commit 48ebad3513
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 269 dodań i 66 usunięć

Wyświetl plik

@ -30,15 +30,9 @@ copy:
# add r3 to flash_base for support dual bank (see flash_loader.c)
ldr r7, flash_base
add r7, r7, r3
ldr r6, flash_off_cr
add r6, r6, r7
ldr r5, flash_off_sr
add r5, r5, r7
# FLASH_CR = 0x01 (set PG)
ldr r4, =0x1
str r4, [r6]
loop:
# copy 2 bytes
ldrh r4, [r0]
@ -68,18 +62,10 @@ wait:
bgt loop
exit:
# FLASH_CR &= ~1
ldr r7, =0x1
ldr r4, [r6]
bics r4, r4, r7
str r4, [r6]
bkpt
.align 2
flash_base:
.word 0x40022000
flash_off_cr:
.word 0x10
flash_off_sr:
.word 0x0c

Wyświetl plik

@ -87,9 +87,11 @@
#define FLASH_CR_PER 1
#define FLASH_CR_MER 2
#define FLASH_CR_OPTPG 4
#define FLASH_CR_OPTER 5
#define FLASH_CR_STRT 6
#define FLASH_CR_LOCK 7
#define FLASH_CR_OPTWRE 9
#define FLASH_CR_OBL_LAUNCH 13
#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00)
#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00)
@ -3137,17 +3139,6 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
}
int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) {
// According to DDI0419C, Table C1-7 firstly force halt
stlink_write_debug32(sl, STLINK_REG_DHCSR,
STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN |
STLINK_REG_DHCSR_C_HALT);
// and only then disable interrupts
stlink_write_debug32(sl, STLINK_REG_DHCSR,
STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN |
STLINK_REG_DHCSR_C_HALT |
STLINK_REG_DHCSR_C_MASKINTS);
// disable DMA
set_dma_state(sl, fl, 0);
@ -3257,6 +3248,15 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) {
ELOG("stlink_flash_loader_init() == -1\n");
return (-1);
}
// unlock flash
unlock_flash_if(sl);
// set programming mode
set_flash_cr_pg(sl, BANK_1);
if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
set_flash_cr_pg(sl, BANK_2);
}
} else if (sl->flash_type == STLINK_FLASH_TYPE_H7) {
ILOG("Starting Flash write for H7\n");
@ -3437,7 +3437,9 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl,
int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) {
uint32_t dhcsr;
if ((sl->flash_type == STLINK_FLASH_TYPE_F4) ||
if ((sl->flash_type == STLINK_FLASH_TYPE_F0) ||
(sl->flash_type == STLINK_FLASH_TYPE_F1_XL) ||
(sl->flash_type == STLINK_FLASH_TYPE_F4) ||
(sl->flash_type == STLINK_FLASH_TYPE_F7) ||
(sl->flash_type == STLINK_FLASH_TYPE_L4) ||
(sl->flash_type == STLINK_FLASH_TYPE_WB) ||
@ -3446,8 +3448,9 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) {
(sl->flash_type == STLINK_FLASH_TYPE_H7)) {
clear_flash_cr_pg(sl, BANK_1);
if (sl->flash_type == STLINK_FLASH_TYPE_H7 &&
sl->chip_flags & CHIP_F_HAS_DUAL_BANK) {
if ((sl->flash_type == STLINK_FLASH_TYPE_H7 &&
sl->chip_flags & CHIP_F_HAS_DUAL_BANK) ||
sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
clear_flash_cr_pg(sl, BANK_2);
}
lock_flash(sl);
@ -3840,6 +3843,64 @@ int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) {
return (err);
}
/**
* Write option bytes
* @param sl
* @param base option bytes to write
* @param addr of the memory mapped option bytes
* @param len of options bytes to write
* @return 0 on success, -ve on failure.
*/
static int stlink_write_option_bytes_f0(
stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) {
int ret = 0;
if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) {
WLOG("Only full write of option bytes area is supported\n");
return -1;
}
clear_flash_error(sl);
WLOG("Erasing option bytes\n");
/* erase option bytes */
stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE));
ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE));
if (ret) {
return ret;
}
wait_flash_busy(sl);
ret = check_flash_error(sl);
if (ret) {
return ret;
}
WLOG("Writing option bytes to %#10x\n", addr);
/* Set the Option PG bit to enable programming */
stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE));
/* Use flash loader for write OP
* because flash memory writable by half word */
flash_loader_t fl;
ret = stlink_flash_loader_init(sl, &fl);
if (ret) {
return ret;
}
ret = stlink_flash_loader_run(sl, &fl, addr, base, len);
if (ret) {
return ret;
}
/* Reload option bytes */
stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH));
return check_flash_error(sl);
}
/**
* Write option bytes
* @param sl
@ -4192,6 +4253,18 @@ int stlink_read_option_control_register_f7(stlink_t *sl,
return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte);
}
/**
* Read option bytes
* @param sl
* @param option_byte value to read
* @return 0 on success, -ve on failure.
*/
int stlink_read_option_control_register_f0(stlink_t *sl,
uint32_t *option_byte) {
DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR);
return stlink_read_debug32(sl, FLASH_OBR, option_byte);
}
/**
* Read option bytes
* @param sl
@ -4335,8 +4408,8 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) {
return -1;
}
switch (sl->chip_id) {
case STLINK_CHIPID_STM32_F7XXXX:
switch (sl->flash_type) {
case STLINK_FLASH_TYPE_F7:
return stlink_read_option_bytes_boot_add_f7(sl, option_byte);
default:
return -1;
@ -4356,12 +4429,14 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) {
return -1;
}
switch (sl->chip_id) {
case STLINK_CHIPID_STM32_F7XXXX:
switch (sl->flash_type) {
case STLINK_FLASH_TYPE_F0:
case STLINK_FLASH_TYPE_F1_XL:
return stlink_read_option_control_register_f0(sl, option_byte);
case STLINK_FLASH_TYPE_F7:
return stlink_read_option_control_register_f7(sl, option_byte);
default:
return -1;
// return stlink_read_option_control_register_generic(sl, option_byte);
}
}
@ -4378,8 +4453,8 @@ int stlink_read_option_control_register1_32(stlink_t *sl,
return -1;
}
switch (sl->chip_id) {
case STLINK_CHIPID_STM32_F7XXXX:
switch (sl->flash_type) {
case STLINK_FLASH_TYPE_F7:
return stlink_read_option_control_register1_f7(sl, option_byte);
default:
return -1;
@ -4441,6 +4516,10 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
}
switch (sl->flash_type) {
case STLINK_FLASH_TYPE_F0:
case STLINK_FLASH_TYPE_F1_XL:
ret = stlink_write_option_bytes_f0(sl, base, addr, len);
break;
case STLINK_FLASH_TYPE_F4:
ret = stlink_write_option_bytes_f4(sl, base, addr, len);
break;
@ -4511,6 +4590,95 @@ stlink_write_option_control_register_f7(stlink_t *sl,
return ret;
}
/**
* Write option bytes
* @param sl
* @param option_byte value to write
* @return 0 on success, -ve on failure.
*/
static int
stlink_write_option_control_register_f0(stlink_t *sl,
uint32_t option_control_register) {
int ret = 0;
uint16_t opt_val[8];
unsigned protection, optiondata;
uint16_t user_options, user_data, rdp;
unsigned option_offset, user_data_offset;
ILOG("Asked to write option control register %#10x to %#010x.\n",
option_control_register, FLASH_OBR);
/* Clear errors */
clear_flash_error(sl);
/* Retrieve current values */
ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata);
if (ret) {
return ret;
}
ret = stlink_read_debug32(sl, FLASH_WRPR, &protection);
if (ret) {
return ret;
}
/* Translate OBR value to flash store structure
* F0: RM0091, Option byte description, pp. 75-78
* F1: PM0075, Option byte description, pp. 19-22
* F3: RM0316, Option byte description, pp. 85-87 */
switch(sl->chip_id)
{
case 0x422: /* STM32F30x */
case 0x432: /* STM32F37x */
case 0x438: /* STM32F303x6/8 and STM32F328 */
case 0x446: /* STM32F303xD/E and STM32F398xE */
case 0x439: /* stm32f302x6/8 */
case 0x440: /* stm32f05x */
case 0x444: /* stm32f03x */
case 0x445: /* stm32f04x */
case 0x448: /* stm32f07x */
case 0x442: /* stm32f09x */
option_offset = 6;
user_data_offset = 16;
rdp = 0x55AA;
break;
default:
option_offset = 0;
user_data_offset = 10;
rdp = 0x5AA5;
break;
}
user_options = (option_control_register >> option_offset >> 2) & 0xFFFF;
user_data = (option_control_register >> user_data_offset) & 0xFFFF;
#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00))
opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp;
opt_val[1] = VAL_WITH_COMPLEMENT(user_options);
opt_val[2] = VAL_WITH_COMPLEMENT(user_data);
opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8);
opt_val[4] = VAL_WITH_COMPLEMENT(protection);
opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8);
opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16);
opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24);
#undef VAL_WITH_COMPLEMENT
/* Write bytes and check errors */
ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val));
if (ret)
return ret;
ret = check_flash_error(sl);
if (!ret) {
ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register,
FLASH_OBR);
}
return ret;
}
/**
* Write option bytes
* @param sl
@ -4631,6 +4799,10 @@ int stlink_write_option_control_register32(stlink_t *sl,
}
switch (sl->flash_type) {
case STLINK_FLASH_TYPE_F0:
case STLINK_FLASH_TYPE_F1_XL:
ret = stlink_write_option_control_register_f0(sl, option_control_register);
break;
case STLINK_FLASH_TYPE_F7:
ret = stlink_write_option_control_register_f7(sl, option_control_register);
break;

Wyświetl plik

@ -57,6 +57,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x5000,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -83,6 +85,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x2800,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -162,6 +166,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x10000,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -232,6 +238,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x10000,
.bootrom_base = 0x1fffb000,
.bootrom_size = 0x4800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -244,6 +252,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x2000, // 0x1000 for low density devices
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -283,6 +293,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0xa000,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -296,6 +308,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0xa000,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -307,6 +321,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x8000,
.bootrom_base = 0x1ffff000,
.bootrom_size = 0x800,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -332,12 +348,14 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base =
0x1fffC800, // "System memory" starting address from Table 2
.bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
},
{
// Use this as an example for mapping future chips:
// RM0091 document was used to find these paramaters
.chip_id = STLINK_CHIPID_STM32_F0,
.description = "F0xx",
.description = "F05x",
.flash_type = STLINK_FLASH_TYPE_F0,
.flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735)
.flash_pagesize = 0x400, // Page sizes listed in Table 4
@ -345,6 +363,8 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base =
0x1fffec00, // "System memory" starting address from Table 2
.bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
},
{
// RM0402 document was used to find these parameters
@ -387,6 +407,8 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base =
0x1fffd800, // "System memory" starting address from Table 2
.bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
},
{
// Use this as an example for mapping future chips:
@ -400,12 +422,14 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base =
0x1fffec00, // "System memory" starting address from Table 2
.bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
},
{
// Use this as an example for mapping future chips:
// RM0091 document was used to find these paramaters
.chip_id = STLINK_CHIPID_STM32_F0_SMALL,
.description = "F0xx small",
.description = "F03x",
.flash_type = STLINK_FLASH_TYPE_F0,
.flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735)
.flash_pagesize = 0x400, // Page sizes listed in Table 4
@ -413,6 +437,8 @@ static const struct stlink_chipid_params devices[] = {
.bootrom_base =
0x1fffec00, // "System memory" starting address from Table 2
.bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
},
{
// STM32F30x
@ -424,6 +450,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0xa000,
.bootrom_base = 0x1fffd800,
.bootrom_size = 0x2000,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -479,6 +507,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x3000,
.bootrom_base = 0x1fffd800,
.bootrom_size = 0x2000,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{
@ -492,6 +522,8 @@ static const struct stlink_chipid_params devices[] = {
.sram_size = 0x10000, // 3.3 Embedded SRAM
.bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory
.bootrom_size = 0x2000,
.option_base = STM32_F0_OPTION_BYTES_BASE,
.option_size = 16,
.flags = CHIP_F_HAS_SWO_TRACING,
},
{

Wyświetl plik

@ -19,44 +19,33 @@
/* flashloaders/stm32f0.s -- compiled with thumb2 */
static const uint8_t loader_code_stm32vl[] = {
0x00, 0xbf, 0x00, 0xbf,
0x0e, 0x4f, 0x1f, 0x44,
0x0e, 0x4e, 0x3e, 0x44,
0x0e, 0x4d, 0x3d, 0x44,
0x4f, 0xf0, 0x01, 0x04,
0x34, 0x60, 0x04, 0x88,
0x0c, 0x80, 0x02, 0x30,
0x02, 0x31, 0x4f, 0xf0,
0x01, 0x07, 0x2c, 0x68,
0x3c, 0x42, 0xfc, 0xd1,
0x4f, 0xf0, 0x14, 0x07,
0x3c, 0x42, 0x01, 0xd1,
0x02, 0x3a, 0xf0, 0xdc,
0x09, 0x4f, 0x1f, 0x44,
0x09, 0x4d, 0x3d, 0x44,
0x04, 0x88, 0x0c, 0x80,
0x02, 0x30, 0x02, 0x31,
0x4f, 0xf0, 0x01, 0x07,
0x34, 0x68, 0xbc, 0x43,
0x34, 0x60, 0x00, 0xbe,
0x2c, 0x68, 0x3c, 0x42,
0xfc, 0xd1, 0x4f, 0xf0,
0x14, 0x07, 0x3c, 0x42,
0x01, 0xd1, 0x02, 0x3a,
0xf0, 0xdc, 0x00, 0xbe,
0x00, 0x20, 0x02, 0x40,
0x10, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00
};
/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */
static const uint8_t loader_code_stm32f0[] = {
0xc0, 0x46, 0xc0, 0x46,
0x0c, 0x4f, 0x1f, 0x44,
0x0c, 0x4e, 0x3e, 0x44,
0x0c, 0x4d, 0x3d, 0x44,
0x0c, 0x4c, 0x34, 0x60,
0x08, 0x4f, 0x1f, 0x44,
0x08, 0x4d, 0x3d, 0x44,
0x04, 0x88, 0x0c, 0x80,
0x02, 0x30, 0x02, 0x31,
0x09, 0x4f, 0x2c, 0x68,
0x06, 0x4f, 0x2c, 0x68,
0x3c, 0x42, 0xfc, 0xd1,
0x08, 0x4f, 0x3c, 0x42,
0x05, 0x4f, 0x3c, 0x42,
0x01, 0xd1, 0x02, 0x3a,
0xf2, 0xdc, 0x05, 0x4f,
0x34, 0x68, 0xbc, 0x43,
0x34, 0x60, 0x00, 0xbe,
0xf2, 0xdc, 0x00, 0xbe,
0x00, 0x20, 0x02, 0x40,
0x10, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00
@ -159,6 +148,17 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) {
size_t size = 0;
uint32_t dfsr, cfsr, hfsr;
/* Interrupt masking.
* According to DDI0419C, Table C1-7 firstly force halt */
stlink_write_debug32(sl, STLINK_REG_DHCSR,
STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN |
STLINK_REG_DHCSR_C_HALT);
/* and only then disable interrupts */
stlink_write_debug32(sl, STLINK_REG_DHCSR,
STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN |
STLINK_REG_DHCSR_C_HALT |
STLINK_REG_DHCSR_C_MASKINTS);
// allocate the loader in SRAM
if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) {
WLOG("Failed to write flash loader to sram!\n");

Wyświetl plik

@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>
#include "logging.h"
@ -29,10 +30,22 @@ int ugly_log(int level, const char *tag, const char *format, ...) {
va_list args;
va_start(args, format);
time_t mytt = time(NULL);
struct tm *tt;
tt = localtime(&mytt);
fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900,
tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec);
struct tm *ptt;
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) // C11
struct tm tt;
ptt = &tt;
# if defined (_WIN32) || defined(__STDC_LIB_EXT1__)
localtime_s(&tt, &mytt);
# else
localtime_r(&mytt, &tt);
# endif
#else
ptt = localtime(&mytt);
#endif
fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", ptt->tm_year + 1900,
ptt->tm_mon + 1, ptt->tm_mday, ptt->tm_hour, ptt->tm_min, ptt->tm_sec);
switch (level) {
case UDEBUG: