Friday, March 20, 2026

comfile사의 CWV 시리즈 개발도구인 cwv sdk 설치 오류 해결방법

 cwv_sdk.exe를 받아서 설치하는 도중에 


ToolsMsmCA(Error): IHxRegisterSession transaction failure: Err = 0x8004036f, pRegSession->CommitTransaction()


이러한 오류가 난다면, help 시스템에 등록하는 과정에서 오류가 나는건데 이거해결방법은 따로 없는거 같고

filter 설치를 하지 않도록 수정하면됨. 

그렇게 수정한것을 올려드립니다. 이거 쓰세요.

 아래 링크는 오류를 수정한 CWV_SDK 입니다.


https://drive.google.com/file/d/1yfKqceWzi2J6WiXYJKx5eoAhczsx5Lfx/view?usp=sharing


Friday, October 24, 2025

stm32 외부 RAM에 변수 배치방법


STM32CubeIDE 기준임.


 먼저 Loader 스크립트를 수정해야함


외부 RAM이 0x90000000에서 시작하고 용량이 32MB라는 가정을 하면,


__EXTRAM_BEGIN = 0x90000000;

__EXTRAM_SIZE = 0x02000000;


__RAM_BEGIN = 0x24000000;

__RAM_SIZE = 0x71C00;

__RAM_NONCACHEABLEBUFFER_SIZE = 0x400;


/* Memories definition */

MEMORY

{

RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE

RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE


ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000

DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000

SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000

BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000


FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE

EXTRAM (rw) : ORIGIN = __EXTRAM_BEGIN, LENGTH = __EXTRAM_SIZE

/* EXT_FLASH (rx) : ORIGIN = 0x70000000, LENGTH = 8192K */

}


.....


SECTIONS

{


    ... 생략...


/* 외부 램 사용자 섹션 */

.ext_ram_data (NOLOAD) : {

. = ALIGN(4);

*(.ext_ram_data)

. = ALIGN(4);

} > EXTRAM

    ... 생략...

}


처럼 수정한다.


NOLOAD는 매우 중요하다. 이것은 flash에 초기화 값을 사용하지 않겠다는것이다. 따라서

기본값 지정은 불가능함.

내가 사용하는 STM32H7시리즈 칩이 내부 플래시가 워낙 작고, 나는 단지 RAM을 확장할것이

때문에 RAM만 늘리면 되기에 초기값은 사용하지 않은것이다.



그리고 변수를 만들때에는



__attribute__((section(".ext_ram_data"))) uint8_t ext_ram_variable_example1[100];



이런식으로 section을 직접 지정해준다.



Tuesday, October 14, 2025

stm32 external loader에서 qspi사용하는 메모리에서 256바이트만 써지고 나머지가 안써질때

stm32_sfdp_driver.c파일에서

EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Write(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, uint32_t Address, const uint8_t* Data, uint32_t Size)

{

EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr;

uint32_t size_write;

uint32_t local_size = Size;

uint32_t local_Address = Address;

uint32_t local_Data = (uint32_t)Data;

uint32_t misalignment = 0u;


SFDPObject->sfpd_private.PageSize = 0x100; // 이거 추가


....

}



오류가 나는 경우는 프로그램 페이지 크기가 제대로 안들어가는거 같다.




Thursday, October 9, 2025

STM32CubeProgrammer error when Erase full chip External Flash.

Version 2.17 is no error

Version 2.20 - error


STM32CubeProgrammer 2.17 is stable.


STM32CubeProgrammer를 위한 External loader에서 Write한것이 첫바이트가 사라질때

STM32CubeMX 최신버전 (6.15)이상에서 External Loader를 만들면 기본적인 기능을 모두 만들어준다.

그런데 QSPI용 Nor flash  메모리 MX25L6433F를 사용하도록 세팅해보니 내가 Write한 내용의 첫바이트가 사라지는 현상이 있었다.


원인을 찾아보니 Flash write,read명령 중에 dummy cycle가 필요한 경우도 있지만 없는 경우도 있음에도 불구하고

dummy cycle이 8로 지정되어있음을 확인했고, 그것을 0으로 변경하니 잘 돌아갔다.


문제의 코드는 이러하다


Muddlewares/ST/STM32_ExtMem_Manager/stm32_sal_xspi.c 

HAL_StatusTypeDef SAL_XSPI_MemoryConfig(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_MemParamTypeTypeDef ParametersType, void *ParamVal)

{

HAL_StatusTypeDef retr = HAL_OK;

XSPI_RegularCmdTypeDef s_commandbase = SalXspi->Commandbase;


switch (ParametersType) {

case PARAM_PHY_LINK:{

SalXspi->PhyLink = *((SAL_XSPI_PhysicalLinkTypeDef *)ParamVal);

DEBUG_PARAM_BEGIN(); DEBUG_PARAM_DATA("::PARAM_PHY_LINK::");DEBUG_PARAM_DATA(STR_PHY_LINK(SalXspi->PhyLink));

switch (SalXspi->PhyLink)

{

case PHY_LINK_1S1D1D:

case PHY_LINK_1S2S2S:

case PHY_LINK_1S1S2S:

case PHY_LINK_1S1S1S: {

s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;

s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;

s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;

s_commandbase.AddressMode = HAL_XSPI_ADDRESS_1_LINE;

s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;

s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;

s_commandbase.DataMode = HAL_XSPI_DATA_1_LINE;

s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;

s_commandbase.DummyCycles = 8; // 0으로 변경해야함

s_commandbase.DQSMode = HAL_XSPI_DQS_DISABLE;

break;

}


이하 생략



위에서 DummyCycles를 0으로 수정하면 잘 돌아간다.




-----------------------------------

Problem : STM32CubeMx generated External loader miss first byte write/read with QSPI Flash memory

Solution : Change DummyCycles to 0



Saturday, August 2, 2025

STM32 시리즈 SPI로 SD카드 읽고 쓰는 소스중에서 


 https://github.com/eziya/STM32_SPI_SDCARD/

가 있다.


이 소스중에 

 https://github.com/eziya/STM32_SPI_SDCARD/blob/master/STM32F4_HAL_SPI_SDCARD/Src/fatfs_sd.c




while(len--); 구문은 오류임.


실제로는 len 보다 1 만큼 많이 실행되어 메모리 침범 오류를 만듭니다.


/* receive data block */

static bool SD_RxDataBlock(BYTE *buff, UINT len)

{

uint8_t token;


/* timeout 200ms */

Timer1 = 200;


/* loop until receive a response or timeout */

do {

token = SPI_RxByte();

} while((token == 0xFF) && Timer1);


/* invalid response */

if(token != 0xFE) return FALSE;


/* receive data */

do {

SPI_RxBytePtr(buff++);

len--;


} while(len--);


/* discard CRC */

SPI_RxByte();

SPI_RxByte();


return TRUE;

}


이것은 아래처럼 수정해야함.



/* receive data block */

static bool SD_RxDataBlock(BYTE *buff, UINT len)

{

uint8_t token;


/* timeout 200ms */

Timer1 = 200;


/* loop until receive a response or timeout */

do {

token = SPI_RxByte();

} while((token == 0xFF) && Timer1);


/* invalid response */

if(token != 0xFE) return FALSE;


/* receive data */

do {

SPI_RxBytePtr(buff++);

len--;


} while(len !=0);


/* discard CRC */

SPI_RxByte();

SPI_RxByte();


return TRUE;

}



len-- 대신 --len을 써도 된다.

그러지 말고 명확하게 하기 위해서 --는 먼저 하고 비교문을 확실히 넣는것이 낫다.




Monday, February 5, 2024

xdebug 무조건 트레이스 시작시키기(xDebug, stop break point always setup)

php.ini 에 xdebug 설정을 넣을때 아래와 같이 설정하면 된다.

dll 파일의 이름은 각자 자기 상황에 맞게 수정하시라.


this setup will stopped always on break point. 

DLL filename depends on your system.



[xdebug]

zend_extension="php_xdebug-3.3.0-8.1-vs16-nts-x86_64.dll"

xdebug.mode=debug

xdebug.default_enable = 1

xdebug.remote_enable = 1

xdebug.remote_autostart = 1

xdebug.idekey="PHPSTORM"

xdebug.client_host=127.0.0.1

xdebug.client_port=9000

xdebug.start_with_request=yes

Sunday, January 28, 2024

NanoCAD is Free CAD program like AutoCAD

NanoCAD is free for personal cad program. Usage is same as AutoCAD.

go to nanocad.com, download personal version. 

https://nanocad.com/personal/






Saturday, January 27, 2024

HardFault (error ) on STM32 USB Host + FreeRTOS

I have Hard fault when USB device Attached to my STM32F407.


STM32CubeMX makes rtos STACK SIZE default to 128 bytes.

It is too small.


You can increase stack size.


Filename : USB_HOST/Target/usbh_config.h


Original (ERROR case)


#if (USBH_USE_OS == 1)

#include "cmsis_os.h"

#define USBH_PROCESS_PRIO osPriorityNormal

#define USBH_PROCESS_STACK_SIZE ((uint16_t)128)

#endif /* (USBH_USE_OS == 1) */



Fix (ERROR case)


#if (USBH_USE_OS == 1)

#include "cmsis_os.h"

#define USBH_PROCESS_PRIO osPriorityNormal

#define USBH_PROCESS_STACK_SIZE ((uint16_t)2048)

#endif /* (USBH_USE_OS == 1) */

 





Sunday, October 29, 2023

Kirisun DP405 DMR Radio Walkie walkie programming cable pinout

Kirisun DP-405

Kirisun DP405

Programming cable pinout:




I tested cable with FTDI usb serial TTL module.

It works.


Wednesday, October 25, 2023

Monday, August 28, 2023

Wednesday, June 14, 2023

ESP32 Clear(disable) esp_deep_sleep_enable_gpio_wakeup

in ESP32 C3

esp32 c3 have no disable gpio wakeup function. so, gpio wakeup masks adds only. 

PROBLEM:

step 1: 
    esp_deep_sleep_enable_gpio_wakeup( 1<<GPIO_NUM_2 , 0 );
    esp_deep_sleep_enable_gpio_wakeup( 1<<GPIO_NUM_5 , 0 );
    esp_deep_sleep_start();
step 2: 
    wakeup 
step 3:
    esp_deep_sleep_enable_gpio_wakeup( 1<<GPIO_NUM_5 , 0 );
    esp_deep_sleep_start();
step 4 (problem):
    ESP32 can wakeup by GPIO_NUM_2 !!!!
    

Reason: ESP32 SDK 

esp_deep_sleep_enable_gpio_wakeup does not clear for other pins.

You can modify SDK source code.

sleep_modes.c   esp_deep_sleep_enable_gpio_wakeup function


esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
{
    if (mode > ESP_GPIO_WAKEUP_GPIO_HIGH) {
        ESP_LOGE(TAG, "invalid mode");
        return ESP_ERR_INVALID_ARG;
    }
    gpio_int_type_t intr_type = ((mode == ESP_GPIO_WAKEUP_GPIO_LOW) ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
    esp_err_t err = ESP_OK;
   
    /*s_config.gpio_wakeup_mask = 0;
    for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++, gpio_pin_mask >>= 1)
    {
       gpio_deep_sleep_wakeup_disable(gpio_idx);
   }*/
   
   
    for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < 6; gpio_idx++, gpio_pin_mask >>= 1) {
        if ((gpio_pin_mask & 1) == 0) {
           s_config.gpio_wakeup_mask &= ~BIT(gpio_idx);
           gpio_deep_sleep_wakeup_disable(gpio_idx);
           
            continue;
        }
        if (!esp_sleep_is_valid_wakeup_gpio(gpio_idx)) {
            ESP_LOGE(TAG, "invalid mask, please ensure gpio number is no more than 5");
            return ESP_ERR_INVALID_ARG;
        }
        err = gpio_deep_sleep_wakeup_enable(gpio_idx, intr_type);

        s_config.gpio_wakeup_mask |= BIT(gpio_idx);
        if (mode == ESP_GPIO_WAKEUP_GPIO_HIGH) {
            s_config.gpio_trigger_mode |= (mode << gpio_idx);
        } else {
            s_config.gpio_trigger_mode &= ~(mode << gpio_idx);
        }
    }
    s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
   
    rtc_hal_gpio_clear_wakeup_status();
    return err;
}


after modify , If you want use multiple pins for wakeup source, 
call esp_deep_sleep_enable_gpio_wakeup with pin bitmask. 
example: esp_deep_sleep_enable_gpio_wakeup(  1<<GPIO_NUM_2 |  1<<GPIO_NUM_5 );



In my case , sleep_modes.c located on C:\Espressif\frameworks\esp-idf-5.0\components\esp_hw_support


Wednesday, April 26, 2023

Get serial pin event and status(level) c#(ring, cts, dsr, rlsd)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.IO.Ports;

using System.Reflection;

using System.Runtime.InteropServices;

using Microsoft.Win32.SafeHandles;


namespace SerialEventMonitor

{

    class Program

    {

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        static extern Boolean GetCommModemStatus(SafeFileHandle hFile, ref UInt32 Status);


        const UInt32 MS_CTS_ON = 0x0010;

        const UInt32 MS_DSR_ON = 0x0020;

        const UInt32 MS_RING_ON = 0x0040;

        const UInt32 MS_RLSD_ON = 0x0080;


        static void Main(string[] args)

        {


            Console.WriteLine( string.Join( ",",SerialPort.GetPortNames()));

            

            string com_port_name = Console.ReadLine();



            SerialPort port = new SerialPort(com_port_name.Trim(), 9600, Parity.None, 8, StopBits.One);

            port.PinChanged += PinChanged;

            

            port.Open();


            DateTime dt_Start = DateTime.MinValue;            

            while(true)

            {

                if( port.ReadExisting() == "q")

                    break;


                System.Threading.Thread.Sleep(1000);

            }

            port.Close();

            port.Dispose();

        }


        private static void PinChanged(object sender, SerialPinChangedEventArgs e)

        {

            SerialPort port = sender as SerialPort;


            Console.WriteLine( e.EventType.ToString());

            ShowPinStates(port);

        }

        static private void ShowPinStates(System.IO.Ports.SerialPort serialPort)

        {

            UInt32 Status = 0;

            Boolean CTS = false;

            Boolean DSR = false;

            Boolean DCD = false;

            Boolean RI = false;


            if (serialPort == null) return;

            if (serialPort.IsOpen)

            {

                object baseStream = serialPort.BaseStream;

                Type baseStreamType = baseStream.GetType();


                // Get the Win32 file handle for the port

                SafeFileHandle portFileHandle = (SafeFileHandle)baseStreamType.GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(baseStream);


                if (GetCommModemStatus(portFileHandle, ref Status))

                {

                    CTS = ((Status & MS_CTS_ON) == MS_CTS_ON);

                    DSR = ((Status & MS_DSR_ON) == MS_DSR_ON);

                    DCD = ((Status & MS_RLSD_ON) == MS_RLSD_ON);

                    RI = ((Status & MS_RING_ON) == MS_RING_ON);


                    Console.WriteLine(RI);


                }

            }

        }

    }

}


Friday, June 24, 2022

How to use Mitutoyo Digimatic Indicator Interface cable ( USB-ITN ) by VCP(serial) API




Mitsutoyo digimatic dial indicator has 10 pin idc connector. port interface is not standard spec. It needs USB cable for this device and computer programming.



USB-ITN cable runs as HID device, HID device has no COM port. 

Mitsutoyo supplies VCP driver for using as Serial port(COM port).


1. download VCP driver bellow link.

https://drive.google.com/file/d/1Jqvw-fO2zItXSliuVXSOlYRzt5G7uoM9/view?usp=sharing

2. download API manual 
3. Install VCP driver.
   Right click the file "usb-itn.inf" and run "install driver".
4. connect USB-ITN cable to computer.
   it will be installed automatically.
5. Open serial terminal program and connect to COM port.
6. typing "1" and press Enter key.



---------------------------------------------------
command syntax
---------------------------------------------------
request:
[1 byte command ][carridge return]

response:
[1 byte command ][1byte channel][1 byte type][ variable length data ......][carridge return]




---------------------------------------------------
command list 
---------------------------------------------------

V : DEVICE INFORMATION
1 : DATA REQ CMD
0 : MEASURED DATA RESPONSE
8 : FOOT SWITCH
9 : STATUS

ETX : 0x0d (\r)


---------------------------------------------------
example
---------------------------------------------------

REQ RES
-------------------------------
V 1ITN49001557
1 01A+0003.770


---------------------------------------------------
packet description
---------------------------------------------------
0 data command
1 channel (1, fixed)
A normal data(A, fixed)
+ sign
0 value
0
0
3
.
7
7
0
0x0d(\r)



Thursday, August 27, 2020

TDA7468이 소리를 내지 않을때. (TDA7468 not works)

TDA7468 의 Surround 기능을 off 하면 출력이 나오지 않는다.

register 0x02 에  0x19를 넣어주자.


--------------------------
if TDA7468 not works

write 0x19 into register 0x02  (surround)


ISE Design suite에서 File Open 을 하면 프로그램이 꺼진다면 (Crash on ISE Design Suite File Open Menu)

설치되어있는 디렉토리 밑에 

예를 들면 


C:\Xilinx\14.4\ISE_DS\ISE\bin\nt64

에 있는

libPortabilityNOSH.dll 을 libPortability.dll 로 대체한다.


즉. 원래있던 libPortability.dll 를 LibPortability_old.dll 식으로 백업해놓고

libPortabilityNOSH.dll 을 libPortability.dll 로 복사해넣으면됨.


1. Backup libPortability.dll 

2. Delete libPortability.dll 

3. Duplicate  libPortabilityNOSH.dll 

4. Rename "libPortabilityNOSH.dll 's copy"  to libPortability.dll 


Saturday, February 23, 2019

Raspberry pi zero w Blank monitor problem with MiniHDMI gender connector

라즈베리파이 제로의 HDMI 커넥터가 mini hdmi 이다 보니 일반 hdmi 케이블을 사용하기 위하여 gender 를 꼽아쓰게 되는데

이 젠더가 안좋으면 화면이 안나온다.

무조건 안나오는것은 아니고 모니터에 따라서 다르다.

차라리 고급진 mini hdmi - hdmi 케이블을 사서 쓰자.



Use mini HDMI to HDMI cable.

Do not use mini HDMI - HDMI gender ( watch upper picture )

Sunday, December 30, 2018

Change Arduino Editor Tab size. 아두이노 에디터 탭 크기 변경


C:\Users\사용자이름\AppData\Local\Arduino15\preferences.txt

파일을 열어서
editor.tabs.size 항목을 변경하세요.

반드시 아두이노 개발툴을 끈 상태에서 편집하고 저장한 후

아두이노 개발툴을 실행하세요.

그리고 자동 포멧시 탭 크기도 변경하세요.

아두이노 IDE가 설치된 폴더의 lib폴더 안의 formatter.conf 파일을 열어

indent=spaces=2  항목의 숫자를 수정하고 저장하세요.

보통 위치는 C:\Program Files (x86)\Arduino\lib\formatter.conf 입니다.

편집 후 저장할 때 저장이 안되면 메모장을 관리자 권한으로 실행하여 파일 열기로 들어가서 직접 열면 편집 가능합니다.

Friday, July 13, 2018

STM8S PB4 PB5 output not works 출력 안되는 문제

STM8S 의

PB4, PB5 는 OD 출력만된다.


STM8S
PB4, PB5  have no Push-Pull output.  have only Open drain output