diff --git a/about/index.html b/about/index.html index d11b8b7..544892e 100644 --- a/about/index.html +++ b/about/index.html @@ -252,6 +252,9 @@
Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/add_tensorflow_lite_to_ma35d1_yocto/index.html b/blog/add_tensorflow_lite_to_ma35d1_yocto/index.html index 285fa28..b8b8eee 100644 --- a/blog/add_tensorflow_lite_to_ma35d1_yocto/index.html +++ b/blog/add_tensorflow_lite_to_ma35d1_yocto/index.html @@ -171,7 +171,12 @@

    直接找到他把它關掉

    blog圖片的連結

    -
    Tensorflow-Lite 加入成功
    +
    EXTRA_OECMAKE = "\
    +    -DTFLITE_ENABLE_XNNPACK=off \
    +    -DTFLITE_ENABLE_RUY=on \
    +    -DTFLITE_ENABLE_GPU=off \
    +    ${S}/tensorflow/lite/ \
    +
    Tensorflow-Lite 加入成功

    blog圖片的連結

    加入 VNC 相關的 Library

    下面這幾個library 是跟tigervnc相關:

    @@ -296,6 +301,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/btn/index.html b/blog/btn/index.html index 21ef597..978ab9a 100644 --- a/blog/btn/index.html +++ b/blog/btn/index.html @@ -499,6 +499,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/debug_enable_semihost/index.html b/blog/debug_enable_semihost/index.html index aec96a0..4b31edd 100644 --- a/blog/debug_enable_semihost/index.html +++ b/blog/debug_enable_semihost/index.html @@ -212,6 +212,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/error_flash_download_failed_cortex-m0/index.html b/blog/error_flash_download_failed_cortex-m0/index.html index f6f2d79..f7e3d06 100644 --- a/blog/error_flash_download_failed_cortex-m0/index.html +++ b/blog/error_flash_download_failed_cortex-m0/index.html @@ -213,6 +213,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/gpio_introduce/index.html b/blog/gpio_introduce/index.html index 700999a..b4b3248 100644 --- a/blog/gpio_introduce/index.html +++ b/blog/gpio_introduce/index.html @@ -630,6 +630,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/i2c_bh1750/index.html b/blog/i2c_bh1750/index.html index 7c09d83..57cb92a 100644 --- a/blog/i2c_bh1750/index.html +++ b/blog/i2c_bh1750/index.html @@ -383,6 +383,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/icp_introduce/index.html b/blog/icp_introduce/index.html index 41b8db8..593195c 100644 --- a/blog/icp_introduce/index.html +++ b/blog/icp_introduce/index.html @@ -229,6 +229,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/index.html b/blog/index.html index d7feb87..1105c49 100644 --- a/blog/index.html +++ b/blog/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,23 +193,23 @@

    Social

    - 將Tensorflow Lite Library加到MA35D1的Yocto中 + MA35D1 Control
    安裝步驟文件 - 將Tensorflow Lite Library加到MA35D1的Yocto中 + MA35D1 Control -

    this is meta description

    - read more +

    在做Machine Learning 專案的時候,image Classfication的輸送帶要用PWM控制物件的 SG90 伺服馬達

    + read more
    @@ -214,23 +217,23 @@

    Social

    - MA35D1 extra package in Yocto project after the image is built + M460 Level0 說明
    - 說明文件 + 心得 - MA35D1 extra package in Yocto project after the image is built + M460 Level0 說明 -

    How to build an extra package in MA35D1 Yocto project after the image is built?

    - read more +

    this is meta description

    + read more
    @@ -238,23 +241,23 @@

    Social

    - MA35D1 devmem2 Read / Write memory address + 將Tensorflow Lite Library加到MA35D1的Yocto中
    - 說明文件 + 安裝步驟文件 - MA35D1 devmem2 Read / Write memory address + 將Tensorflow Lite Library加到MA35D1的Yocto中 -

    MA35D1 可以選用 devmem2 Tool 觀測或寫入記憶體狀況

    - read more +

    this is meta description

    + read more
    @@ -262,23 +265,23 @@

    Social

    - MA35D1 開機啟動位置 + MA35D1 extra package in Yocto project after the image is built
    說明文件 - MA35D1 開機啟動位置 + MA35D1 extra package in Yocto project after the image is built -

    MA35D1 開機啟動後執行的位置

    - read more +

    How to build an extra package in MA35D1 Yocto project after the image is built?

    + read more
    @@ -286,23 +289,23 @@

    Social

    - MA35D1 IoT 的 SPI 介面使用 + MA35D1 devmem2 Read / Write memory address
    說明文件 - MA35D1 IoT 的 SPI 介面使用 + MA35D1 devmem2 Read / Write memory address -

    MA35D1 當 Master , Sensor Module 當 Slave

    - read more +

    MA35D1 可以選用 devmem2 Tool 觀測或寫入記憶體狀況

    + read more
    @@ -310,23 +313,23 @@

    Social

    - 解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法 + MA35D1 開機啟動位置
    說明文件 - 解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法 + MA35D1 開機啟動位置 -

    M4 只有128KB 去存取資料是不夠的,一定會想用到DDR

    - read more +

    MA35D1 開機啟動後執行的位置

    + read more
    @@ -416,6 +419,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/index.xml b/blog/index.xml index 2f225aa..50e435f 100644 --- a/blog/index.xml +++ b/blog/index.xml @@ -6,7 +6,26 @@ Recent content in Blogs on 暐宗's Blog Hugo -- gohugo.io zh-tw - Fri, 03 Feb 2023 23:24:00 +0800 + Mon, 05 Jun 2023 23:24:00 +0800 + + MA35D1 Control + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + Mon, 05 Jun 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + 要找MA35D1的兩根pin腳給PWM 新唐定義 PG1 PG2 的地方 設定 device tree Kernel configuration settin + + + + M460 Level0 說明 + https://weizongchen.github.io/blog/m460_level0/ + Thu, 25 May 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/m460_level0/ + 控制 LED 0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他 +uint32_t* ptr_mode; ptr_mode = (uint32_t*)(0x40004000 + 0x1c0); *ptr_mode = 0x00000100; uint32_t* ptr_value; ptr_value = (uint32_t*)(0x40004000 + 0x1c8); *ptr_value = 0xFFFFFFEF; 負源觸發 補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示: + + 將Tensorflow Lite Library加到MA35D1的Yocto中 https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/ @@ -254,5 +273,14 @@ Clock, LDO control Rigister, PDBIASEN 這個 bit 系統環境 Windows 10 VS 2019 OpenCV 4.5.5 選擇 Windows 版本的OpenCV download下來 解壓縮到指定資料夾 可以在C 根目錄建一個 OpenCV 資料夾,在OpenCV資料夾下再建一個OpenCV4. + + + https://weizongchen.github.io/blog/m460-level0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://weizongchen.github.io/blog/m460-level0/ + + + diff --git a/blog/install_and_update_pinconfigure/index.html b/blog/install_and_update_pinconfigure/index.html index 8925fdf..8b8346a 100644 --- a/blog/install_and_update_pinconfigure/index.html +++ b/blog/install_and_update_pinconfigure/index.html @@ -218,6 +218,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/keil_debug_memoryupdate/index.html b/blog/keil_debug_memoryupdate/index.html index 1e611f5..0a49b32 100644 --- a/blog/keil_debug_memoryupdate/index.html +++ b/blog/keil_debug_memoryupdate/index.html @@ -219,6 +219,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/keil_ide_licence/index.html b/blog/keil_ide_licence/index.html index b22ca3d..75f8c2b 100644 --- a/blog/keil_ide_licence/index.html +++ b/blog/keil_ide_licence/index.html @@ -219,6 +219,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/keil_import_pack/index.html b/blog/keil_import_pack/index.html index 7017a82..4047c88 100644 --- a/blog/keil_import_pack/index.html +++ b/blog/keil_import_pack/index.html @@ -238,6 +238,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/m460-level0/index.html b/blog/m460-level0/index.html new file mode 100644 index 0000000..a5f4877 --- /dev/null +++ b/blog/m460-level0/index.html @@ -0,0 +1,296 @@ + + + + 暐宗's Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + +
    +
    +
    +
    + +

    + + +
    + +
    + + +
    + + +comments powered by Disqus +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/m460_level0/index.html b/blog/m460_level0/index.html new file mode 100644 index 0000000..25d2d40 --- /dev/null +++ b/blog/m460_level0/index.html @@ -0,0 +1,363 @@ + + + + 暐宗's Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + +
    +
    +
    +
    + + 心得 + +

    M460 Level0 說明

    + + + M460 Level0 說明 + +
    +

    blog圖片的連結 +blog圖片的連結

    +

    控制 LED

    +

    0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他

    +
    	uint32_t* ptr_mode;
    +
    +	ptr_mode = (uint32_t*)(0x40004000 + 0x1c0);
    +
    +	*ptr_mode = 0x00000100;
    +
    +

    blog圖片的連結

    +
    	uint32_t* ptr_value;
    +	ptr_value = (uint32_t*)(0x40004000 + 0x1c8);
    +	*ptr_value = 0xFFFFFFEF; 負源觸發
    +
    +

    blog圖片的連結

    +

    補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示:

    +

    blog圖片的連結

    +

    所以新唐寫法

    +
    	uint32_t* ptr_mode;
    +	ptr_mode = (uint32_t*)(0x40004000 + 0x1c0);
    +	*ptr_mode = 0x00000100;
    +
    +	uint32_t* ptr_value;
    +	ptr_value = (uint32_t*)(0x40004000 + 0x1c8);
    +	*ptr_value = 0xFFFFFFEF;
    +//----------------和下面寫法一樣-----------------------------------
    +	GPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);
    +	GPIO_SetMode(PH, BIT5, GPIO_MODE_OUTPUT);
    +	GPIO_SetMode(PH, BIT6, GPIO_MODE_OUTPUT);
    +
    +	LED_YELLOW = 0;//PH5
    +	LED_RED = 1;   //PH4
    +	LED_GREEN = 0; //PH6
    +
    +

    blog圖片的連結

    +

    blog圖片的連結 +blog圖片的連結

    +

    控制 BTN

    +

    先用 Keil 的Tool 看一下 按下Button 的狀態

    +

    blog圖片的連結

    +
    GPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);
    +GPIO_SetMode(PH, BIT5, GPIO_MODE_OUTPUT);
    +GPIO_SetMode(PH, BIT6, GPIO_MODE_OUTPUT);
    +
    +LED_YELLOW = 1;//PH5
    +LED_RED = 1;   //PH4
    +LED_GREEN = 1; //PH6
    +
    +GPIO_SetMode(PH, BIT0, GPIO_MODE_INPUT);
    +
    +/* Got no where to go, just loop forever */
    +while(1) {
    +
    +			if(PH0 == 0){
    +				LED_RED = 0;   //PH4
    +			}
    +			if(PH0 == 1){
    +				LED_RED = 1;   //PH4
    +			}
    +}
    +
    + +
    + + +
    + + +comments powered by Disqus +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/m4_fmc/index.html b/blog/m4_fmc/index.html index 525323b..c74ea7f 100644 --- a/blog/m4_fmc/index.html +++ b/blog/m4_fmc/index.html @@ -222,6 +222,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_devmem2/index.html b/blog/ma35d1_devmem2/index.html index 5a7a8d3..79337e6 100644 --- a/blog/ma35d1_devmem2/index.html +++ b/blog/ma35d1_devmem2/index.html @@ -216,6 +216,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_extra_package_yocto/index.html b/blog/ma35d1_extra_package_yocto/index.html index 4bd2c3a..e0fcff0 100644 --- a/blog/ma35d1_extra_package_yocto/index.html +++ b/blog/ma35d1_extra_package_yocto/index.html @@ -242,6 +242,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_install_method/index.html b/blog/ma35d1_install_method/index.html index a6cafc8..33f80be 100644 --- a/blog/ma35d1_install_method/index.html +++ b/blog/ma35d1_install_method/index.html @@ -302,6 +302,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_pwm_control/index.html b/blog/ma35d1_pwm_control/index.html new file mode 100644 index 0000000..6468994 --- /dev/null +++ b/blog/ma35d1_pwm_control/index.html @@ -0,0 +1,705 @@ + + + + 暐宗's Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + +
    +
    +
    +
    + + 安裝步驟文件 + +

    MA35D1 Control

    + + + MA35D1 Control + +
    +

    要找MA35D1的兩根pin腳給PWM

    +

    blog圖片的連結

    +

    新唐定義 PG1 PG2 的地方

    +

    blog圖片的連結

    +

    設定 device tree

    +

    Kernel configuration settin

    +
    /* 1. Add node in device tree root's configuration */
    +/ {
    +	model = "Nuvoton MA35D1-SOM";
    +        ………
    +        gpio_pwm {
    +		compatible = "gpio-pwm";
    +		status = "okay";
    +		pinctrl-names = "default";
    +		pinctrl-0 = <&pinctrl_gpio_pwm>;
    +		gpios = <&gpiog 1 GPIO_ACTIVE_LOW>,
    +		        <&gpiog 2 GPIO_ACTIVE_LOW>;       
    +        };
    +        ………
    +};
    +
    +/* 2. Add module pin configuration to device tree's pinctl as below */
    +&pinctrl {
    +	………
    +	gpio_pwm {
    +		pinctrl_gpio_pwm: gpio_pwmgrp{
    +			nuvoton,pins =
    +			<SYS_GPG_MFPL_PG1MFP_GPIO &pcfg_default>,
    +			<SYS_GPG_MFPL_PG2MFP_GPIO &pcfg_default>;
    +		};		
    +	};
    +………
    +

    gpio-pwm 的Driver

    +

    gpio-pwm.c

    +
    #include <linux/module.h>
    +#include <linux/kernel.h>
    +#include <linux/init.h>
    +#include <linux/slab.h>
    +#include <linux/timer.h>
    +#include <linux/sched.h>
    +#include <linux/reboot.h>
    +#include <linux/pwm.h>
    +#include <linux/gpio.h>
    +#include <linux/hrtimer.h>
    +#include <linux/platform_device.h>
    +#include <linux/of.h>
    +#include <linux/of_platform.h>
    +#include <linux/of_gpio.h>
    +
    +#include "gpio_pwm.h"
    +
    +#define GPIO_STATE_DEFAULT         0
    +
    +struct gpio_pwm_driver_data {
    +	unsigned int gpio;
    +	bool gpio_state;
    +	struct pwm_device *pwm_dev;
    +	bool pwm_enable;
    +	bool pwm_requset; 
    +	struct hrtimer timer;
    +	struct mutex lock;
    +};
    +
    +struct gpio_pwm_chip {
    +	struct pwm_chip chip;
    +	int gpio_nums;
    +	struct gpio_pwm_driver_data gpio_pwm_drv_data[];
    +};
    +
    +static enum hrtimer_restart gpio_pwm_timer_fun(struct hrtimer *data)
    +{
    +	int gpio_pwm_hi_time = 0;
    +	int gpio_pwm_lo_time = 0;
    +	int gpio_keep_time = 0;
    +
    +	struct gpio_pwm_driver_data *gpio_pwm_drv = container_of(data, struct gpio_pwm_driver_data, timer);
    +	struct pwm_device *pwm_dev = gpio_pwm_drv->pwm_dev;
    +
    +	gpio_pwm_hi_time = pwm_dev->state.duty_cycle;
    +	gpio_pwm_lo_time = pwm_dev->state.period - pwm_dev->state.duty_cycle;
    +
    +	if(gpio_pwm_drv->gpio_state == 0) {
    +		gpio_keep_time = gpio_pwm_hi_time;
    +	} else {
    +		gpio_keep_time = gpio_pwm_lo_time;
    +	}
    +
    +	gpio_pwm_drv->gpio_state ^= 0x01;
    +	gpio_set_value(gpio_pwm_drv->gpio, gpio_pwm_drv->gpio_state);
    +
    +	hrtimer_forward_now(&gpio_pwm_drv->timer, ns_to_ktime(gpio_keep_time));
    +
    +	return HRTIMER_RESTART;
    +}
    +
    +static int gpio_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
    +{
    +	struct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);
    +	struct gpio_pwm_driver_data *gpio_pwm_drv = &(pwm_chip_ptr->gpio_pwm_drv_data[pwm->hwpwm]);
    +	int ret = 0;
    +
    +	ret = gpio_request_one(gpio_pwm_drv->gpio, GPIOF_DIR_OUT, pwm->label);
    +	if (ret == 0) {
    +		gpio_pwm_drv->gpio_state = GPIO_STATE_DEFAULT;
    +		gpio_set_value(gpio_pwm_drv->gpio, gpio_pwm_drv->gpio_state);
    +		gpio_pwm_drv->pwm_requset = 1;
    +	}
    +
    +	return ret;
    +}
    +
    +static void gpio_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
    +{
    +	struct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);
    +	struct gpio_pwm_driver_data *gpio_pwm_drv = &(pwm_chip_ptr->gpio_pwm_drv_data[pwm->hwpwm]);
    +	int i;
    +
    +	mutex_lock(&gpio_pwm_drv->lock);
    +
    +	if(gpio_pwm_drv->pwm_enable) {
    +		hrtimer_cancel(&gpio_pwm_drv->timer);
    +		gpio_pwm_drv->pwm_enable = false;
    +	}
    +
    +	mutex_unlock(&gpio_pwm_drv->lock);
    +
    +	for(i=0; i < pwm_chip_ptr->gpio_nums; i++) {
    +		if (gpio_pwm_drv->pwm_requset == 1) {   
    +			gpio_free(gpio_pwm_drv->gpio);
    +		}
    +	}
    +}
    +
    +static int gpio_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
    +{
    +	struct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);
    +	struct gpio_pwm_driver_data *gpio_pwm_drv = &(pwm_chip_ptr->gpio_pwm_drv_data[pwm->hwpwm]);
    +
    +	mutex_lock(&gpio_pwm_drv->lock);
    +
    +	if(!gpio_pwm_drv->pwm_enable) {
    +		hrtimer_init(&gpio_pwm_drv->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
    +		gpio_pwm_drv->timer.function = gpio_pwm_timer_fun;
    +		gpio_pwm_drv->pwm_enable = true;
    +	}
    +
    +	mutex_unlock(&gpio_pwm_drv->lock);
    +	hrtimer_start(&gpio_pwm_drv->timer, ktime_add_ns(ktime_get(), pwm->state.duty_cycle), HRTIMER_MODE_ABS);
    +	return 0;
    +}
    +
    +static int gpio_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns)
    +{
    +	pwm->state.period = period_ns;
    +	pwm->state.duty_cycle = duty_ns;
    +	return 0;
    +}
    +
    +static void gpio_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
    +{
    +	struct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);
    +	struct gpio_pwm_driver_data * gpio_pwm_drv = &(pwm_chip_ptr->gpio_pwm_drv_data[pwm->hwpwm]);
    +
    +	mutex_lock(&gpio_pwm_drv->lock);
    +
    +	if(gpio_pwm_drv->pwm_enable) {
    +		hrtimer_cancel(&gpio_pwm_drv->timer);
    +		gpio_pwm_drv->pwm_enable = false;
    +	}
    +
    +	mutex_unlock(&gpio_pwm_drv->lock);
    +}
    +
    +static struct pwm_ops gpio_pwm_ops = {
    +	.request = gpio_pwm_request,
    +	.free = gpio_pwm_free,
    +	.enable = gpio_pwm_enable,
    +	.disable = gpio_pwm_disable,
    +	.config = gpio_pwm_config,
    +	.owner = THIS_MODULE,
    +};
    +
    +#ifdef CONFIG_OF
    +static const struct of_device_id of_gpio_pwm_match[] = {
    +	{ .compatible = "gpio-pwm", },
    +	{},
    +};
    +#endif
    +
    +static struct gpio_pwm_chip *gpio_pwmparse_dt(struct device *dev)
    +{
    +	const struct of_device_id *of_id = of_match_device(of_gpio_pwm_match, dev);
    +	struct device_node *np = dev->of_node;
    +	enum of_gpio_flags flags;
    +	struct gpio_pwm_chip *pwm_chip_ptr;
    +	int gpio_nums;
    +	int i;
    +	int err;
    +
    +	if (!of_id || !np)
    +		return NULL;
    +
    +	gpio_nums = of_gpio_count(np);
    +	if (!gpio_nums)           
    +		return ERR_PTR(-ENODEV);    
    +
    +	printk("gpio_nums = %d\n", gpio_nums);
    +
    +	pwm_chip_ptr = devm_kzalloc(dev, 
    +			sizeof(struct gpio_pwm_chip) + (gpio_nums * sizeof(struct gpio_pwm_driver_data)), GFP_KERNEL);
    +
    +	if (!pwm_chip_ptr)
    +		return ERR_PTR(-ENOMEM);
    +
    +	pwm_chip_ptr->gpio_nums = gpio_nums;
    +
    +	for(i = 0; i < gpio_nums; i++) {
    +		pwm_chip_ptr->gpio_pwm_drv_data[i].gpio = of_get_gpio_flags(np, i, &flags);
    +
    +		mutex_init(&(pwm_chip_ptr->gpio_pwm_drv_data[i].lock));
    +		pwm_chip_ptr->gpio_pwm_drv_data[i].pwm_enable = false;
    +
    +		printk("gpio=%d\n", pwm_chip_ptr->gpio_pwm_drv_data[i].gpio);
    +	}
    +
    +	err = of_property_read_u32(np, "base", &pwm_chip_ptr->chip.base);
    +	if (err)
    +		pwm_chip_ptr->chip.base = 0x20;
    +
    +	return pwm_chip_ptr;
    +}
    +
    +static int gpio_pwm_probe(struct platform_device *pdev)
    +{
    +	struct device *dev = &pdev->dev;
    +	struct gpio_pwm_platform_data *pdata = (struct gpio_pwm_platform_data *)dev_get_platdata(dev);
    +	struct gpio_pwm_chip *pwm_chip_ptr = NULL;
    +	int i = 0;
    +	int ret = 0;
    +
    +	if (!pdata) {
    +
    +		printk("probe dt\n");
    +
    +		pwm_chip_ptr = gpio_pwmparse_dt(dev);
    +		if (IS_ERR(pwm_chip_ptr))
    +			return PTR_ERR(pwm_chip_ptr);
    +
    +		if (!pwm_chip_ptr) {
    +			dev_err(dev, "pwm gpio missing platform data\n");
    +			return -EINVAL;
    +		}
    +	} else {
    +
    +		pwm_chip_ptr = devm_kzalloc(&pdev->dev, sizeof(struct gpio_pwm_chip) + (pdata->gpio_nums * sizeof(struct gpio_pwm_driver_data)), GFP_KERNEL);
    +
    +		if(pwm_chip_ptr == NULL)
    +			return -ENOMEM;
    +
    +		pwm_chip_ptr->gpio_nums = pdata->gpio_nums;
    +		for(i=0; i < pdata->gpio_nums; i++) {
    +			pwm_chip_ptr->gpio_pwm_drv_data[i].gpio = pdata->gpios[i];
    +			mutex_init(&(pwm_chip_ptr->gpio_pwm_drv_data[i].lock));
    +			pwm_chip_ptr->gpio_pwm_drv_data[i].pwm_enable = false;
    +
    +			printk("gpio-%d\n",pwm_chip_ptr->gpio_pwm_drv_data[i].gpio);
    +		}
    +		pwm_chip_ptr->chip.base = pdata->pwm_chip_idx;
    +
    +		printk("pwm_chip_idx=%d\n", pdata->pwm_chip_idx);
    +	}
    +
    +	pwm_chip_ptr->chip.npwm = pwm_chip_ptr->gpio_nums;
    +	pwm_chip_ptr->chip.ops = &gpio_pwm_ops;
    +	pwm_chip_ptr->chip.dev = &pdev->dev;
    +
    +#ifdef CONFIG_OF 
    +	pwm_chip_ptr->chip.dev->of_node = pdev->dev.of_node;
    +#endif
    +
    +	ret = pwmchip_add(&pwm_chip_ptr->chip);
    +	if(ret) {
    +		return ret;
    +	}
    +
    +	for(i = 0; i < pwm_chip_ptr->gpio_nums; i++) {
    +		pwm_chip_ptr->gpio_pwm_drv_data[i].pwm_dev = &pwm_chip_ptr->chip.pwms[i];
    +	}
    +
    +	platform_set_drvdata(pdev, pwm_chip_ptr);
    +
    +	return 0;
    +}
    +
    +static int gpio_pwm_remove(struct platform_device *pdev)
    +{
    +	struct gpio_pwm_chip *pwm_chip_ptr = platform_get_drvdata(pdev);
    +
    +	pwmchip_remove(&pwm_chip_ptr->chip);
    +	platform_set_drvdata(pdev, NULL);
    +
    +	return 0;
    +}
    +
    +static struct platform_driver gpio_pwm_driver = {
    +	.probe		= gpio_pwm_probe,
    +	.remove		= gpio_pwm_remove,
    +	.driver		= {
    +		.name	= "gpio-pwm",
    +		.owner	= THIS_MODULE,
    +		.of_match_table = of_match_ptr(of_gpio_pwm_match),
    +	},
    +};
    +
    +module_platform_driver(gpio_pwm_driver);
    +
    +MODULE_AUTHOR("nuvoton porting");
    +MODULE_DESCRIPTION("gpio pwm chip driver");
    +MODULE_LICENSE("GPL");
    +

    gpio-pwm.h

    +
    #ifndef __GPIO_PWM_H
    +#define __GPIO_PWM_H
    +
    +#include <linux/kernel.h>
    +#include <linux/init.h>
    +#include <linux/slab.h>
    +
    +struct gpio_pwm_platform_data {
    +	int pwm_chip_idx;
    +    	int gpio_nums;
    +	unsigned int *gpios;
    +};
    +
    +#endif
    +

    MakeFile to Build gpio-pwm.ko

    +

    下面要注意 :

    +
      +
    1. 在docker裡面 make
    2. +
    3. LINUX_DIR 要擺已經Build過的 kernel 位置
    4. +
    5. aarch64 tool chain 要有 : source /usr/local/oecore-x86_64/environment-setup-aarch64-poky-linux
    6. +
    +
    PWD := $(shell pwd)
    +
    +obj-m += gpio-pwm.o
    +
    +.PHONY: all clean
    +
    +COMPILE=aarch64-poky-linux-
    +
    +LINUX_DIR=../tmp-glibc/work/numaker_som_ma35d16a81-poky-linux/linux-ma35d1/5.10.140-r0/build
    +
    +all:
    +	make ARCH=arm64 CROSS_COMPILE=$(COMPILE) -C $(LINUX_DIR) M=$(PWD) modules
    +	
    +	
    +

    結構應該長得像下面的資料夾

    +

    blog圖片的連結

    +

    實體接線

    +

    blog圖片的連結 +blog圖片的連結

    +

    AP 層控制

    +

    GPIO PWM執行輸出與佔空比設定

    +

    Export PWM

    +
    echo 0 > /sys/class/pwm/pwmchip32/export
    +

    PWM 週期設定,單位為ns, gpioi12 輸出頻率為 100 HZ

    +
    echo 10000000 > /sys/class/pwm/pwmchip32/pwm0/period
    +

    PWM 佔空比設定, 以下設定佔空比為 0.5

    +
    echo 5000000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle
    +

    PWM 使能輸出

    +
    echo 1 >/sys/class/pwm/pwmchip32/pwm0/enable
    +
    echo 0 會 export ,這個時候,會出現pwm0的節點
    +
    echo 0 > /sys/class/pwm/pwmchip32/export
    +echo 20000000 > /sys/class/pwm/pwmchip32/pwm0/period
    +echo 1000000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle
    +echo 2000000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle
    +echo 1 >/sys/class/pwm/pwmchip32/pwm0/enable
    +
    PWM1 也是差不多的方式
    +

    echo 1 export ,這個時候會出現pwm1的節點

    +
    echo 1 > /sys/class/pwm/pwmchip32/export
    +echo 20000000 > /sys/class/pwm/pwmchip32/pwm1/period
    +echo 1000000 > /sys/class/pwm/pwmchip32/pwm1/duty_cycle
    +echo 2000000 > /sys/class/pwm/pwmchip32/pwm1/duty_cycle
    +echo 1 >/sys/class/pwm/pwmchip32/pwm1/enable
    +

    SG90 伺服馬達說明

    +

    小巧輕便且輸出功率高。伺服馬達可以大約旋轉180度(每個方向90度),並且與標準的伺服馬達一樣工作,只是體積更小。

    +

    您可以使用任何伺服馬達的程式碼、硬體或庫來控制這些伺服馬達。

    +

    對於初學者來說非常適合,他們想要讓東西移動,而不需要建立帶有反饋和齒輪箱的馬達控制器,尤其是因為它可以放在狹小的空間中。

    +

    位置 “0”(1.5 毫秒脈衝)代表中間位置。

    +

    位置 “90”(約 2 毫秒脈衝)代表向右極限。

    +

    位置 “-90”(約 1 毫秒脈衝)代表向左極限。

    +

    簡單來說,這段描述了 PWM 信號的位置與對應的角度之間的關係。位置 “0” 代表中間位置,位置 “90” 代表完全向右轉的極限,而位置 “-90” 則代表完全向左轉的極限。這些位置對應於 PWM 脈衝的持續時間,可以控制舵機或其他類似裝置的運動位置。

    +

    blog圖片的連結

    +

    注意

    +

    100 Hz 是 :

    +

    echo 10000000 > /sys/class/pwm/pwmchip32/pwm0/period

    +

    Datashet 要 50 Hz

    +

    要寫成以下才會是50 Hz:

    +
    echo 20000000 > /sys/class/pwm/pwmchip32/pwm0/period
    +

    1 ms 的duty 我要給以下:

    +

    echo 1000000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle

    +

    1.5 ms 的duty 我要給以下:

    +

    echo 1500000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle

    +

    2 ms 的duty 我要給以下:

    +

    echo 2000000 > /sys/class/pwm/pwmchip32/pwm0/duty_cycle

    + +
    + + +
    + + +comments powered by Disqus +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/ma35d1_rtp/index.html b/blog/ma35d1_rtp/index.html index 5cfcc8f..cf327db 100644 --- a/blog/ma35d1_rtp/index.html +++ b/blog/ma35d1_rtp/index.html @@ -261,6 +261,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_rtp_memory/index.html b/blog/ma35d1_rtp_memory/index.html index 8966253..d008afd 100644 --- a/blog/ma35d1_rtp_memory/index.html +++ b/blog/ma35d1_rtp_memory/index.html @@ -259,6 +259,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_spi/index.html b/blog/ma35d1_spi/index.html index 4df78ee..3a309d1 100644 --- a/blog/ma35d1_spi/index.html +++ b/blog/ma35d1_spi/index.html @@ -312,6 +312,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/ma35d1_startup_execute/index.html b/blog/ma35d1_startup_execute/index.html index ebbc84b..83eb70e 100644 --- a/blog/ma35d1_startup_execute/index.html +++ b/blog/ma35d1_startup_execute/index.html @@ -226,6 +226,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/opencv_env/index.html b/blog/opencv_env/index.html index 807a05f..7b1d416 100644 --- a/blog/opencv_env/index.html +++ b/blog/opencv_env/index.html @@ -283,6 +283,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/page/2/index.html b/blog/page/2/index.html index fab54e8..feb1ac0 100644 --- a/blog/page/2/index.html +++ b/blog/page/2/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,23 +193,23 @@

    Social

    @@ -214,23 +217,23 @@

    Social

    @@ -238,23 +241,23 @@

    Social

    @@ -262,23 +265,23 @@

    Social

    @@ -286,23 +289,23 @@

    Social

    @@ -310,23 +313,23 @@

    Social

    @@ -416,6 +419,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/page/3/index.html b/blog/page/3/index.html index c5df076..f8702d3 100644 --- a/blog/page/3/index.html +++ b/blog/page/3/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,23 +193,23 @@

    Social

    @@ -214,14 +217,14 @@

    Social

    @@ -238,23 +241,23 @@

    Social

    @@ -262,23 +265,23 @@

    Social

    @@ -286,23 +289,23 @@

    Social

    @@ -310,23 +313,23 @@

    Social

    @@ -416,6 +419,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/page/4/index.html b/blog/page/4/index.html index 50e7fd6..f807c27 100644 --- a/blog/page/4/index.html +++ b/blog/page/4/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,23 +193,23 @@

    Social

    @@ -214,23 +217,23 @@

    Social

    @@ -238,23 +241,23 @@

    Social

    @@ -262,23 +265,23 @@

    Social

    @@ -286,23 +289,23 @@

    Social

    @@ -310,23 +313,23 @@

    Social

    @@ -416,6 +419,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/page/5/index.html b/blog/page/5/index.html index b6befb6..a64e574 100644 --- a/blog/page/5/index.html +++ b/blog/page/5/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,6 +193,54 @@

    Social

    +
    + +
    + +
    + +
    +
    + OpenCV 環境安裝
    @@ -211,6 +262,25 @@

    Social

    +
    +
    + +
    + + + +

    + read more +
    +
    +
    + @@ -296,6 +366,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/pi3ldd/index.html b/blog/pi3ldd/index.html index e6766b7..760145e 100644 --- a/blog/pi3ldd/index.html +++ b/blog/pi3ldd/index.html @@ -245,6 +245,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/pwm/index.html b/blog/pwm/index.html index ba11c86..406bf7a 100644 --- a/blog/pwm/index.html +++ b/blog/pwm/index.html @@ -521,6 +521,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/question/index.html b/blog/question/index.html index 481d6af..b041c20 100644 --- a/blog/question/index.html +++ b/blog/question/index.html @@ -236,6 +236,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/timer_delay/index.html b/blog/timer_delay/index.html index 75c3cf6..0fba04c 100644 --- a/blog/timer_delay/index.html +++ b/blog/timer_delay/index.html @@ -458,6 +458,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/blog/timer_init_timer0_toggle/index.html b/blog/timer_init_timer0_toggle/index.html index 383f4d6..d11d826 100644 --- a/blog/timer_init_timer0_toggle/index.html +++ b/blog/timer_init_timer0_toggle/index.html @@ -345,6 +345,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/categories/index.html b/categories/index.html index 4e84fd5..c8338eb 100644 --- a/categories/index.html +++ b/categories/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -211,6 +214,25 @@

    Social

    + 心得 + +

    + read more +
    + + + +
    +
    + +
    + 說明文件
    +
    +
    + + +
    + +
    + +
    +
    + +
    @@ -242,7 +233,7 @@

    Social

    - 暐宗's Blog +
    @@ -267,8 +258,6 @@
    Contact Me
    Social Contacts
    diff --git "a/categories/\345\277\203\345\276\227/index.xml" "b/categories/\345\277\203\345\276\227/index.xml" index 0c30e5e..a76171a 100644 --- "a/categories/\345\277\203\345\276\227/index.xml" +++ "b/categories/\345\277\203\345\276\227/index.xml" @@ -6,17 +6,15 @@ Recent content in 心得 on 暐宗's Blog Hugo -- gohugo.io zh-tw - Mon, 06 Jun 2022 23:24:00 +0800 + Thu, 25 May 2023 23:24:00 +0800 - 文章的Markdwon 說明 - https://weizongchen.github.io/blog/test/ - Mon, 06 Jun 2022 23:24:00 +0800 + M460 Level0 說明 + https://weizongchen.github.io/blog/m460_level0/ + Thu, 25 May 2023 23:24:00 +0800 - https://weizongchen.github.io/blog/test/ - Hello World -我是暐宗 -一級標題 二級標題 五級標題 六級標題 我是暐宗,這裡是測試文章 -暐宗 有序序列 內縮 第三繩得有序序列內縮開頭 Hello test Hello printf(); World Hello 引用 通常放到文章最前面 https://github. + https://weizongchen.github.io/blog/m460_level0/ + 控制 LED 0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他 +uint32_t* ptr_mode; ptr_mode = (uint32_t*)(0x40004000 + 0x1c0); *ptr_mode = 0x00000100; uint32_t* ptr_value; ptr_value = (uint32_t*)(0x40004000 + 0x1c8); *ptr_value = 0xFFFFFFEF; 負源觸發 補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示: diff --git "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/index.html" "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/index.html" index a7d23ec..98b2abf 100644 --- "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/index.html" +++ "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/index.html" @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -413,6 +416,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/2/index.html" "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/2/index.html" index 92b64b4..edc8adf 100644 --- "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/2/index.html" +++ "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/2/index.html" @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -413,6 +416,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/3/index.html" "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/3/index.html" index 614925d..0658777 100644 --- "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/3/index.html" +++ "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/3/index.html" @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -413,6 +416,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/4/index.html" "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/4/index.html" index 2cedcca..4d9de55 100644 --- "a/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/4/index.html" +++ "b/categories/\350\252\252\346\230\216\346\226\207\344\273\266/page/4/index.html" @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -341,6 +344,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/contact/index.html b/contact/index.html index 159ac35..3f316b9 100644 --- a/contact/index.html +++ b/contact/index.html @@ -218,6 +218,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/images/M467HJ.png b/images/M467HJ.png new file mode 100644 index 0000000..cf3596f Binary files /dev/null and b/images/M467HJ.png differ diff --git a/images/M467HJ0.JPG b/images/M467HJ0.JPG new file mode 100644 index 0000000..2cd0651 Binary files /dev/null and b/images/M467HJ0.JPG differ diff --git a/images/M467HJ1.JPG b/images/M467HJ1.JPG new file mode 100644 index 0000000..173fb72 Binary files /dev/null and b/images/M467HJ1.JPG differ diff --git a/images/M467HJ2.JPG b/images/M467HJ2.JPG new file mode 100644 index 0000000..0137524 Binary files /dev/null and b/images/M467HJ2.JPG differ diff --git a/images/M467HJ2.png b/images/M467HJ2.png new file mode 100644 index 0000000..be4fc3e Binary files /dev/null and b/images/M467HJ2.png differ diff --git a/images/M467HJ3.JPG b/images/M467HJ3.JPG new file mode 100644 index 0000000..4db1527 Binary files /dev/null and b/images/M467HJ3.JPG differ diff --git a/images/M467HJ4.JPG b/images/M467HJ4.JPG new file mode 100644 index 0000000..78fe471 Binary files /dev/null and b/images/M467HJ4.JPG differ diff --git a/images/M467HJ5.JPG b/images/M467HJ5.JPG new file mode 100644 index 0000000..0617eef Binary files /dev/null and b/images/M467HJ5.JPG differ diff --git a/images/MA35D1_PWM1.jpg b/images/MA35D1_PWM1.jpg new file mode 100644 index 0000000..cb4fbfb Binary files /dev/null and b/images/MA35D1_PWM1.jpg differ diff --git a/images/MA35D1_PWM1.png b/images/MA35D1_PWM1.png new file mode 100644 index 0000000..a83bbac Binary files /dev/null and b/images/MA35D1_PWM1.png differ diff --git a/images/MA35D1_PWM2.png b/images/MA35D1_PWM2.png new file mode 100644 index 0000000..38cdc62 Binary files /dev/null and b/images/MA35D1_PWM2.png differ diff --git a/images/MA35D1_PWM3.png b/images/MA35D1_PWM3.png new file mode 100644 index 0000000..659d161 Binary files /dev/null and b/images/MA35D1_PWM3.png differ diff --git a/images/MA35D1_PWM4.jpg b/images/MA35D1_PWM4.jpg new file mode 100644 index 0000000..861437d Binary files /dev/null and b/images/MA35D1_PWM4.jpg differ diff --git a/images/MA35D1_PWM5.png b/images/MA35D1_PWM5.png new file mode 100644 index 0000000..9b02a0c Binary files /dev/null and b/images/MA35D1_PWM5.png differ diff --git a/images/MA35D1_PWM6.png b/images/MA35D1_PWM6.png new file mode 100644 index 0000000..21b2c20 Binary files /dev/null and b/images/MA35D1_PWM6.png differ diff --git a/images/post/MA35D1_PWM.jpg b/images/post/MA35D1_PWM.jpg new file mode 100644 index 0000000..950eb7a Binary files /dev/null and b/images/post/MA35D1_PWM.jpg differ diff --git a/images/post/NuMaker-M467HJ-V1F.png b/images/post/NuMaker-M467HJ-V1F.png new file mode 100644 index 0000000..a4b6b78 Binary files /dev/null and b/images/post/NuMaker-M467HJ-V1F.png differ diff --git a/index.html b/index.html index 732c54d..17b1e7b 100644 --- a/index.html +++ b/index.html @@ -146,6 +146,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -191,23 +194,23 @@

    Social

    @@ -215,23 +218,23 @@

    Social

    @@ -239,23 +242,23 @@

    Social

    @@ -263,23 +266,23 @@

    Social

    @@ -287,23 +290,23 @@

    Social

    @@ -311,23 +314,23 @@

    Social

    @@ -417,6 +420,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/index.json b/index.json index 934143e..bcb089d 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -[{"categories":["安裝步驟文件"],"contents":"yocto添加網路上現有的meta layer 查找菜譜 可以點下面連結去首頁\nOpenEmbedded Layer Index\n也可以直接點下面是 Tensorflow Lite 的資源\nmeta-neural-network\n如下圖,目前是tensorflow2.6.0版本( dunfell )\n找到Source Code 如下圖,點擊 web repo 會到Github的頁面\n目前是dunfell ,要改成dunfell的source Download Source Code 在 bitbake 裡面下以下指令去Download Code git clone -b dunfell https://github.com/nnstreamer/meta-neural-network.git 下載成功的畫面 裡面內容大概長成下面:\n在 bblayers.conf 加入 meta-neural-network 在 local.conf 加入 tensorflow-lite 編譯一次Image 編譯一次nvt-image-qt5的Image , bitbake -s | grep tensorflow-lite 就應該可以看到tensorflow lite 的 library 被加到Image 裡面。\n過程當中,Tensorflow lite 的資源裡面,會發現 XNNPACK 相關的 error 一直跑出來 Debug 後 , 發現要 -DTFLITE_ENABLE_XNNPACK=off , 把XNNPACK給off掉,如下圖所示\n直接找到他把它關掉 Tensorflow-Lite 加入成功 加入 VNC 相關的 Library 下面這幾個library 是跟tigervnc相關:\ngtk+3 、 tigervnc 、 xauth 、 xkbcomp 、 xsetroot 、 xterm 、 twm\nMACHINE ??= \u0026#39;numaker-som-ma35d16a81\u0026#39;\rDISTRO ?= \u0026#39;nvt-ma35d1-directfb\u0026#39;\rPACKAGE_CLASSES ?= \u0026#34;package_rpm\u0026#34;\rEXTRA_IMAGE_FEATURES ?= \u0026#34;debug-tweaks\u0026#34;\rUSER_CLASSES ?= \u0026#34;buildstats image-mklibs image-prelink\u0026#34;\rPATCHRESOLVE = \u0026#34;noop\u0026#34;\rBB_DISKMON_DIRS ??= \u0026#34;\\\rSTOPTASKS,${TMPDIR},1G,100K \\\rSTOPTASKS,${DL_DIR},1G,100K \\\rSTOPTASKS,${SSTATE_DIR},1G,100K \\\rSTOPTASKS,/tmp,100M,100K \\\rABORT,${TMPDIR},100M,1K \\\rABORT,${DL_DIR},100M,1K \\\rABORT,${SSTATE_DIR},100M,1K \\\rABORT,/tmp,10M,1K\u0026#34;\rPACKAGECONFIG_append_pn-qemu-system-native = \u0026#34; sdl\u0026#34;\rCONF_VERSION = \u0026#34;1\u0026#34;\rMACHINE_FEATURES_append = \u0026#34; optee \u0026#34;\rIMAGE_INSTALL_append += \u0026#34; opencv\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; tensorflow-lite\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; gtk+3\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; tigervnc\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xauth\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xkbcomp\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xsetroot\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xterm\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; twm\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; cmake\u0026#34;\rDL_DIR ?= \u0026#34;${BSPDIR}/downloads/\u0026#34; 編譯 nvt-image-qt5 的 Image 時候會看到 下面 x11 錯誤\n點開下面的 nvt-ma35d1-directfb.conf 檔案,加入x11 的內容就可以了\n路徑:\r/home/nuvoton/yocto/sources/meta-ma35d1/conf/distro\r# Nuvoton DISTRO for the FrameBuffer graphical backend.\rinclude conf/distro/include/nvt-base.inc\rDISTRO = \u0026#34;nvt-ma35d1-directfb\u0026#34;\r# Remove conflicting backends.\rDISTRO_FEATURES_append += \u0026#34; \u0026#34;\rDISTRO_FEATURES_append += \u0026#34; x11 \u0026#34; 再 bitbake nvt-image-qt5 一次,就可以全部都加進去\n","permalink":"https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/","tags":["Ma35d1"],"title":" 將Tensorflow Lite Library加到MA35D1的Yocto中 "},{"categories":["說明文件"],"contents":"Open local.conf nuvoton@84d536ecc45d:~/shared/yocto/build$ vim conf/local.conf For example : add pip3 and devmem2 CORE_IMAGE_EXTRA_INSTALL += \u0026ldquo;devmem2\u0026rdquo;\nIMAGE_INSTALL_append += \u0026quot; python3-pip\u0026quot;\nMACHINE ??= \u0026#39;numaker-iot-ma35d16f90\u0026#39;\rDISTRO ?= \u0026#39;nvt-ma35d1-directfb\u0026#39;\rPACKAGE_CLASSES ?= \u0026#34;package_rpm\u0026#34;\rEXTRA_IMAGE_FEATURES ?= \u0026#34;debug-tweaks\u0026#34;\rUSER_CLASSES ?= \u0026#34;buildstats image-mklibs image-prelink\u0026#34;\rPATCHRESOLVE = \u0026#34;noop\u0026#34;\rBB_DISKMON_DIRS ??= \u0026#34;\\\rSTOPTASKS,${TMPDIR},1G,100K \\\rSTOPTASKS,${DL_DIR},1G,100K \\\rSTOPTASKS,${SSTATE_DIR},1G,100K \\\rSTOPTASKS,/tmp,100M,100K \\\rABORT,${TMPDIR},100M,1K \\\rABORT,${DL_DIR},100M,1K \\\rABORT,${SSTATE_DIR},100M,1K \\\rABORT,/tmp,10M,1K\u0026#34;\rPACKAGECONFIG_append_pn-qemu-system-native = \u0026#34; sdl\u0026#34;\rCONF_VERSION = \u0026#34;1\u0026#34;\rMACHINE_FEATURES_append = \u0026#34; optee\u0026#34;\rCORE_IMAGE_EXTRA_INSTALL += \u0026#34;devmem2\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; python3-pip\u0026#34;\rDL_DIR ?= \u0026#34;${BSPDIR}/downloads/\u0026#34; Search package nuvoton@84d536ecc45d:~/shared/yocto/build$ bitbake -s | grep pip\nlibpipeline :1.5.2-r0 nativesdk-python3-pip :20.0.2-r0 pipewire :0.3.1-r0 pipewire-0.2 :0.2.7-r0 python3-pip :20.0.2-r0 python3-pip-native :20.0.2-r0 ","permalink":"https://weizongchen.github.io/blog/ma35d1_extra_package_yocto/","tags":["MA35D1"],"title":"MA35D1 extra package in Yocto project after the image is built"},{"categories":["說明文件"],"contents":"devmem2 Tool read register devmem2 0x40600014 TRM SPI Status Register (SPIx_STATUS) write 32bit to register devmem2 0x40600014 w 0x0058112 ","permalink":"https://weizongchen.github.io/blog/ma35d1_devmem2/","tags":["MA35D1"],"title":"MA35D1 devmem2 Read / Write memory address"},{"categories":["說明文件"],"contents":"MA35D1 QT startup path vi /etc/profile.d/qt5-env.sh You can write that you want to auto execute command or script here. Here, I setup a IP and a gpio driver when startup the A35. #define a new path for the font in qt5\rexport QT_QPA_FONTDIR=/usr/share/fonts/truetype\rexport XDG_RUNTIME_DIR=\u0026#34;/tmp/runtime-root\u0026#34;\rexport QT_QPA_PLATFORM=\u0026#34;linuxfb\u0026#34;\rexport QT_QPA_FB_TSLIB=1\rexport TSLIB_CONSOLEDEVICE=none\rifconfig eth1 192.168.11.6 netmask 255.255.255.0\rinsmod ~/gpio-capture.ko SCP a file test sudo scp spidev_test3 root@192.168.11.6:/home/root/\n","permalink":"https://weizongchen.github.io/blog/ma35d1_startup_execute/","tags":["MA35D1"],"title":"MA35D1 開機啟動位置"},{"categories":["說明文件"],"contents":"MA35D1 SPI Device Tree 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi\nspi0: spi@40600000 {\rcompatible = \u0026#34;nuvoton,ma35d1-spi\u0026#34;;\rreg = \u0026lt;0x0 0x40600000 0x0 0x10000\u0026gt;;\rinterrupts = \u0026lt;GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH\u0026gt;;\rclocks = \u0026lt;\u0026amp;clk SPI0_GATE\u0026gt;;\rdmas = \u0026lt;\u0026amp;pdma1 4\u0026gt;,\u0026lt;\u0026amp;pdma1 5\u0026gt;;\rdma-names = \u0026#34;tx\u0026#34;,\u0026#34;rx\u0026#34;;\rpdma_reqsel_tx = \u0026lt;60\u0026gt;;\rpdma_reqsel_rx = \u0026lt;61\u0026gt;;\ruse_pdma = \u0026lt;0\u0026gt;;\rnum_cs = \u0026lt;2\u0026gt;;\rlsb = \u0026lt;0\u0026gt;;\rsleep = \u0026lt;0\u0026gt;;\rtxbitlen = \u0026lt;8\u0026gt;;\rbus_num = \u0026lt;2\u0026gt;;\rspimode = \u0026lt;0\u0026gt;;\rmrxphase = \u0026lt;0\u0026gt;;\rspi-max-frequency = \u0026lt;10000000\u0026gt;;\rstatus = \u0026#34;disabled\u0026#34;;\r}; 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts\nCS = PG0\nCLK = PB9\nMOSI = PL14\nMISO =PL15\n使用PDMA 所以下面給1\n速度最高給12M (後面會蓋掉前面設定!)\n\u0026amp;spi0 {\rstatus = \u0026#34;okay\u0026#34;;\rpinctrl-names = \u0026#34;default\u0026#34;;\ruse_pdma = \u0026lt;1\u0026gt;;\rspi-max-frequency = \u0026lt;30000000\u0026gt;;\rpinctrl-0 = \u0026lt;\u0026amp;pinctrl_spi0\u0026gt;;\rspidev@0 {\rcompatible = \u0026#34;spidev\u0026#34;;\rreg = \u0026lt;0\u0026gt;;\rspi-max-frequency = \u0026lt;12000000\u0026gt;;\r};\r};\r\u0026amp;pinctrl {\rspi0 {\rpinctrl_spi0: spi0grp{\rnuvoton,pins =\r\u0026lt;SYS_GPG_MFPL_PG0MFP_SPI0_SS0 \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPB_MFPH_PB8MFP_SPI0_SS1 \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPB_MFPH_PB9MFP_SPI0_CLK \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPL_MFPH_PL14MFP_SPI0_MOSI \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPL_MFPH_PL15MFP_SPI0_MISO \u0026amp;pcfg_default\u0026gt;;\r};\r};\r}; 電路圖 Linux Driver: 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/drivers/spi\nstatic int nuvoton_spi_data_xfer(struct nuvoton_spi *hw, const void *txbuf,\rvoid *rxbuf, unsigned int len)\r{\r...\r} Linux Application: 環境上預設並沒有開啟spidev (decice node for user)須經由以下流程開啟: APP: 採用NUC980的 app https://github.com/OpenNuvoton/NUC980_Linux_Applications/blob/master/demos/spi/spidev_test.c\nAPP Makefile .SUFFIXES : .x .o .c .s\rSTRIP := aarch64-poky-linux-strip\r#TARGET = spidev_test\r#SRCS := spidev_test.c\rall:\r#\t$(CC) $(SRCS) -o $(TARGET) clean:\rrm -f *.o\rrm -f *.x\rrm -f *.flat\rrm -f *.map\rrm -f temp\rrm -f *.img\rrm -f $(TARGET)\rrm -f *.gdb Application 執行結果 ","permalink":"https://weizongchen.github.io/blog/ma35d1_spi/","tags":["MA35D1"],"title":"MA35D1 IoT 的 SPI 介面使用"},{"categories":["說明文件"],"contents":"跟新唐過去Cortex® M4 的 Feature 不一樣的地方 M4 speed 調升至 180 MHz 本章的重點,SRAM 有 128KB 以及 可以控制DDR 384KB Support Peripheral 1. UART、I2C、I2S、PDMA、SPI、etc… NuLink2Me Debug Wormhole Linux Setup Device Tree 查看各個 memory 設定 這裡是設定 Memory 的起始位置 8000 0000\n注意 Reserved-memory :\n在這裡,我們為不同的功能保留了三個塊。 其中一個地方是 rproc 函數,它用在 M4 DRAM 上(384KB)\n(0x60000 = 384 KB)\nDevice Tree 設定 以設定UART16 為例\n_S 就是代表指定給A35\n_SUBM 代表指定給M4\nCompile and make Image Compile the Linux kernel.\r$ bitbake linux-ma35d1 -C compile\rCompile the TF-A.\r$ bitbake tf-a-ma35d1 -C compile\rBuild-up Image.\r$ bitbake nvt-image-qt5 –c cleanall \u0026amp;\u0026amp; bitbake nvt-image-qt5\rBurn-in Image into SD card.\r$ sudo dd if=core-image-minimal-xxxxx.rootfs.sdcard of=/dev/sdbx 在 Keil IDE 設定 memory 使用空間 上圖中我們可以看到,RO data 配置位置在 0x0 ~ 0x1FFFF ,一共有128KB SRAM\nRW data 配置位置在 0x80040000 大小為0x1FFFF ,一共有128KB 的DDR\n我寫一個 c code 在 DDR memory 使用空間 在 .c 的右鍵 option ,可以指定要把這個 function 放到 DDR 去\n在 map file 中可以看到 memtest 已經在DDR 的 使用空間了\n使用 scatter file 去直接指定 哪個 上圖可以看到 紅色 是代表記憶體區間\n0x00000000 ~ 0x0001FFFF 是SRAM 的空間\n這裡的寫法可以直接打開 map file ,copy paste 一模一樣的名子就可以了,\n例如 : startup_ma35d1_rtp.o(STACK, HEAP) 這個我放到SRAM\npdm_converter.o(.bss) 我放到DRAM\n以此類推\n所以上圖可以知道,我把需要比較快速算完的data 放到SRAM\n比較不需要速度的資料我放到 DRAM\n","permalink":"https://weizongchen.github.io/blog/ma35d1_rtp_memory/","tags":["Cortex M4","MA35D1"],"title":"解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法"},{"categories":["說明文件"],"contents":"PC 接好onboard的 nulink2 然後設定 Keil 的 option 這邊可以看到上圖我們開啟了412KB 的 flash 要使用\n在程式的部分,我open 一個 fmc\n寫一個pattern : 0x5A5A5A5A\n然後下面有兩個API可以參考(FMC_Write 、 FMC_Read),其他可以去看新唐的fmc.c 參考。\n可以看到,我們用ICP查詢片上的flash 有0x5A5A5A5A 的資料被寫入\nFMC_Erase(u32Addr) 一次會Erase 4096 個 byte uTemp 一次要寫入 4 byte 的資料\nelse if( (i*4) == 4096)\n因為一次會寫入4 byte,所以當i=1024時,寫買了需要Erase新的4096 byte 空間\n","permalink":"https://weizongchen.github.io/blog/m4_fmc/","tags":["Cortex M4"],"title":"M4 把資料寫進 FMC的方法"},{"categories":["說明文件"],"contents":"Raspberry pi 3 Linux Device Driver\n下載上課用Raspberry Pi image檔 (Linux 核心 4.14.x )(已包含上課用的範例程式 最新版本請再次下載)\nRaspberry Pi image\n範例程式\n登入帳號 派 密碼: 樹莓派\n程式目錄結構\ncd /home/pi/LinuxDriver_Data_20191001\n├── Code\n├── 01_LED\r├── 02_BTN_LED\r├── ....\r├── driver-example\r├── hello\r├── image_Readme.txt \u0026lt;== 請參考此檔案說明\n└── Sch\u0026amp;DataSheet\n說明\n1.範例程式碼是基於Linux 核心 4.14.x 版本。提醒: 來自核心所提供的Driver Code, 大部份都位於 linux-raspberrypi-kernel_1.20190401-1/drivers/bcma , 例如 driver_gpio.c (舊版是 arch/mach-bcm2708/bcm2708_gpio.c )\n2.講師講解內容不限於Raspberry Pi 開發套件包,惟能實際硬體實驗的部份會受限於Raspberry Pi 開發套件包所提供的硬體。 Raspberry Pi 開發套件包\n3.Linux Driver 學習須知\n如何執行第一個LED範例\n如何使用make menuconfig\nPi 新手教學(零) \u0026ndash;艾鍗Raspberry Pi I/O Shield 規格介紹: https://goo.gl/eg1JMh\nPi 新手教學(一) \u0026ndash; 使用Wind32 Disk Imager 燒錄卬象檔: https://goo.gl/bsxy66\nPi 新手教學(二) \u0026ndash;如何使用UART Console 登入Raspberry Pi: https://goo.gl/ffJ6aP\nPi 新手教學(三) \u0026ndash;使用SSH登入Raspberry Pi: https://goo.gl/KPGco1\n下載Pi子卡Datasheet及電路圖: https://goo.gl/FoDXM1\n","permalink":"https://weizongchen.github.io/blog/pi3ldd/","tags":["Cortex A"],"title":"pi3ldd"},{"categories":["說明文件"],"contents":"\n原因是這裡可能空白 至少要選一個\n","permalink":"https://weizongchen.github.io/blog/error_flash_download_failed_cortex-m0/","tags":["Tool"],"title":"Error:Flash Download failed - Cortex-M0"},{"categories":["說明文件"],"contents":"開啟 Option Define 好 DEBUG_ENABLE_SEMIHOST 在 Debug Mode 的時候打開 UART #1 可以看到 UART0 的輸出 ","permalink":"https://weizongchen.github.io/blog/debug_enable_semihost/","tags":["Tool"],"title":"SemiHost 使用方法"},{"categories":["說明文件"],"contents":"找M460開發版的2根空的 I2C 由上圖可以知道 I2C Pin角選\nPA5 SCL 板上 PIN75\nPA4 SDA 板上 PIN76\nBSP 包 直接用 I2C_MultiBytes_Master /* Slave address */\ng_u8DeviceAddr = 0x46;\nBH1750的 ID 是 0x46 (包含第8個 bit)\nI2C_WriteByte(I2C0, device ID (不包含第8個bit), 要傳的命令)\nI2C_WriteByte(I2C0, 0x23, 0x10);\n這裡命令 0x10 是參考下圖\n//I2C_ReadByte(I2C0, device ID (不包含第8個bit));\n//r = I2C_ReadByte(I2C0, 0x23);\n讀到幾個byte = I2C_ReadMultiBytes(I2C0, device ID 不包含第8個bit, 放個陣列ReadData 會存到回到ReadData, 讀取長度len = 2 )\nreceive_byte = I2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\nLA 量測結果 我MCU發送 0x46 (第8bit 值0 方向 write) ID ,並給值 0x10 給 Device\n0x46+1 (第8bit 值1 方向 read)Device 回 MCU 2個值 : 0x00 0xC5\n實體接線 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief\r* Show how to set I2C use Multi bytes API Read and Write data to Slave.\r* Needs to work with I2C_Slave sample code.\r* @copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r*****************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define PLL_CLOCK 192000000\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rvolatile uint8_t g_u8DeviceAddr;\rvolatile uint8_t g_au8MstTxData[3];\rvolatile uint8_t g_u8MstRxData;\rvolatile uint8_t g_u8MstDataLen;\rvolatile uint8_t g_u8MstEndFlag = 0;\rtypedef void (*I2C_FUNC)(uint32_t u32Status);\rvolatile static I2C_FUNC s_I2C0HandlerFn = NULL;\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/* Enable I2C0 peripheral clock */\rCLK_EnableModuleClock(I2C0_MODULE);\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();;\r/* Set I2C0 multi-function pins */\rSET_I2C0_SDA_PA4();\rSET_I2C0_SCL_PA5();\r/* I2C pin enable schmitt trigger */\rPA-\u0026gt;SMTEN |= GPIO_SMTEN_SMTEN4_Msk | GPIO_SMTEN_SMTEN5_Msk;\r}\rvoid I2C0_Init(void)\r{\r/* Open I2C module and set bus clock */\rI2C_Open(I2C0, 100000);\r/* Get I2C0 Bus Clock */\rprintf(\u0026#34;I2C clock %d Hz\\n\u0026#34;, I2C_GetBusClockFreq(I2C0));\r}\rvoid I2C0_Close(void)\r{\r/* Disable I2C0 interrupt and clear corresponding NVIC bit */\rI2C_DisableInt(I2C0);\rNVIC_DisableIRQ(I2C0_IRQn);\r/* Disable I2C0 and close I2C0 clock */\rI2C_Close(I2C0);\rCLK_DisableModuleClock(I2C0_MODULE);\r}\rint32_t main(void)\r{\ruint32_t receive_byte;\ruint8_t ReadData[2];\ruint32_t Lux;\ruint32_t i;\ruint8_t txbuf[256] = {0}, rDataBuf[256] = {0};\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, IP clock and multi-function I/O. */\rSYS_Init();\r/* Configure UART0: 115200, 8-bit word, no parity bit, 1 stop bit. */\rUART_Open(UART0, 115200);\r#ifdef _PZ\r/* For palladium */\rUART0-\u0026gt;BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(153600, 38400);\r#endif\r/*\rThis sample code sets I2C bus clock to 100kHz. Then, Master accesses Slave with Multi Bytes Write\rand Multi Bytes Read operations, and check if the read data is equal to the programmed data.\r*/\rprintf(\u0026#34;+--------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| I2C Driver Sample Code for Multi Bytes Read/Write Test |\\n\u0026#34;);\rprintf(\u0026#34;| Needs to work with I2C_Slave sample code |\\n\u0026#34;);\rprintf(\u0026#34;| |\\n\u0026#34;);\rprintf(\u0026#34;| I2C Master (I2C0) \u0026lt;---\u0026gt; I2C Slave(I2C0) |\\n\u0026#34;);\rprintf(\u0026#34;| !! This sample code requires two borads to test !! |\\n\u0026#34;);\rprintf(\u0026#34;+--------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;\\n\u0026#34;);\r/* Init I2C0 */\rI2C0_Init();\r/* Slave address */\rg_u8DeviceAddr = 0x46;\rI2C_WriteByte(I2C0, 0x23, 0x10);\r//r = I2C_ReadByte(I2C0, 0x23);\rreceive_byte = I2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\rprintf(\u0026#34;receive_byte = %d \\n\u0026#34;, receive_byte);\rprintf(\u0026#34;ReadData[0] = %x \\n\u0026#34;, ReadData[0]);\rprintf(\u0026#34;ReadData[1] = %x \\n\u0026#34;, ReadData[1]);\rLux = ReadData[0] * 256 + ReadData[1];\rwhile(1)\r{\rI2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\rLux = ReadData[0] * 256 + ReadData[1];\rprintf(\u0026#34;Lux = %d \\n\u0026#34;, Lux);\r}\r}\r/*** (C) COPYRIGHT 2021 Nuvoton Technology Corp. ***/ ","permalink":"https://weizongchen.github.io/blog/i2c_bh1750/","tags":["Cortex M4"],"title":"使用M460開發版的 I2C 去要 BH1750 照度計sensor的data"},{"categories":["說明文件"],"contents":"BSP EPWM 我是找 BSP 使用的 PWM PIN 角, 但還是用pinconfigure 看一下\n所以根據上圖以及BSP ,\nPWM1 的 Channel0\n會發訊號 給\nPWM1 的 Channel2\n查看開發版的電路圖 是哪兩根PIN EPWM_Capture BSP 的 console 量測邏輯分析儀 EPWM1 的 channel0 發 250 Hz pwm 訊號 30% duty\n/**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Capture the EPWM1 Channel 0 waveform by EPWM1 Channel 2.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r/*---------------------------------------------------------------------------------------------------------*/\r/* Macro, type and constant definitions */\r/*---------------------------------------------------------------------------------------------------------*/\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid CalPeriodTime(EPWM_T *EPWM, uint32_t u32Ch);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\r/*--------------------------------------------------------------------------------------*/\r/* Capture function to calculate the input waveform information */\r/* au32Count[4] : Keep the internal counter value when input signal rising / falling */\r/* happens */\r/* */\r/* time A B C D */\r/* ___ ___ ___ ___ ___ ___ ___ ___ */\r/* ____| |_| |_| |_| |_| |_| |_| |_| |_____ */\r/* index 0 1 2 3 */\r/* */\r/* The capture internal counter down count from 0x10000, and reload to 0x10000 after */\r/* input signal falling happens (Time B/C/D) */\r/*--------------------------------------------------------------------------------------*/\rvoid CalPeriodTime(EPWM_T *EPWM, uint32_t u32Ch)\r{\ruint16_t au16Count[4];\ruint32_t u32i;\ruint16_t u16RisingTime, u16FallingTime, u16HighPeriod, u16LowPeriod, u16TotalPeriod;\r/* Clear Capture Falling Indicator (Time A) */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH);\r/* Wait for Capture Falling Indicator */\rwhile((EPWM1-\u0026gt;CAPIF \u0026amp; EPWM_CAPIF_CFLIF2_Msk) == 0);\r/* Clear Capture Falling Indicator (Time B)*/\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH);\ru32i = 0;\rwhile(u32i \u0026lt; 4)\r{\r/* Wait for Capture Falling Indicator */\rwhile(EPWM_GetCaptureIntFlag(EPWM, u32Ch) \u0026lt; 2);\r/* Clear Capture Falling and Rising Indicator */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);\r/* Get Capture Falling Latch Counter Data */\rau16Count[u32i++] = (uint16_t)EPWM_GET_CAPTURE_FALLING_DATA(EPWM, u32Ch);\r/* Wait for Capture Rising Indicator */\rwhile(EPWM_GetCaptureIntFlag(EPWM, u32Ch) \u0026lt; 2);\r/* Clear Capture Rising Indicator */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_RISING_LATCH);\r/* Get Capture Rising Latch Counter Data */\rau16Count[u32i++] = (uint16_t)EPWM_GET_CAPTURE_RISING_DATA(EPWM, u32Ch);\r}\ru16RisingTime = au16Count[1];\ru16FallingTime = au16Count[0];\ru16HighPeriod = au16Count[1] - au16Count[2];\ru16LowPeriod = (uint16_t)(0x10000 - au16Count[1]);\ru16TotalPeriod = (uint16_t)(0x10000 - au16Count[2]);\rprintf(\u0026#34;\\nEPWM generate: \\nHigh Period=17141 ~ 17143, Low Period=39999 ~ 40001, Total Period=57141 ~ 57143\\n\u0026#34;);\rprintf(\u0026#34;\\nCapture Result: Rising Time = %d, Falling Time = %d \\nHigh Period = %d, Low Period = %d, Total Period = %d.\\n\\n\u0026#34;,\ru16RisingTime, u16FallingTime, u16HighPeriod, u16LowPeriod, u16TotalPeriod);\rif((u16HighPeriod \u0026lt; 17141) || (u16HighPeriod \u0026gt; 17143) || (u16LowPeriod \u0026lt; 39999) || (u16LowPeriod \u0026gt; 40001) || (u16TotalPeriod \u0026lt; 57141) || (u16TotalPeriod \u0026gt; 57143))\rprintf(\u0026#34;Capture Test Fail!!\\n\u0026#34;);\relse\rprintf(\u0026#34;Capture Test Pass!!\\n\u0026#34;);\r}\rvoid SYS_Init(void)\r{\r/* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */\rSET_XT1_OUT_PF2();\rSET_XT1_IN_PF3();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable HIRC and HXT clock */\rCLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk | CLK_PWRCTL_HXTEN_Msk);\r/* Wait for HIRC and HXT clock ready */\rCLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk | CLK_STATUS_HXTSTB_Msk);\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/* Enable EPWM1 module clock */\rCLK_EnableModuleClock(EPWM1_MODULE);\r/* Select EPWM1 module clock source */\rCLK_SetModuleClock(EPWM1_MODULE, CLK_CLKSEL2_EPWM1SEL_PCLK1, 0);\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r/* Set multi-function pin for EPWM */\rSET_EPWM1_CH0_PC5();\rSET_EPWM1_CH2_PC3();\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Init System, IP clock and multi-function I/O\rIn the end of SYS_Init() will issue SYS_LockReg()\rto lock protected register. If user want to write\rprotected register, please issue SYS_UnlockReg()\rto unlock protected register if necessary */\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, IP clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART to 115200-8n1 for print message */\rUART0_Init();\rprintf(\u0026#34;\\n\\nCPU @ %dHz(PLL@ %dHz)\\n\u0026#34;, SystemCoreClock, PllClock);\rprintf(\u0026#34;+------------------------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| EPWM Driver Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;| |\\n\u0026#34;);\rprintf(\u0026#34;+------------------------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34; This sample code will use EPWM1 channel 2 to capture\\n the signal from EPWM1 channel 0.\\n\u0026#34;);\rprintf(\u0026#34; I/O configuration:\\n\u0026#34;);\rprintf(\u0026#34; EPWM1 channel 2(PC.3) \u0026lt;--\u0026gt; EPWM1 channel 0(PC.5)\\n\\n\u0026#34;);\rprintf(\u0026#34;Use EPWM1 Channel 2(PC.3) to capture the EPWM1 Channel 0(PC.5) Waveform\\n\u0026#34;);\rwhile(1)\r{\rprintf(\u0026#34;\\n\\nPress any key to start EPWM Capture Test\\n\u0026#34;);\rgetchar();\r/*--------------------------------------------------------------------------------------*/\r/* Set the EPWM1 Channel 0 as EPWM output function. */\r/*--------------------------------------------------------------------------------------*/\r/* Assume EPWM output frequency is 250Hz and duty ratio is 30%, user can calculate EPWM settings by follows.(up counter type)\rduty ratio = (CMR)/(CNR+1)\rcycle time = CNR+1\rHigh level = CMR\rEPWM clock source frequency = PLL/2 = 100000000\r(CNR+1) = EPWM clock source frequency/prescaler/EPWM output frequency\r= 100000000/7/250 = 57142\r(Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)\rCNR = 57141\rduty ratio = 30% ==\u0026gt; (CMR)/(CNR+1) = 30%\rCMR = 17142\rPrescale value is 6 : prescaler= 7\r*/\r/* Set EPWM1 channel 0 output configuration */\rEPWM_ConfigOutputChannel(EPWM1, 0, 250, 30);\r/* Enable EPWM Output path for EPWM1 channel 0 */\rEPWM_EnableOutput(EPWM1, EPWM_CH_0_MASK);\r/* Enable Timer for EPWM1 channel 0 */\rEPWM_Start(EPWM1, EPWM_CH_0_MASK);\r/*--------------------------------------------------------------------------------------*/\r/* Set the EPWM1 channel 2 for capture function */\r/*--------------------------------------------------------------------------------------*/\r/* If input minimum frequency is 250Hz, user can calculate capture settings by follows.\rCapture clock source frequency = PLL = 100000000 in the sample code.\r(CNR+1) = Capture clock source frequency/prescaler/minimum input frequency\r= 100000000/7/250 = 57142\r(Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)\rCNR = 0xFFFF\r(Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)\rCapture unit time = 1/Capture clock source frequency/prescaler\r70 ns = 1/100000000/7\r*/\r/* Set EPWM1 channel 2 capture configuration */\rEPWM_ConfigCaptureChannel(EPWM1, 2, 70, 0);\r/* Enable Timer for EPWM1 channel 2 */\rEPWM_Start(EPWM1, EPWM_CH_2_MASK);\r/* Enable Capture Function for EPWM1 channel 2 */\rEPWM_EnableCapture(EPWM1, EPWM_CH_2_MASK);\r/* Enable falling capture reload */\rEPWM1-\u0026gt;CAPCTL |= EPWM_CAPCTL_FCRLDEN2_Msk;\r/* Wait until EPWM1 channel 2 Timer start to count */\rwhile((EPWM1-\u0026gt;CNT[2]) == 0);\r/* Capture the Input Waveform Data */\rCalPeriodTime(EPWM1, 2);\r/*------------------------------------------------------------------------------------------------------------*/\r/* Stop EPWM1 channel 0 (Recommended procedure method 1) */\r/* Set EPWM Timer loaded value(Period) as 0. When EPWM internal counter(CNT) reaches to 0, disable EPWM Timer */\r/*------------------------------------------------------------------------------------------------------------*/\r/* Set EPWM1 channel 0 loaded value as 0 */\rEPWM_Stop(EPWM1, EPWM_CH_0_MASK);\r/* Wait until EPWM1 channel 0 Timer Stop */\rwhile((EPWM1-\u0026gt;CNT[0] \u0026amp; EPWM_CNT0_CNT_Msk) != 0);\r/* Disable Timer for EPWM1 channel 0 */\rEPWM_ForceStop(EPWM1, EPWM_CH_0_MASK);\r/* Disable EPWM Output path for EPWM1 channel 0 */\rEPWM_DisableOutput(EPWM1, EPWM_CH_0_MASK);\r/*------------------------------------------------------------------------------------------------------------*/\r/* Stop EPWM1 channel 2 (Recommended procedure method 1) */\r/* Set EPWM Timer loaded value(Period) as 0. When EPWM internal counter(CNT) reaches to 0, disable EPWM Timer */\r/*------------------------------------------------------------------------------------------------------------*/\r/* Set loaded value as 0 for EPWM1 channel 2 */\rEPWM_Stop(EPWM1, EPWM_CH_2_MASK);\r/* Wait until EPWM1 channel 2 current counter reach to 0 */\rwhile((EPWM1-\u0026gt;CNT[2] \u0026amp; EPWM_CNT2_CNT_Msk) != 0);\r/* Disable Timer for EPWM1 channel 2 */\rEPWM_ForceStop(EPWM1, EPWM_CH_2_MASK);\r/* Disable Capture Function and Capture Input path for EPWM1 channel 2*/\rEPWM_DisableCapture(EPWM1, EPWM_CH_2_MASK);\r/* Clear Capture Interrupt flag for EPWM1 channel 2 */\rEPWM_ClearCaptureIntFlag(EPWM1, 2, EPWM_CAPTURE_INT_FALLING_LATCH);\r}\r}\r/*** (C) COPYRIGHT 2021 Nuvoton Technology Corp. ***/ ","permalink":"https://weizongchen.github.io/blog/pwm/","tags":["Cortex M4"],"title":" PWM 的 應用範例 "},{"categories":["說明文件"],"contents":"Timer0 電路位置 由pinconfigure 可以知道Timer0 在 pin 1 (PB5) 接著\n設定 Timer0 pin 角 //\u0026mdash;PIN\u0026mdash;- /* Set timer toggle out pin */ SET_TM0_PB5();\nTimer Delay Delay 1 秒:\nTIMER_Delay(TIMER0, 1000000);\nTimer init_TIMER0_Toggle TIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 250000);\n開啟TIMER0 反轉250K\n邏輯分析儀量測 邏輯分析儀 桶著 Pin1 開 Salease 邏輯分析儀 SW 可以發現訊號是125K Hz 波峰 +波谷 就250K Hz\n/*---------------------------------------------------------------------------------------------------------*/\r/* Global Interface Variables Declarations */\r/*---------------------------------------------------------------------------------------------------------*/\rvolatile uint32_t g_au32TMRINTCount[4] = {0};\r//----------------- TIMER0 --------------------\rvoid TMR0_IRQHandler(void)\r{\rif(TIMER_GetIntFlag(TIMER0) == 1)\r{\r/* Clear Timer0 time-out interrupt flag */\rTIMER_ClearIntFlag(TIMER0);\rg_au32TMRINTCount[0]++;\rPH4 ^= 1;\r}\r}\rvoid TMR0_Init(void)\r{\r/* Enable TIMER module clock */\r//---clock---\rCLK_EnableModuleClock(TMR0_MODULE);\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);\r//---PIN----\r/* Set timer toggle out pin */\rSET_TM0_PB5();\r/* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */\rTIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1);\r/* Start Timer0 ~ Timer3 counting */\rTIMER_Start(TIMER0);\r//--- NVIC ----\rTIMER_EnableInt(TIMER0);\r/* Enable Timer0 ~ Timer3 NVIC */\rNVIC_EnableIRQ(TMR0_IRQn);\r/* Check Timer0 ~ Timer3 interrupt counts */\r//g_au32TMRINTCount[0];\r}\rvoid init_TIMER0_Toggle(void)\r{\r/* Enable TIMER module clock */\r//---clock---\rCLK_EnableModuleClock(TMR0_MODULE);\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);\r//---PIN----\r/* Set timer toggle out pin */\rSET_TM0_PB5();\r/* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */\rTIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 250000);\r/* Start Timer0 ~ Timer3 counting */\rTIMER_Start(TIMER0);\r}\r//-------------- HCLK -------------\rvoid init_HCLK(void){\rSYS_UnlockReg();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable HXT clock */\rCLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);\rCLK_WaitClockReady( CLK_STATUS_HXTSTB_Msk);\rSYS_LockReg();\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\ruint16_t cnt = 0;\ruint8_t STA = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rinit_HCLK();\rinit_TIMER0_Toggle();\r// PH4 LED R\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rwhile(1) {\r}\r} ","permalink":"https://weizongchen.github.io/blog/timer_init_timer0_toggle/","tags":["Cortex M4"],"title":"Timer Toggle 使用邏輯分析儀量測timer toggle (by M460)"},{"categories":["說明文件"],"contents":" 新唐 Pinconfigure 地址 https://www.nuvoton.com/resource-download.jsp?tp_GUID=SW1320200319135912\n當發現我要的IC 沒有出現在 我要的M460 沒有在 Pinconfigure 選單\nDownload 新的exe file Pinconfigure 下載\nM460 出現了 ","permalink":"https://weizongchen.github.io/blog/install_and_update_pinconfigure/","tags":["Tool"],"title":"安裝新唐 Pinconfigure "},{"categories":["說明文件"],"contents":"Button 的 狀態討論 /*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\ruint16_t cnt = 0;\ruint8_t STA = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rwhile(1) {\rSTA \u0026lt;\u0026lt;= 1;\rSTA += PH0;\rprintf(\u0026#34;%d \\n\u0026#34;, PH0);\rTIMER_Delay(TIMER0, 1000000);\rSTA \u0026amp;= 3;\rif(STA == 2) {\rcnt++;\r//printf(\u0026#34;%d \u0026#34;, cnt);\r}\r//TIMER_Delay(TIMER0, 1000000);\r}\r} STA 原始值 00000000(0)\n二進制 (十進制)\rSTA :\n第一圈 結果 00000000 左移一次 00000000 00000000+ PH0(1) [沒有按] 00000001 00000001 \u0026amp; 00000011(3) 00000001(1) STA == 2 false 第二圈 結果 00000001 左移一次 00000010 00000010 + PH0(1) [沒有按] 00000011 00000011 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第三圈 結果 00000011 左移一次 00000110 00000110 + PH0(1) [沒有按] 00000111 00000111 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第四圈 結果 00000011 左移一次 00000110 00000110 + PH0(1) [沒有按] 00000111 00000111 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第五圈 結果 00000011 左移一次 00000110 00000110 + PH0(0) [按下去] 00000110 00000110 \u0026amp; 00000011(3) 00000010(2) STA == 2 true 印數字 (CPU執行很快,可能不小心print到數個數字)\n第六圈 結果 00000010 左移一次 00000100 00000100 + PH0(0) [還按著] 00000100 00000100 \u0026amp; 00000011(3) 00000000(0) STA == 2 false 第七圈 結果 00000000 左移一次 00000000 00000000 + PH0(0) [還按著] 00000000 00000000 \u0026amp; 00000011(3) 00000000(0) STA == 2 false 第八圈 (等於第一圈) 結果 00000000 左移一次 00000000 00000000 + PH0(1) [沒有按] 00000001 00000001 \u0026amp; 00000011(3) 00000001(1) STA == 2 false ","permalink":"https://weizongchen.github.io/blog/btn/","tags":["Cortex M4"],"title":"Button 的各種說明"},{"categories":["說明文件"],"contents":"加入Timer的Driver 在 SYS_Init() 時 ,加入TMR0 的 clock source /*---------------------------------------------------------------------------------------------------------*/\r/* Initialization for sample code */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable TIMER module clock */\rCLK_EnableModuleClock(TMR0_MODULE);\r/* Select TIMER clock source */\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HIRC, 0); 在 SYS_Init() 時 ,加入TMR0 的 clock source while(1) {\rPH4 = 1;\rTIMER_Delay(TIMER0, 1000000);\rPH4 = 0;\rTIMER_Delay(TIMER0, 1000000);\r} 邏輯分析儀量測 LED 訊號 用 Timer0 控制 LED 1秒亮 1秒滅 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Transmit and receive data from PC terminal through RS232 interface.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define RXBUFSIZE 1024\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rstatic uint8_t g_u8RecData[RXBUFSIZE] = {0};\rstatic volatile uint32_t g_u32comRbytes = 0;\rstatic volatile uint32_t g_u32comRhead = 0;\rstatic volatile uint32_t g_u32comRtail = 0;\rstatic volatile int32_t g_i32Wait = TRUE;\r/*---------------------------------------------------------------------------------------------------------*/\r/* Define functions prototype */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void);\rvoid UART_TEST_HANDLE(void);\rvoid UART_FunctionTest(void);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\rvoid UART0_IRQHandler(void);\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART module clock */\rCLK_EnableModuleClock(UART0_MODULE);\rCLK_EnableModuleClock(UART1_MODULE);\r/* Select UART module clock source and UART module clock divider */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\rCLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HIRC, CLK_CLKDIV0_UART1(1));\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Initialization for sample code */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable TIMER module clock */\rCLK_EnableModuleClock(TMR0_MODULE);\r/* Select TIMER clock source */\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HIRC, 0);\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Reset UART0 */\rSYS_ResetModule(UART0_RST);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rprintf(\u0026#34;test \\n\u0026#34;);\rwhile(1) {\rPH4 = 1;\rTIMER_Delay(TIMER0, 1000000);\rPH4 = 0;\rTIMER_Delay(TIMER0, 1000000);\r}\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* ISR to handle UART Channel 0 interrupt event */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART0_IRQHandler(void)\r{\rUART_TEST_HANDLE();\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* UART Callback function */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART_TEST_HANDLE(void)\r{\ruint8_t u8InChar = 0xFF;\ruint32_t u32IntSts = UART0-\u0026gt;INTSTS;\rif(u32IntSts \u0026amp; UART_INTSTS_RDAINT_Msk)\r{\rprintf(\u0026#34;\\nInput:\u0026#34;);\r/* Get all the input characters */\rwhile(UART_IS_RX_READY(UART0))\r{\r/* Get the character from UART Buffer */\ru8InChar = (uint8_t)UART_READ(UART0);\rprintf(\u0026#34;%c \u0026#34;, u8InChar);\rif(u8InChar == \u0026#39;0\u0026#39;)\r{\rg_i32Wait = FALSE;\r}\r/* Check if buffer full */\rif(g_u32comRbytes \u0026lt; RXBUFSIZE)\r{\r/* Enqueue the character */\rg_u8RecData[g_u32comRtail] = u8InChar;\rg_u32comRtail = (g_u32comRtail == (RXBUFSIZE - 1)) ? 0 : (g_u32comRtail + 1);\rg_u32comRbytes++;\r}\r}\rprintf(\u0026#34;\\nTransmission Test:\u0026#34;);\r/* Forces a write of all user-space buffered data for the given output */\rfflush(stdout);\r}\rif(u32IntSts \u0026amp; UART_INTSTS_THREINT_Msk)\r{\ruint32_t u32Tmp;\ru32Tmp = g_u32comRtail;\rif(g_u32comRhead != u32Tmp)\r{\ru8InChar = g_u8RecData[g_u32comRhead];\rwhile(UART_IS_TX_FULL(UART0)); /* Wait Tx is not full to transmit data */\rUART_WRITE(UART0, u8InChar);\rg_u32comRhead = (g_u32comRhead == (RXBUFSIZE - 1)) ? 0 : (g_u32comRhead + 1);\rg_u32comRbytes--;\r}\r}\r/* Handle transmission error */\rif(UART0-\u0026gt;FIFOSTS \u0026amp; (UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_RXOVIF_Msk))\r{\rUART0-\u0026gt;FIFOSTS = (UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_RXOVIF_Msk);\r}\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* UART Function Test */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART_FunctionTest(void)\r{\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| UART Function Test |\\n\u0026#34;);\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| Description : |\\n\u0026#34;);\rprintf(\u0026#34;| The sample code will print input char on terminal |\\n\u0026#34;);\rprintf(\u0026#34;| Please enter any to start (Press \u0026#39;0\u0026#39; to exit) |\\n\u0026#34;);\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\r/*\rUsing a RS232 cable to connect UART0 and PC.\rUART0 is set to debug port. UART0 is enable RDA interrupt.\rWhen inputting char to terminal screen, RDA interrupt will happen and\rUART0 will print the received char on screen.\r*/\r/* Enable UART RDA and THRE interrupt */\rNVIC_EnableIRQ(UART0_IRQn);\rUART_EnableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk));\rwhile(g_i32Wait);\r/* Disable UART RDA and THRE interrupt */\rNVIC_DisableIRQ(UART0_IRQn);\rUART_DisableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk));\rg_i32Wait = TRUE;\r} ","permalink":"https://weizongchen.github.io/blog/timer_delay/","tags":["Cortex M4"],"title":"Timer Delay 說明 (by M460)"},{"categories":["說明文件"],"contents":"在Keil IDE 的 Debug Mode 時 Memory window data 突然不實時更新了?\n下圖 右邊的 Memory2 本來會一直更新,但是沒有?\n只要在 View下的 Periodic Window Update 打開就好\n如下影片操作\n","permalink":"https://weizongchen.github.io/blog/keil_debug_memoryupdate/","tags":["Cortex M4"],"title":"Keil IDE Debug Mode Memory window data not update?"},{"categories":["說明文件"],"contents":"Keil IDE 在啟動 project 時,會自己上網下載 一堆不是新唐的pack\n下圖看到時趕緊關掉,不然他會一直download 不是新唐的東西。\n這邊選\u0026quot;是\u0026quot; 跳過這裡\n這個時候,Keil會跟你說沒有這個M460的 pack 包,你如果不安裝 ,compile 也會過,但是每次打開Keil 會就跳出來,滿煩的。\n去新唐的官網,下載Driver 就可以解決這個問題了。\n新唐Driver 位置\nNu-Link_Keil_Driver_V3.09.7380r\n準備安裝\n這裡如果你不懂,就按照指示預設安裝路徑。\n這裡會出現這個視窗,是因為我原本就已經安裝過這個Driver,裡面有M480 NUC505 \u0026hellip; 一堆 但是不包含M460的部分,所以按\u0026quot;是\u0026quot;,就會更新成有包含460的\n這裡步驟就是安裝pack(Nuvoton device family pack)了 一路按\u0026quot;是\u0026quot; 就可以了\n他會把Nuvoton的pack都安裝\n因為我使用新唐的開發版,上面有Nu-Link2-Me 的燒錄器,所以當然也安裝一下它的driver,你如果是 J-Link 、U-Link 、巴拉巴拉Link\u0026hellip;,要自己安裝他們的Driver喔。\n安裝\n再次打開Project 就不會有那些警告視窗拉~\n","permalink":"https://weizongchen.github.io/blog/keil_import_pack/","tags":["Cortex M4"],"title":"Keil IDE 在啟動 project 時,會自己上網下載 一堆不是新唐的pack"},{"categories":["說明文件"],"contents":"如果你不是商業使用 !\n如果你不是商業使用 !\n如果你不是商業使用 !\n很重要所以說三次! 所以如果你是個人評估使用\nARM 對這個 MDK-Community 說明\n簡單說就是支援 : All microcontrollers based on Arm Cortex®-M processors\n你給他E mail 它就給你licence\n把上面 LIC 填到下面\n","permalink":"https://weizongchen.github.io/blog/keil_ide_licence/","tags":["Cortex M4"],"title":"Keil IDE 16K Code size 限制?"},{"categories":["說明文件"],"contents":" 可以直接來這邊下載 https://www.nuvoton.com/tool-and-software/debugger-and-programmer/mass-production-tool/\nICP Tool 新唐燒錄器適用於新唐NuMicro®微控制器的大量生產階段。基於靈活的設定與直觀的操作,使用者可全面掌握量產流程。\n選擇你的series\n如果你電腦插著很多個NuLnk 可以選,點選Radio Button時,那個被指定的NuLnk會閃閃閃閃閃~\n如果你電腦灌過ICP 軟體了,跟這板子原本的ICP版本不匹配,你可以更新,也可以不更新,一般我都直接不更新,反正可以燒就好。\n因為我是要把板子上的APROM的 firmware拿出來存,可以照下圖的方式點選\n最後成功存取\nFile Data 要燒進去板子的FW版本\nOn board flash 板子上面的FW版本\nOffline Flash 在燒入除錯器裡面的版本\n","permalink":"https://weizongchen.github.io/blog/icp_introduce/","tags":["Tool"],"title":"ICP 使用說明"},{"categories":["說明文件"],"contents":" User Manual https://www.nuvoton.com/export/resource-files/UM_NuMaker-ETM-M487_User_Manual_EN_Rev1.01.pdf\n通用 I/O (GPIO) 概述 M480 系列多達118 個通用I/O管腳和其他功能管腳共享,這取決於芯片的配置。 118個管腳分配在PA, PB, PC, PD, PE, PF, PG 和 PH這8個端口上。 PA, PB, PE和PG有16個管腳,PC,PD有15個管腳,PF,PH有12個管腳。每個管腳都是獨立的,都有相應的寄存器位來控制管腳功能模式與數據。\n1. 設定發電廠 (clock) 2. 設定 LED 的腳位 General Port 0~7 為 Low byte, 8~15 為 High byte 所以是Port H 的 0 1 2 是L,如下面黃色的標記\n設定 Port H 0 1 2 腳位為 output\n3. 設定 Button 的腳位 General Port 0~7 為 Low byte, 8~15 為 High byte 所以是Port B 的 15 是H , Port F 的 11 是H,如下面黃色的標記\n設定 Port B 15 和 Port F 11 腳位為 input\n4. 設定 UART0 的腳位 新唐大部分的M4 UART0 腳位是 PB12 RXD / PB13 TXD\n5. 設定中斷 這邊中斷就是用UART0 打印東西,和 toggle LED 的亮滅\n完整程式參考 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief GPIO function for level1 training course\r*\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define LED_R\tPH0\r#define LED_G\tPH1\r#define LED_B\tPH2\r#define LED_ON\t0\r#define LED_OFF\t1\rvolatile uint32_t sw1_int_cnt = 0;\rvolatile uint32_t sw2_int_cnt = 0;\rvoid SYS_Init(void)\r{\r/* Enable HXT clock (external XTAL 12MHz) */\rCLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);\r/* Wait for HXT clock ready */\rCLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);\r/* Enable LIRC clock */\rCLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);\r/* Wait for LIRC clock ready */\rCLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);\r/* Set core clock as PLL_CLOCK from PLL */\rCLK_SetCoreClock(FREQ_192MHZ);\r/* Set PCLK0/PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2);\r/* Enable module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Set module clock */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));\r}\rvoid UART0_Init()\r{\r/* Set GPB multi-function pins to UART0 RXD and TXD */\rSYS-\u0026gt;GPB_MFPH = (SYS-\u0026gt;GPB_MFPH \u0026amp; ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) |\r(SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\rvoid LED_Init(void)\r{\r/* Set PH.0 ~ PH.2 to GPIO */\rSYS-\u0026gt;GPH_MFPL = (SYS-\u0026gt;GPH_MFPL \u0026amp; ~(SYS_GPH_MFPL_PH0MFP_Msk | SYS_GPH_MFPL_PH1MFP_Msk | SYS_GPH_MFPL_PH2MFP_Msk)) |\r(SYS_GPH_MFPL_PH0MFP_GPIO | SYS_GPH_MFPL_PH1MFP_GPIO | SYS_GPH_MFPL_PH2MFP_GPIO);\r/* Set PC.9 ~ PC.11 to GPIO output */\rGPIO_SetMode(PH, (BIT0 | BIT1 | BIT2), GPIO_MODE_OUTPUT);\r/* Let LED off after initialize */\rLED_R = LED_OFF;\rLED_G = LED_OFF;\rLED_B = LED_OFF;\r}\rvoid BTN_Init(void)\r{\r/************** SW2 ***************/\r/* Set PB.15 to GPIO */\rSYS-\u0026gt;GPG_MFPH = (SYS-\u0026gt;GPG_MFPH \u0026amp; ~(SYS_GPG_MFPH_PG15MFP_Msk)) | (SYS_GPG_MFPH_PG15MFP_GPIO);\r/* Set PB.15 to GPIO intput */\rGPIO_SetMode(PG, BIT15, GPIO_MODE_INPUT);\rGPIO_EnableInt(PG, 15, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPG_IRQn);\r/************** SW3 ***************/\r/* Set PF.11 to GPIO */\rSYS-\u0026gt;GPF_MFPH = (SYS-\u0026gt;GPF_MFPH \u0026amp; ~(SYS_GPF_MFPH_PF11MFP_Msk)) | (SYS_GPF_MFPH_PF11MFP_GPIO);\r/* Set PF.11 to GPIO intput */\rGPIO_SetMode(PF, BIT11, GPIO_MODE_INPUT);\rGPIO_EnableInt(PF, 11, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPF_IRQn);\r/* Set de-bounce function */\rGPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_512);\rGPIO_ENABLE_DEBOUNCE(PG, BIT15);\rGPIO_ENABLE_DEBOUNCE(PF, BIT11);\r}\rint main(void)\r{\ruint32_t sw1_cnt = 0, sw2_cnt = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| Level1 GPIO control Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\\n\u0026#34;);\r/* Init LED */\rLED_Init();\r/* Init BTN */\rBTN_Init();\rwhile(1) {\r/* Check if the SW1 is pressed */\rif (sw1_int_cnt != sw1_cnt) {\rsw1_cnt = sw1_int_cnt;\rprintf(\u0026#34;SW1 interrupt count: %d\\n\u0026#34;, sw1_cnt);\r}\r/* Check if the SW2 is pressed */\rif (sw2_int_cnt != sw2_cnt) {\rsw2_cnt = sw2_int_cnt;\rprintf(\u0026#34;SW2 interrupt count: %d\\n\u0026#34;, sw2_cnt);\r}\r}\r}\r//PG15\rvoid GPG_IRQHandler(void)\r{\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;+------------Detect PG---------------+\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\r/* Check if PG.15 the interrupt occurred */\rif(GPIO_GET_INT_FLAG(PG, BIT15)) {\rLED_R ^= 1;\rsw1_int_cnt++;\r/* Clear PG.15 interrupt flag */\rGPIO_CLR_INT_FLAG(PG, BIT15);\r}else {\r/* Un-expected interrupt. Just clear all PB interrupts */\rPG-\u0026gt;INTSRC = PG-\u0026gt;INTSRC;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r}\r//PF11\rvoid GPF_IRQHandler(void)\r{\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;+------------Detect PF---------------+\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\r/* Check if PF.11 the interrupt occurred */\rif(GPIO_GET_INT_FLAG(PF, BIT11)) {\rLED_G ^= 1;\rsw2_int_cnt++;\r/* Clear PF.11 interrupt flag */\rGPIO_CLR_INT_FLAG(PF, BIT11);\r} else {\r/* Un-expected interrupt. Just clear all PB interrupts */\rPF-\u0026gt;INTSRC = PF-\u0026gt;INTSRC;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r} M460 的控制LED範例 /*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r//Mode\r*(volatile unsigned int *)(0x400041C0) = 0x00001500;\r//value\r*(volatile unsigned int *)(0x400041C8) = 0x0000FF8F;\rwhile(1) {\rint i;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1下\r*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1下\r*(volatile unsigned int *)(0x400041C8) = 0x00000070;\r}\r} *(volatile unsigned int *)(0x400041C0) = 0x00001500;\nRegister 位置\n0x40004000 + 0x1C0\nRegister的值\n0x 0000 1500\n000\u0026hellip;0 1500 如下圖\n*(volatile unsigned int *)(0x400041C8) = 0x00000070;\n0x1C8 是 PH_DOUT (port H out) 的控制\n70 如下圖所示 (0x00000070 全滅 0x00000000 全亮)\nint32_t main(void)\r{\r//Mode\r*(volatile unsigned int *)(0x400041C0) = 0x00001500;\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\r//value\r*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rPH4 = 0;\rPH5 = 0;\rPH6 = 0;\rwhile(1) {\rint i;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1百萬下\r// 全滅\r//*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rPH4 = 1;\rPH5 = 1;\rPH6 = 1;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1百萬下\r// 全亮\rPH4 = 0;\rPH5 = 0;\rPH6 = 0;\r}\r} M460 的控制Button範例 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Show the usage of GPIO interrupt function.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\rvoid GPH_IRQHandler(void);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\r/**\r* @brief GPIO PH IRQ\r*\r* @param None\r*\r* @return None\r*\r* @details The PH default IRQ, declared in startup_m460.s.\r*/\rvoid GPH_IRQHandler(void)\r{\rvolatile uint32_t u32temp;\r/* To check if PH.0 interrupt occurred */\rif(GPIO_GET_INT_FLAG(PH, BIT0))\r{\rGPIO_CLR_INT_FLAG(PH, BIT0);\rprintf(\u0026#34;PH.0 INT occurred.\\n\u0026#34;);\r}\relse if(GPIO_GET_INT_FLAG(PH, BIT1))\r{\rGPIO_CLR_INT_FLAG(PH, BIT1);\rprintf(\u0026#34;PH.1 INT occurred.\\n\u0026#34;);\r}\relse\r{\r/* Un-expected interrupt. Just clear all PH interrupts */\ru32temp = PH-\u0026gt;INTSRC;\rPH-\u0026gt;INTSRC = u32temp;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r}\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Reset UART0 */\rSYS_ResetModule(UART0_RST);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rprintf(\u0026#34;\\n\\nCPU @ %d Hz\\n\u0026#34;, SystemCoreClock);\rprintf(\u0026#34;+------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| GPIO PH.0 and PH.1 Interrupt Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;+------------------------------------------------+\\n\\n\u0026#34;);\r/*-----------------------------------------------------------------------------------------------------*/\r/* GPIO Interrupt Function Test */\r/*-----------------------------------------------------------------------------------------------------*/\rprintf(\u0026#34;PH.0 and PH.1 are used to test interrupt ......\\n\u0026#34;);\r/* Configure PH.0 as Input mode and enable interrupt by rising edge trigger */\rGPIO_SetMode(PH, BIT0, GPIO_MODE_INPUT);\rGPIO_EnableInt(PH, 0, GPIO_INT_RISING);\rNVIC_EnableIRQ(GPH_IRQn);\r/* Configure PH.1 as Quasi-bidirection mode and enable interrupt by falling edge trigger */\rGPIO_SetMode(PH, BIT1, GPIO_MODE_QUASI);\rGPIO_EnableInt(PH, 1, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPH_IRQn);\r/* Enable interrupt de-bounce function and select de-bounce sampling cycle time is 1024 clocks of LIRC clock */\rGPIO_SET_DEBOUNCE_TIME(PH, GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_1024);\rGPIO_SET_DEBOUNCE_TIME(PH, GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_1024);\rGPIO_ENABLE_DEBOUNCE(PH, BIT0);\rGPIO_ENABLE_DEBOUNCE(PH, BIT1);\r/* Waiting for interrupts */\rwhile(1);\r} ","permalink":"https://weizongchen.github.io/blog/gpio_introduce/","tags":["Cortex M4"],"title":"GPIO 說明"},{"categories":["安裝步驟文件"],"contents":"Description Enable the Remoteproc device driver in the Linux kernel.\n$ bitbake linux-ma35d1 -c menuconfig Device Drivers ---\u0026gt;\rRemoteproc drivers ---\u0026gt;\r[*] Support for Remote Processor subsystem\r\u0026lt;*\u0026gt; MA35D1 remoteproc support \u0026lt;Save\u0026gt; and \u0026lt;Exit\u0026gt; Description Modify the device tree node setting of remoteproc in the Linux kernel.\nLINUX_KERENL_PATH/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi Description Compile the Linux kernel.\n$ bitbake linux-ma35d1 -C compile Description Modify the device tree node setting of SSPCC in the TF-A. 怎麼知道是I2S0_SUBM的?\nDescription Modify the device tree node setting of SSPCC in the TF-A. 怎麼知道是這4根pin角的?\nDescription Compile the TF-A.\n$ bitbake tf-a-ma35d1 -C compile Description Build-up Image. Qt 版本:\nbitbake nvt-image-qt5 -c cleanall \u0026amp;\u0026amp; bitbake nvt-image-qt5 Minimal 版本:\n$ bitbake core-image-minimal –c cleanall \u0026amp;\u0026amp; bitbake core-image-minimal Description Burn-in Image into SD card. 燒入SD卡\n$ sudo dd if=nvt-image-qt5-evb-ma35d1-xxxxx.rootfs.sdcard of=/dev/sdb 延展SD的size\rsudo ./ma35d1_resize.sh /dev/sdb 1 apply 把 M4 的.axf 放到SD卡的 /lib/firmware 中\nNote: The following step copy all of RTP (M4) sample codes in the M4_BSP into Filesystem. You can chose the sample code you want to use or replace with the firmware you developed. 執行 M4 axf 的指令\necho -n /lib/firmware \u0026gt; /sys/module/firmware_class/parameters/path\recho -n I2S_Codec_PDMA.elf \u0026gt; /sys/class/remoteproc/remoteproc0/firmware\recho start \u0026gt; /sys/class/remoteproc/remoteproc0/state\recho stop \u0026gt; /sys/class/remoteproc/remoteproc0/state Remoteproc - Keil IDE 設定\nNu-link 的DAP 要設定1\nPS:原本我們開發板的NuLink 是 0 ,MA35D1的要改1 ","permalink":"https://weizongchen.github.io/blog/ma35d1_rtp/","tags":["MA35D1","Cortex M4"],"title":"MA35D1 M4 使用設定"},{"categories":["安裝步驟文件"],"contents":"MA35D16A887C (BGA312) MCP package with DDR3L (256 MB)\n7-inch TFT LCD (1024x600) with touch daughter board\neMMC memory device daughter board\nSPI-NAND flash W25N02JWZEIF (256MB)\nNAND flash W29N01HVS1NA (128MB)\n2 x Giga Ethernet\n2 x High Speed USB\n2 x Camera Capture (CMOS sensor) header connectors\n1 x SIM Card slot\n2 x UART, 2 x RS485, 2 x CAN-FD, 8 x EADC channels\n基本安裝設定 Yocto 項目至少需要 150G 存儲\n在使用 Yocto 項目之前必須安裝必要的包\n$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \\\rbuild-essential chrpath socat cpio python python3 python3-pip python3-pexpect \\\rxz-utils debianutils iputils-ping libsdl1.2-dev xterm curl Update existing list of packages\n$ sudo apt-get update Install a few prerequisite packages which let apt use packages over HTTPS\n$ sudo apt install apt-transport-https ca-certificates curl software-properties-common Add Docker’s official GPG key for the official Docker repository to your system\n$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add Set up the stable repository, add the Docker repository to APT sources\n$ sudo add-apt-repository \u0026#34;deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable\u0026#34; Update the package database with the Docker packages from the newly added repo\n$ sudo apt-get update Install Docker\n$ sudo apt-get install docker-ce docker-ce-cli containerd.io Download the Docker Script for MA35D1\n$ git clone https://github.com/OpenNuvoton/MA35D1_Docker_Script.git Enter docker-yocto folder, setup docker image, and select folder to be share\n$ ./build.sh It may take one hour to get 710 files.\rPlease enter absolute path for shared folders(eg:/home/\u0026lt;user name\u0026gt;) : Enter docker image, and your command line head will be like nuvoton@a24d9e06abe3:~$\n$ ./join.sh\rnua3500_nuvoton\rnuvoton@a24d9e06abe3:~$ Create a folder name yocto under /share\nnuvoton@a24d9e06abe3:~/share$ mkdir yocto The first time you use repo, you need to set up the GIT environment\nnuvoton@a24d9e06abe3:~/share/yocto$ git config --global user.email \u0026#34;test@test.test.test\u0026#34;\rnuvoton@a24d9e06abe3:~/share/yocto$ git config --global user.name \u0026#34;test“\rnuvoton@a24d9e06abe3:~/share/yocto$ git config --global http.sslverify false Go to /share/yocto to setup repo path\nnuvoton@a24d9e06abe3:~/share/yocto$ repo init -u https://github.com/OpenNuvoton/MA35D1_Yocto-v3.1.3.git -m meta-ma35d1/base/ma35d1.xml Download the yocto project\nnuvoton@a24d9e06abe3:~/share/yocto$ repo sync Build Image by Yocto Setup building configuration. The DISTRO option we usually use nvt-ma35d1-directfb\nEVB :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=ma35d1-evb source sources/init-build-env build SOM :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=numaker-som-ma35d16a81 source sources/init-build-env build MACHINE 目前有 SOM 板 或 IOT 板,後面ma35d16a81是 板號,所以客戶可以做他自己的板子,用自己得板號。\nMACHINE=numaker-som-ma35d16a81\nMACHINE=numaker-iot-ma35d16f70 ( f7 =\u0026gt; DDR 128MB )\nMACHINE=numaker-iot-ma35d16f90 ( f9 =\u0026gt; DDR 512MB )\ntest chip SOM :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=ma35d1-tc-som source sources/init-build-env build (補充說明) 假設我要改build 不同的板號,從numaker-som-ma35d16a81 改成 numaker-iot-ma35d16f70,有兩個地方要改 local.conf 的 Machine 要改如下 指定編譯 DISTRO=nvt-ma35d1-directfb MACHINE=numaker-iot-ma35d16f70 source sources/init-build-env build Choose what Image you want to build\nImage 包含Qt的版本 (建議)\nbitbake nvt-image-qt5 小 Image 版本\nbitbake core-image-minimal Copy the image to SD $ sudo dd if=nvt-image-qt5-evb-ma35d1-xxxxx.rootfs.sdcard of=/dev/sdb status=progress Fast Application Development Make a toolchain installer\n$ bitbake nvt-image-qt5 -c populate_sdk\r(This may take about 1 hour ) Go to the following path and execute the shell file\n~build/tmp-glibc/deploy/sdk $ ./oecore-x86_x64-aarch64-toolcahin-5.5-dunfell.sh Add toolchain to environment variables\n$ source /usr/local/oecore-x86_64/environment-setup-aarch64-poky-linux Create the source code file for this example: helloworld.c\n#include \u0026lt;stdio.h\u0026gt;\rint main() {\r// printf() displays the string inside console\rprintf(“Hello, World!\\n”);\rreturn 0;\r} Compile it\n$ $CC helloworld.c -o helloworld ","permalink":"https://weizongchen.github.io/blog/ma35d1_install_method/","tags":["MA35D1"],"title":"MA35D1 Yocto 安裝說明"},{"categories":["說明文件"],"contents":" 要找這個Register\n問這個PDBIASEN bit 找不到\u0026hellip;..\nCLK-\u0026gt;LDOCTL |= CLK_LDOCTL_PDBIASEN_Msk;\nClock, LDO control Rigister, PDBIASEN 這個 bit\nbit 18\n忘記在哪一版本TRM 有找到這個register\n右邊表格˙(1) (2) 沒有賣了,所以只是給過去參考,目前就是看(3) 就好~\nCore Coupled Memory Mode (CCM Mode)\nCCM Mode 是 SRAM 跟 SPI Flash 的關係,SPI Flash可以把SRAM當作catch來使用,\nCCMEN 打開 就是一般SRAM,不是catch\nWhen user sets CCMEN(SPIM_CTL1[2]) to 1, the operation mode of cache memory will be core coupled memory mode (CCM mode). In CCM mode, the cache function of SPI Flash controller is disabled by hardware automatically, and MCU can access this core coupled memory as general SRAM. When user sets CCMEN(SPIM_CTL1[2]) to 0 and MCU accesses CCM address range, SPI Flash controller will generate AHB error response to MCU.\n當用戶設置CCMEN(SPIM_CTL1[2])為1時,緩存存儲器操作模式會轉變成內核耦合存儲器模式(CCM模 式)。在CCM模式下,SPI flash控制器的緩存功能會被硬件自動禁用,MCU訪問內核耦合存儲器就像是 SRAM一樣。當用戶設置CCMEN(SPIM_CTL1[2])為0時MCU訪問CCM地址範圍,SPI flash控制器將會 產生AHB錯誤給MCU\n","permalink":"https://weizongchen.github.io/blog/question/","tags":null,"title":"自己的問題筆記"},{"categories":["安裝步驟文件"],"contents":"系統環境 Windows 10 VS 2019 OpenCV 4.5.5 選擇 Windows 版本的OpenCV download下來 解壓縮到指定資料夾 可以在C 根目錄建一個 OpenCV 資料夾,在OpenCV資料夾下再建一個OpenCV4.5.5資料夾,並解押到這裡面\n整理檔案位置,將需要的檔案拿出來就好 因為opencv資料夾的大小很大,可以刪除。如空間夠大可以留下來,以備不時之需。\nbin 資料夾說明 opencv 3 版本之後,只需要opencv_world455.dll就可以了,opencv_world455d.dll 多一個d是指 debug版本的意思。\n設定環境變數 建立一個空的C++專案 建立一個空的C++專案 在這裡應該有solution 和 project 的分別,我們要在solution的位置新增一個專案 建立屬性管理員 Property Manager 方便每次專案可以套用同一個屬性,比如哪天出了opencv新的版本,可以直接套用新的版本的opencv或使用更舊版本的opencv 去view打開屬姓管理員,預設是沒有顯示的。 使用x64的Release版本\n建一個有意義的名子,給x64、opencv版本是455、Release的版本使用的property 已產生此版本的屬性,待會就用這個屬性設定opencv的變數\n使用 Property Manager 設定OpenCV的環境 記得因為我們是使用 Release x64 版本的屬性所以上面要改一下\n基本上打到第2層,就會有提示字出現之後,就表示設定成功了,設定一下起始專案。\n寫一個簡單的程式測試一下 opencv 的設定 // loadimg.cpp : 此檔案包含 \u0026#39;main\u0026#39; 函式。程式會於該處開始執行及結束執行。\r//\r#include \u0026lt;iostream\u0026gt;\r#include \u0026lt;opencv2/core/core.hpp\u0026gt;\r#include \u0026lt;opencv2/highgui/highgui.hpp\u0026gt;\rusing namespace std;\rusing namespace cv;\rint main()\r{\rMat img;\rimg = imread(\u0026#34;C:\\\\Users\\\\b51ak\\\\Pictures\\\\promotion.png\u0026#34;);\rnamedWindow(\u0026#34;figure 1\u0026#34;, WINDOW_AUTOSIZE);\rimshow(\u0026#34;figure 1\u0026#34;, img);\rstd::cout \u0026lt;\u0026lt; \u0026#34;Hello World!\\n\u0026#34;;\rwaitKey(0);\rreturn 0;\r} ","permalink":"https://weizongchen.github.io/blog/opencv_env/","tags":["OpenCV"],"title":"OpenCV 環境安裝"}] \ No newline at end of file +[{"categories":["安裝步驟文件"],"contents":"要找MA35D1的兩根pin腳給PWM 新唐定義 PG1 PG2 的地方 設定 device tree Kernel configuration settin\n/* 1. Add node in device tree root\u0026#39;s configuration */\r/ {\rmodel = \u0026#34;Nuvoton MA35D1-SOM\u0026#34;;\r………\rgpio_pwm {\rcompatible = \u0026#34;gpio-pwm\u0026#34;;\rstatus = \u0026#34;okay\u0026#34;;\rpinctrl-names = \u0026#34;default\u0026#34;;\rpinctrl-0 = \u0026lt;\u0026amp;pinctrl_gpio_pwm\u0026gt;;\rgpios = \u0026lt;\u0026amp;gpiog 1 GPIO_ACTIVE_LOW\u0026gt;,\r\u0026lt;\u0026amp;gpiog 2 GPIO_ACTIVE_LOW\u0026gt;; };\r………\r};\r/* 2. Add module pin configuration to device tree\u0026#39;s pinctl as below */\r\u0026amp;pinctrl {\r………\rgpio_pwm {\rpinctrl_gpio_pwm: gpio_pwmgrp{\rnuvoton,pins =\r\u0026lt;SYS_GPG_MFPL_PG1MFP_GPIO \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPG_MFPL_PG2MFP_GPIO \u0026amp;pcfg_default\u0026gt;;\r};\t};\r……… gpio-pwm 的Driver gpio-pwm.c #include \u0026lt;linux/module.h\u0026gt;\r#include \u0026lt;linux/kernel.h\u0026gt;\r#include \u0026lt;linux/init.h\u0026gt;\r#include \u0026lt;linux/slab.h\u0026gt;\r#include \u0026lt;linux/timer.h\u0026gt;\r#include \u0026lt;linux/sched.h\u0026gt;\r#include \u0026lt;linux/reboot.h\u0026gt;\r#include \u0026lt;linux/pwm.h\u0026gt;\r#include \u0026lt;linux/gpio.h\u0026gt;\r#include \u0026lt;linux/hrtimer.h\u0026gt;\r#include \u0026lt;linux/platform_device.h\u0026gt;\r#include \u0026lt;linux/of.h\u0026gt;\r#include \u0026lt;linux/of_platform.h\u0026gt;\r#include \u0026lt;linux/of_gpio.h\u0026gt;\r#include \u0026#34;gpio_pwm.h\u0026#34;\r#define GPIO_STATE_DEFAULT 0\rstruct gpio_pwm_driver_data {\runsigned int gpio;\rbool gpio_state;\rstruct pwm_device *pwm_dev;\rbool pwm_enable;\rbool pwm_requset; struct hrtimer timer;\rstruct mutex lock;\r};\rstruct gpio_pwm_chip {\rstruct pwm_chip chip;\rint gpio_nums;\rstruct gpio_pwm_driver_data gpio_pwm_drv_data[];\r};\rstatic enum hrtimer_restart gpio_pwm_timer_fun(struct hrtimer *data)\r{\rint gpio_pwm_hi_time = 0;\rint gpio_pwm_lo_time = 0;\rint gpio_keep_time = 0;\rstruct gpio_pwm_driver_data *gpio_pwm_drv = container_of(data, struct gpio_pwm_driver_data, timer);\rstruct pwm_device *pwm_dev = gpio_pwm_drv-\u0026gt;pwm_dev;\rgpio_pwm_hi_time = pwm_dev-\u0026gt;state.duty_cycle;\rgpio_pwm_lo_time = pwm_dev-\u0026gt;state.period - pwm_dev-\u0026gt;state.duty_cycle;\rif(gpio_pwm_drv-\u0026gt;gpio_state == 0) {\rgpio_keep_time = gpio_pwm_hi_time;\r} else {\rgpio_keep_time = gpio_pwm_lo_time;\r}\rgpio_pwm_drv-\u0026gt;gpio_state ^= 0x01;\rgpio_set_value(gpio_pwm_drv-\u0026gt;gpio, gpio_pwm_drv-\u0026gt;gpio_state);\rhrtimer_forward_now(\u0026amp;gpio_pwm_drv-\u0026gt;timer, ns_to_ktime(gpio_keep_time));\rreturn HRTIMER_RESTART;\r}\rstatic int gpio_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)\r{\rstruct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);\rstruct gpio_pwm_driver_data *gpio_pwm_drv = \u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[pwm-\u0026gt;hwpwm]);\rint ret = 0;\rret = gpio_request_one(gpio_pwm_drv-\u0026gt;gpio, GPIOF_DIR_OUT, pwm-\u0026gt;label);\rif (ret == 0) {\rgpio_pwm_drv-\u0026gt;gpio_state = GPIO_STATE_DEFAULT;\rgpio_set_value(gpio_pwm_drv-\u0026gt;gpio, gpio_pwm_drv-\u0026gt;gpio_state);\rgpio_pwm_drv-\u0026gt;pwm_requset = 1;\r}\rreturn ret;\r}\rstatic void gpio_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)\r{\rstruct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);\rstruct gpio_pwm_driver_data *gpio_pwm_drv = \u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[pwm-\u0026gt;hwpwm]);\rint i;\rmutex_lock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\rif(gpio_pwm_drv-\u0026gt;pwm_enable) {\rhrtimer_cancel(\u0026amp;gpio_pwm_drv-\u0026gt;timer);\rgpio_pwm_drv-\u0026gt;pwm_enable = false;\r}\rmutex_unlock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\rfor(i=0; i \u0026lt; pwm_chip_ptr-\u0026gt;gpio_nums; i++) {\rif (gpio_pwm_drv-\u0026gt;pwm_requset == 1) { gpio_free(gpio_pwm_drv-\u0026gt;gpio);\r}\r}\r}\rstatic int gpio_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)\r{\rstruct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);\rstruct gpio_pwm_driver_data *gpio_pwm_drv = \u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[pwm-\u0026gt;hwpwm]);\rmutex_lock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\rif(!gpio_pwm_drv-\u0026gt;pwm_enable) {\rhrtimer_init(\u0026amp;gpio_pwm_drv-\u0026gt;timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);\rgpio_pwm_drv-\u0026gt;timer.function = gpio_pwm_timer_fun;\rgpio_pwm_drv-\u0026gt;pwm_enable = true;\r}\rmutex_unlock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\rhrtimer_start(\u0026amp;gpio_pwm_drv-\u0026gt;timer, ktime_add_ns(ktime_get(), pwm-\u0026gt;state.duty_cycle), HRTIMER_MODE_ABS);\rreturn 0;\r}\rstatic int gpio_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns)\r{\rpwm-\u0026gt;state.period = period_ns;\rpwm-\u0026gt;state.duty_cycle = duty_ns;\rreturn 0;\r}\rstatic void gpio_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)\r{\rstruct gpio_pwm_chip *pwm_chip_ptr = container_of(chip, struct gpio_pwm_chip, chip);\rstruct gpio_pwm_driver_data * gpio_pwm_drv = \u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[pwm-\u0026gt;hwpwm]);\rmutex_lock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\rif(gpio_pwm_drv-\u0026gt;pwm_enable) {\rhrtimer_cancel(\u0026amp;gpio_pwm_drv-\u0026gt;timer);\rgpio_pwm_drv-\u0026gt;pwm_enable = false;\r}\rmutex_unlock(\u0026amp;gpio_pwm_drv-\u0026gt;lock);\r}\rstatic struct pwm_ops gpio_pwm_ops = {\r.request = gpio_pwm_request,\r.free = gpio_pwm_free,\r.enable = gpio_pwm_enable,\r.disable = gpio_pwm_disable,\r.config = gpio_pwm_config,\r.owner = THIS_MODULE,\r};\r#ifdef CONFIG_OF\rstatic const struct of_device_id of_gpio_pwm_match[] = {\r{ .compatible = \u0026#34;gpio-pwm\u0026#34;, },\r{},\r};\r#endif\rstatic struct gpio_pwm_chip *gpio_pwmparse_dt(struct device *dev)\r{\rconst struct of_device_id *of_id = of_match_device(of_gpio_pwm_match, dev);\rstruct device_node *np = dev-\u0026gt;of_node;\renum of_gpio_flags flags;\rstruct gpio_pwm_chip *pwm_chip_ptr;\rint gpio_nums;\rint i;\rint err;\rif (!of_id || !np)\rreturn NULL;\rgpio_nums = of_gpio_count(np);\rif (!gpio_nums) return ERR_PTR(-ENODEV); printk(\u0026#34;gpio_nums = %d\\n\u0026#34;, gpio_nums);\rpwm_chip_ptr = devm_kzalloc(dev, sizeof(struct gpio_pwm_chip) + (gpio_nums * sizeof(struct gpio_pwm_driver_data)), GFP_KERNEL);\rif (!pwm_chip_ptr)\rreturn ERR_PTR(-ENOMEM);\rpwm_chip_ptr-\u0026gt;gpio_nums = gpio_nums;\rfor(i = 0; i \u0026lt; gpio_nums; i++) {\rpwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].gpio = of_get_gpio_flags(np, i, \u0026amp;flags);\rmutex_init(\u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].lock));\rpwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].pwm_enable = false;\rprintk(\u0026#34;gpio=%d\\n\u0026#34;, pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].gpio);\r}\rerr = of_property_read_u32(np, \u0026#34;base\u0026#34;, \u0026amp;pwm_chip_ptr-\u0026gt;chip.base);\rif (err)\rpwm_chip_ptr-\u0026gt;chip.base = 0x20;\rreturn pwm_chip_ptr;\r}\rstatic int gpio_pwm_probe(struct platform_device *pdev)\r{\rstruct device *dev = \u0026amp;pdev-\u0026gt;dev;\rstruct gpio_pwm_platform_data *pdata = (struct gpio_pwm_platform_data *)dev_get_platdata(dev);\rstruct gpio_pwm_chip *pwm_chip_ptr = NULL;\rint i = 0;\rint ret = 0;\rif (!pdata) {\rprintk(\u0026#34;probe dt\\n\u0026#34;);\rpwm_chip_ptr = gpio_pwmparse_dt(dev);\rif (IS_ERR(pwm_chip_ptr))\rreturn PTR_ERR(pwm_chip_ptr);\rif (!pwm_chip_ptr) {\rdev_err(dev, \u0026#34;pwm gpio missing platform data\\n\u0026#34;);\rreturn -EINVAL;\r}\r} else {\rpwm_chip_ptr = devm_kzalloc(\u0026amp;pdev-\u0026gt;dev, sizeof(struct gpio_pwm_chip) + (pdata-\u0026gt;gpio_nums * sizeof(struct gpio_pwm_driver_data)), GFP_KERNEL);\rif(pwm_chip_ptr == NULL)\rreturn -ENOMEM;\rpwm_chip_ptr-\u0026gt;gpio_nums = pdata-\u0026gt;gpio_nums;\rfor(i=0; i \u0026lt; pdata-\u0026gt;gpio_nums; i++) {\rpwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].gpio = pdata-\u0026gt;gpios[i];\rmutex_init(\u0026amp;(pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].lock));\rpwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].pwm_enable = false;\rprintk(\u0026#34;gpio-%d\\n\u0026#34;,pwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].gpio);\r}\rpwm_chip_ptr-\u0026gt;chip.base = pdata-\u0026gt;pwm_chip_idx;\rprintk(\u0026#34;pwm_chip_idx=%d\\n\u0026#34;, pdata-\u0026gt;pwm_chip_idx);\r}\rpwm_chip_ptr-\u0026gt;chip.npwm = pwm_chip_ptr-\u0026gt;gpio_nums;\rpwm_chip_ptr-\u0026gt;chip.ops = \u0026amp;gpio_pwm_ops;\rpwm_chip_ptr-\u0026gt;chip.dev = \u0026amp;pdev-\u0026gt;dev;\r#ifdef CONFIG_OF pwm_chip_ptr-\u0026gt;chip.dev-\u0026gt;of_node = pdev-\u0026gt;dev.of_node;\r#endif\rret = pwmchip_add(\u0026amp;pwm_chip_ptr-\u0026gt;chip);\rif(ret) {\rreturn ret;\r}\rfor(i = 0; i \u0026lt; pwm_chip_ptr-\u0026gt;gpio_nums; i++) {\rpwm_chip_ptr-\u0026gt;gpio_pwm_drv_data[i].pwm_dev = \u0026amp;pwm_chip_ptr-\u0026gt;chip.pwms[i];\r}\rplatform_set_drvdata(pdev, pwm_chip_ptr);\rreturn 0;\r}\rstatic int gpio_pwm_remove(struct platform_device *pdev)\r{\rstruct gpio_pwm_chip *pwm_chip_ptr = platform_get_drvdata(pdev);\rpwmchip_remove(\u0026amp;pwm_chip_ptr-\u0026gt;chip);\rplatform_set_drvdata(pdev, NULL);\rreturn 0;\r}\rstatic struct platform_driver gpio_pwm_driver = {\r.probe\t= gpio_pwm_probe,\r.remove\t= gpio_pwm_remove,\r.driver\t= {\r.name\t= \u0026#34;gpio-pwm\u0026#34;,\r.owner\t= THIS_MODULE,\r.of_match_table = of_match_ptr(of_gpio_pwm_match),\r},\r};\rmodule_platform_driver(gpio_pwm_driver);\rMODULE_AUTHOR(\u0026#34;nuvoton porting\u0026#34;);\rMODULE_DESCRIPTION(\u0026#34;gpio pwm chip driver\u0026#34;);\rMODULE_LICENSE(\u0026#34;GPL\u0026#34;); gpio-pwm.h #ifndef __GPIO_PWM_H\r#define __GPIO_PWM_H\r#include \u0026lt;linux/kernel.h\u0026gt;\r#include \u0026lt;linux/init.h\u0026gt;\r#include \u0026lt;linux/slab.h\u0026gt;\rstruct gpio_pwm_platform_data {\rint pwm_chip_idx;\rint gpio_nums;\runsigned int *gpios;\r};\r#endif MakeFile to Build gpio-pwm.ko 下面要注意 :\n在docker裡面 make LINUX_DIR 要擺已經Build過的 kernel 位置 aarch64 tool chain 要有 : source /usr/local/oecore-x86_64/environment-setup-aarch64-poky-linux PWD := $(shell pwd)\robj-m += gpio-pwm.o\r.PHONY: all clean\rCOMPILE=aarch64-poky-linux-\rLINUX_DIR=../tmp-glibc/work/numaker_som_ma35d16a81-poky-linux/linux-ma35d1/5.10.140-r0/build\rall:\rmake ARCH=arm64 CROSS_COMPILE=$(COMPILE) -C $(LINUX_DIR) M=$(PWD) modules\r結構應該長得像下面的資料夾 實體接線 AP 層控制 GPIO PWM執行輸出與佔空比設定\nExport PWM\necho 0 \u0026gt; /sys/class/pwm/pwmchip32/export PWM 週期設定,單位為ns, gpioi12 輸出頻率為 100 HZ\necho 10000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/period PWM 佔空比設定, 以下設定佔空比為 0.5\necho 5000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle PWM 使能輸出\necho 1 \u0026gt;/sys/class/pwm/pwmchip32/pwm0/enable echo 0 會 export ,這個時候,會出現pwm0的節點 echo 0 \u0026gt; /sys/class/pwm/pwmchip32/export\recho 20000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/period\recho 1000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle\recho 2000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle\recho 1 \u0026gt;/sys/class/pwm/pwmchip32/pwm0/enable PWM1 也是差不多的方式 echo 1 export ,這個時候會出現pwm1的節點\necho 1 \u0026gt; /sys/class/pwm/pwmchip32/export\recho 20000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm1/period\recho 1000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm1/duty_cycle\recho 2000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm1/duty_cycle\recho 1 \u0026gt;/sys/class/pwm/pwmchip32/pwm1/enable SG90 伺服馬達說明 小巧輕便且輸出功率高。伺服馬達可以大約旋轉180度(每個方向90度),並且與標準的伺服馬達一樣工作,只是體積更小。\n您可以使用任何伺服馬達的程式碼、硬體或庫來控制這些伺服馬達。\n對於初學者來說非常適合,他們想要讓東西移動,而不需要建立帶有反饋和齒輪箱的馬達控制器,尤其是因為它可以放在狹小的空間中。\n位置 \u0026ldquo;0\u0026rdquo;(1.5 毫秒脈衝)代表中間位置。\n位置 \u0026ldquo;90\u0026rdquo;(約 2 毫秒脈衝)代表向右極限。\n位置 \u0026ldquo;-90\u0026rdquo;(約 1 毫秒脈衝)代表向左極限。\n簡單來說,這段描述了 PWM 信號的位置與對應的角度之間的關係。位置 \u0026ldquo;0\u0026rdquo; 代表中間位置,位置 \u0026ldquo;90\u0026rdquo; 代表完全向右轉的極限,而位置 \u0026ldquo;-90\u0026rdquo; 則代表完全向左轉的極限。這些位置對應於 PWM 脈衝的持續時間,可以控制舵機或其他類似裝置的運動位置。\n注意 100 Hz 是 :\necho 10000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/period\nDatashet 要 50 Hz\n要寫成以下才會是50 Hz:\necho 20000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/period 1 ms 的duty 我要給以下:\necho 1000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle\n1.5 ms 的duty 我要給以下:\necho 1500000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle\n2 ms 的duty 我要給以下:\necho 2000000 \u0026gt; /sys/class/pwm/pwmchip32/pwm0/duty_cycle\n","permalink":"https://weizongchen.github.io/blog/ma35d1_pwm_control/","tags":["MA35D1"],"title":"MA35D1 Control "},{"categories":["心得"],"contents":" 控制 LED 0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他\nuint32_t* ptr_mode;\rptr_mode = (uint32_t*)(0x40004000 + 0x1c0);\r*ptr_mode = 0x00000100;\ruint32_t* ptr_value;\rptr_value = (uint32_t*)(0x40004000 + 0x1c8);\r*ptr_value = 0xFFFFFFEF; 負源觸發\r補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示:\n所以新唐寫法 uint32_t* ptr_mode;\rptr_mode = (uint32_t*)(0x40004000 + 0x1c0);\r*ptr_mode = 0x00000100;\ruint32_t* ptr_value;\rptr_value = (uint32_t*)(0x40004000 + 0x1c8);\r*ptr_value = 0xFFFFFFEF;\r//----------------和下面寫法一樣-----------------------------------\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rGPIO_SetMode(PH, BIT5, GPIO_MODE_OUTPUT);\rGPIO_SetMode(PH, BIT6, GPIO_MODE_OUTPUT);\rLED_YELLOW = 0;//PH5\rLED_RED = 1; //PH4\rLED_GREEN = 0; //PH6\r控制 BTN 先用 Keil 的Tool 看一下 按下Button 的狀態\nGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rGPIO_SetMode(PH, BIT5, GPIO_MODE_OUTPUT);\rGPIO_SetMode(PH, BIT6, GPIO_MODE_OUTPUT);\rLED_YELLOW = 1;//PH5\rLED_RED = 1; //PH4\rLED_GREEN = 1; //PH6\rGPIO_SetMode(PH, BIT0, GPIO_MODE_INPUT);\r/* Got no where to go, just loop forever */\rwhile(1) {\rif(PH0 == 0){\rLED_RED = 0; //PH4\r}\rif(PH0 == 1){\rLED_RED = 1; //PH4\r}\r}\r","permalink":"https://weizongchen.github.io/blog/m460_level0/","tags":["Cortex M4"],"title":" M460 Level0 說明"},{"categories":["安裝步驟文件"],"contents":"yocto添加網路上現有的meta layer 查找菜譜 可以點下面連結去首頁\nOpenEmbedded Layer Index\n也可以直接點下面是 Tensorflow Lite 的資源\nmeta-neural-network\n如下圖,目前是tensorflow2.6.0版本( dunfell )\n找到Source Code 如下圖,點擊 web repo 會到Github的頁面\n目前是dunfell ,要改成dunfell的source Download Source Code 在 bitbake 裡面下以下指令去Download Code git clone -b dunfell https://github.com/nnstreamer/meta-neural-network.git 下載成功的畫面 裡面內容大概長成下面:\n在 bblayers.conf 加入 meta-neural-network 在 local.conf 加入 tensorflow-lite 編譯一次Image 編譯一次nvt-image-qt5的Image , bitbake -s | grep tensorflow-lite 就應該可以看到tensorflow lite 的 library 被加到Image 裡面。\n過程當中,Tensorflow lite 的資源裡面,會發現 XNNPACK 相關的 error 一直跑出來 Debug 後 , 發現要 -DTFLITE_ENABLE_XNNPACK=off , 把XNNPACK給off掉,如下圖所示\n直接找到他把它關掉 EXTRA_OECMAKE = \u0026#34;\\\r-DTFLITE_ENABLE_XNNPACK=off \\\r-DTFLITE_ENABLE_RUY=on \\\r-DTFLITE_ENABLE_GPU=off \\\r${S}/tensorflow/lite/ \\ Tensorflow-Lite 加入成功 加入 VNC 相關的 Library 下面這幾個library 是跟tigervnc相關:\ngtk+3 、 tigervnc 、 xauth 、 xkbcomp 、 xsetroot 、 xterm 、 twm\nMACHINE ??= \u0026#39;numaker-som-ma35d16a81\u0026#39;\rDISTRO ?= \u0026#39;nvt-ma35d1-directfb\u0026#39;\rPACKAGE_CLASSES ?= \u0026#34;package_rpm\u0026#34;\rEXTRA_IMAGE_FEATURES ?= \u0026#34;debug-tweaks\u0026#34;\rUSER_CLASSES ?= \u0026#34;buildstats image-mklibs image-prelink\u0026#34;\rPATCHRESOLVE = \u0026#34;noop\u0026#34;\rBB_DISKMON_DIRS ??= \u0026#34;\\\rSTOPTASKS,${TMPDIR},1G,100K \\\rSTOPTASKS,${DL_DIR},1G,100K \\\rSTOPTASKS,${SSTATE_DIR},1G,100K \\\rSTOPTASKS,/tmp,100M,100K \\\rABORT,${TMPDIR},100M,1K \\\rABORT,${DL_DIR},100M,1K \\\rABORT,${SSTATE_DIR},100M,1K \\\rABORT,/tmp,10M,1K\u0026#34;\rPACKAGECONFIG_append_pn-qemu-system-native = \u0026#34; sdl\u0026#34;\rCONF_VERSION = \u0026#34;1\u0026#34;\rMACHINE_FEATURES_append = \u0026#34; optee \u0026#34;\rIMAGE_INSTALL_append += \u0026#34; opencv\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; tensorflow-lite\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; gtk+3\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; tigervnc\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xauth\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xkbcomp\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xsetroot\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; xterm\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; twm\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; cmake\u0026#34;\rDL_DIR ?= \u0026#34;${BSPDIR}/downloads/\u0026#34; 編譯 nvt-image-qt5 的 Image 時候會看到 下面 x11 錯誤\n點開下面的 nvt-ma35d1-directfb.conf 檔案,加入x11 的內容就可以了\n路徑:\r/home/nuvoton/yocto/sources/meta-ma35d1/conf/distro\r# Nuvoton DISTRO for the FrameBuffer graphical backend.\rinclude conf/distro/include/nvt-base.inc\rDISTRO = \u0026#34;nvt-ma35d1-directfb\u0026#34;\r# Remove conflicting backends.\rDISTRO_FEATURES_append += \u0026#34; \u0026#34;\rDISTRO_FEATURES_append += \u0026#34; x11 \u0026#34; 再 bitbake nvt-image-qt5 一次,就可以全部都加進去\n","permalink":"https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/","tags":["Ma35d1"],"title":" 將Tensorflow Lite Library加到MA35D1的Yocto中 "},{"categories":["說明文件"],"contents":"Open local.conf nuvoton@84d536ecc45d:~/shared/yocto/build$ vim conf/local.conf For example : add pip3 and devmem2 CORE_IMAGE_EXTRA_INSTALL += \u0026ldquo;devmem2\u0026rdquo;\nIMAGE_INSTALL_append += \u0026quot; python3-pip\u0026quot;\nMACHINE ??= \u0026#39;numaker-iot-ma35d16f90\u0026#39;\rDISTRO ?= \u0026#39;nvt-ma35d1-directfb\u0026#39;\rPACKAGE_CLASSES ?= \u0026#34;package_rpm\u0026#34;\rEXTRA_IMAGE_FEATURES ?= \u0026#34;debug-tweaks\u0026#34;\rUSER_CLASSES ?= \u0026#34;buildstats image-mklibs image-prelink\u0026#34;\rPATCHRESOLVE = \u0026#34;noop\u0026#34;\rBB_DISKMON_DIRS ??= \u0026#34;\\\rSTOPTASKS,${TMPDIR},1G,100K \\\rSTOPTASKS,${DL_DIR},1G,100K \\\rSTOPTASKS,${SSTATE_DIR},1G,100K \\\rSTOPTASKS,/tmp,100M,100K \\\rABORT,${TMPDIR},100M,1K \\\rABORT,${DL_DIR},100M,1K \\\rABORT,${SSTATE_DIR},100M,1K \\\rABORT,/tmp,10M,1K\u0026#34;\rPACKAGECONFIG_append_pn-qemu-system-native = \u0026#34; sdl\u0026#34;\rCONF_VERSION = \u0026#34;1\u0026#34;\rMACHINE_FEATURES_append = \u0026#34; optee\u0026#34;\rCORE_IMAGE_EXTRA_INSTALL += \u0026#34;devmem2\u0026#34;\rIMAGE_INSTALL_append += \u0026#34; python3-pip\u0026#34;\rDL_DIR ?= \u0026#34;${BSPDIR}/downloads/\u0026#34; Search package nuvoton@84d536ecc45d:~/shared/yocto/build$ bitbake -s | grep pip\nlibpipeline :1.5.2-r0 nativesdk-python3-pip :20.0.2-r0 pipewire :0.3.1-r0 pipewire-0.2 :0.2.7-r0 python3-pip :20.0.2-r0 python3-pip-native :20.0.2-r0 ","permalink":"https://weizongchen.github.io/blog/ma35d1_extra_package_yocto/","tags":["MA35D1"],"title":"MA35D1 extra package in Yocto project after the image is built"},{"categories":["說明文件"],"contents":"devmem2 Tool read register devmem2 0x40600014 TRM SPI Status Register (SPIx_STATUS) write 32bit to register devmem2 0x40600014 w 0x0058112 ","permalink":"https://weizongchen.github.io/blog/ma35d1_devmem2/","tags":["MA35D1"],"title":"MA35D1 devmem2 Read / Write memory address"},{"categories":["說明文件"],"contents":"MA35D1 QT startup path vi /etc/profile.d/qt5-env.sh You can write that you want to auto execute command or script here. Here, I setup a IP and a gpio driver when startup the A35. #define a new path for the font in qt5\rexport QT_QPA_FONTDIR=/usr/share/fonts/truetype\rexport XDG_RUNTIME_DIR=\u0026#34;/tmp/runtime-root\u0026#34;\rexport QT_QPA_PLATFORM=\u0026#34;linuxfb\u0026#34;\rexport QT_QPA_FB_TSLIB=1\rexport TSLIB_CONSOLEDEVICE=none\rifconfig eth1 192.168.11.6 netmask 255.255.255.0\rinsmod ~/gpio-capture.ko SCP a file test sudo scp spidev_test3 root@192.168.11.6:/home/root/\n","permalink":"https://weizongchen.github.io/blog/ma35d1_startup_execute/","tags":["MA35D1"],"title":"MA35D1 開機啟動位置"},{"categories":["說明文件"],"contents":"MA35D1 SPI Device Tree 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi\nspi0: spi@40600000 {\rcompatible = \u0026#34;nuvoton,ma35d1-spi\u0026#34;;\rreg = \u0026lt;0x0 0x40600000 0x0 0x10000\u0026gt;;\rinterrupts = \u0026lt;GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH\u0026gt;;\rclocks = \u0026lt;\u0026amp;clk SPI0_GATE\u0026gt;;\rdmas = \u0026lt;\u0026amp;pdma1 4\u0026gt;,\u0026lt;\u0026amp;pdma1 5\u0026gt;;\rdma-names = \u0026#34;tx\u0026#34;,\u0026#34;rx\u0026#34;;\rpdma_reqsel_tx = \u0026lt;60\u0026gt;;\rpdma_reqsel_rx = \u0026lt;61\u0026gt;;\ruse_pdma = \u0026lt;0\u0026gt;;\rnum_cs = \u0026lt;2\u0026gt;;\rlsb = \u0026lt;0\u0026gt;;\rsleep = \u0026lt;0\u0026gt;;\rtxbitlen = \u0026lt;8\u0026gt;;\rbus_num = \u0026lt;2\u0026gt;;\rspimode = \u0026lt;0\u0026gt;;\rmrxphase = \u0026lt;0\u0026gt;;\rspi-max-frequency = \u0026lt;10000000\u0026gt;;\rstatus = \u0026#34;disabled\u0026#34;;\r}; 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts\nCS = PG0\nCLK = PB9\nMOSI = PL14\nMISO =PL15\n使用PDMA 所以下面給1\n速度最高給12M (後面會蓋掉前面設定!)\n\u0026amp;spi0 {\rstatus = \u0026#34;okay\u0026#34;;\rpinctrl-names = \u0026#34;default\u0026#34;;\ruse_pdma = \u0026lt;1\u0026gt;;\rspi-max-frequency = \u0026lt;30000000\u0026gt;;\rpinctrl-0 = \u0026lt;\u0026amp;pinctrl_spi0\u0026gt;;\rspidev@0 {\rcompatible = \u0026#34;spidev\u0026#34;;\rreg = \u0026lt;0\u0026gt;;\rspi-max-frequency = \u0026lt;12000000\u0026gt;;\r};\r};\r\u0026amp;pinctrl {\rspi0 {\rpinctrl_spi0: spi0grp{\rnuvoton,pins =\r\u0026lt;SYS_GPG_MFPL_PG0MFP_SPI0_SS0 \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPB_MFPH_PB8MFP_SPI0_SS1 \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPB_MFPH_PB9MFP_SPI0_CLK \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPL_MFPH_PL14MFP_SPI0_MOSI \u0026amp;pcfg_default\u0026gt;,\r\u0026lt;SYS_GPL_MFPH_PL15MFP_SPI0_MISO \u0026amp;pcfg_default\u0026gt;;\r};\r};\r}; 電路圖 Linux Driver: 路徑 : ~/yocto/build/tmp-glibc/work-shared/numaker-iot-ma35d16f90/kernel-source/drivers/spi\nstatic int nuvoton_spi_data_xfer(struct nuvoton_spi *hw, const void *txbuf,\rvoid *rxbuf, unsigned int len)\r{\r...\r} Linux Application: 環境上預設並沒有開啟spidev (decice node for user)須經由以下流程開啟: APP: 採用NUC980的 app https://github.com/OpenNuvoton/NUC980_Linux_Applications/blob/master/demos/spi/spidev_test.c\nAPP Makefile .SUFFIXES : .x .o .c .s\rSTRIP := aarch64-poky-linux-strip\r#TARGET = spidev_test\r#SRCS := spidev_test.c\rall:\r#\t$(CC) $(SRCS) -o $(TARGET) clean:\rrm -f *.o\rrm -f *.x\rrm -f *.flat\rrm -f *.map\rrm -f temp\rrm -f *.img\rrm -f $(TARGET)\rrm -f *.gdb Application 執行結果 ","permalink":"https://weizongchen.github.io/blog/ma35d1_spi/","tags":["MA35D1"],"title":"MA35D1 IoT 的 SPI 介面使用"},{"categories":["說明文件"],"contents":"跟新唐過去Cortex® M4 的 Feature 不一樣的地方 M4 speed 調升至 180 MHz 本章的重點,SRAM 有 128KB 以及 可以控制DDR 384KB Support Peripheral 1. UART、I2C、I2S、PDMA、SPI、etc… NuLink2Me Debug Wormhole Linux Setup Device Tree 查看各個 memory 設定 這裡是設定 Memory 的起始位置 8000 0000\n注意 Reserved-memory :\n在這裡,我們為不同的功能保留了三個塊。 其中一個地方是 rproc 函數,它用在 M4 DRAM 上(384KB)\n(0x60000 = 384 KB)\nDevice Tree 設定 以設定UART16 為例\n_S 就是代表指定給A35\n_SUBM 代表指定給M4\nCompile and make Image Compile the Linux kernel.\r$ bitbake linux-ma35d1 -C compile\rCompile the TF-A.\r$ bitbake tf-a-ma35d1 -C compile\rBuild-up Image.\r$ bitbake nvt-image-qt5 –c cleanall \u0026amp;\u0026amp; bitbake nvt-image-qt5\rBurn-in Image into SD card.\r$ sudo dd if=core-image-minimal-xxxxx.rootfs.sdcard of=/dev/sdbx 在 Keil IDE 設定 memory 使用空間 上圖中我們可以看到,RO data 配置位置在 0x0 ~ 0x1FFFF ,一共有128KB SRAM\nRW data 配置位置在 0x80040000 大小為0x1FFFF ,一共有128KB 的DDR\n我寫一個 c code 在 DDR memory 使用空間 在 .c 的右鍵 option ,可以指定要把這個 function 放到 DDR 去\n在 map file 中可以看到 memtest 已經在DDR 的 使用空間了\n使用 scatter file 去直接指定 哪個 上圖可以看到 紅色 是代表記憶體區間\n0x00000000 ~ 0x0001FFFF 是SRAM 的空間\n這裡的寫法可以直接打開 map file ,copy paste 一模一樣的名子就可以了,\n例如 : startup_ma35d1_rtp.o(STACK, HEAP) 這個我放到SRAM\npdm_converter.o(.bss) 我放到DRAM\n以此類推\n所以上圖可以知道,我把需要比較快速算完的data 放到SRAM\n比較不需要速度的資料我放到 DRAM\n","permalink":"https://weizongchen.github.io/blog/ma35d1_rtp_memory/","tags":["Cortex M4","MA35D1"],"title":"解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法"},{"categories":["說明文件"],"contents":"PC 接好onboard的 nulink2 然後設定 Keil 的 option 這邊可以看到上圖我們開啟了412KB 的 flash 要使用\n在程式的部分,我open 一個 fmc\n寫一個pattern : 0x5A5A5A5A\n然後下面有兩個API可以參考(FMC_Write 、 FMC_Read),其他可以去看新唐的fmc.c 參考。\n可以看到,我們用ICP查詢片上的flash 有0x5A5A5A5A 的資料被寫入\nFMC_Erase(u32Addr) 一次會Erase 4096 個 byte uTemp 一次要寫入 4 byte 的資料\nelse if( (i*4) == 4096)\n因為一次會寫入4 byte,所以當i=1024時,寫買了需要Erase新的4096 byte 空間\n","permalink":"https://weizongchen.github.io/blog/m4_fmc/","tags":["Cortex M4"],"title":"M4 把資料寫進 FMC的方法"},{"categories":["說明文件"],"contents":"Raspberry pi 3 Linux Device Driver\n下載上課用Raspberry Pi image檔 (Linux 核心 4.14.x )(已包含上課用的範例程式 最新版本請再次下載)\nRaspberry Pi image\n範例程式\n登入帳號 派 密碼: 樹莓派\n程式目錄結構\ncd /home/pi/LinuxDriver_Data_20191001\n├── Code\n├── 01_LED\r├── 02_BTN_LED\r├── ....\r├── driver-example\r├── hello\r├── image_Readme.txt \u0026lt;== 請參考此檔案說明\n└── Sch\u0026amp;DataSheet\n說明\n1.範例程式碼是基於Linux 核心 4.14.x 版本。提醒: 來自核心所提供的Driver Code, 大部份都位於 linux-raspberrypi-kernel_1.20190401-1/drivers/bcma , 例如 driver_gpio.c (舊版是 arch/mach-bcm2708/bcm2708_gpio.c )\n2.講師講解內容不限於Raspberry Pi 開發套件包,惟能實際硬體實驗的部份會受限於Raspberry Pi 開發套件包所提供的硬體。 Raspberry Pi 開發套件包\n3.Linux Driver 學習須知\n如何執行第一個LED範例\n如何使用make menuconfig\nPi 新手教學(零) \u0026ndash;艾鍗Raspberry Pi I/O Shield 規格介紹: https://goo.gl/eg1JMh\nPi 新手教學(一) \u0026ndash; 使用Wind32 Disk Imager 燒錄卬象檔: https://goo.gl/bsxy66\nPi 新手教學(二) \u0026ndash;如何使用UART Console 登入Raspberry Pi: https://goo.gl/ffJ6aP\nPi 新手教學(三) \u0026ndash;使用SSH登入Raspberry Pi: https://goo.gl/KPGco1\n下載Pi子卡Datasheet及電路圖: https://goo.gl/FoDXM1\n","permalink":"https://weizongchen.github.io/blog/pi3ldd/","tags":["Cortex A"],"title":"pi3ldd"},{"categories":["說明文件"],"contents":"\n原因是這裡可能空白 至少要選一個\n","permalink":"https://weizongchen.github.io/blog/error_flash_download_failed_cortex-m0/","tags":["Tool"],"title":"Error:Flash Download failed - Cortex-M0"},{"categories":["說明文件"],"contents":"開啟 Option Define 好 DEBUG_ENABLE_SEMIHOST 在 Debug Mode 的時候打開 UART #1 可以看到 UART0 的輸出 ","permalink":"https://weizongchen.github.io/blog/debug_enable_semihost/","tags":["Tool"],"title":"SemiHost 使用方法"},{"categories":["說明文件"],"contents":"找M460開發版的2根空的 I2C 由上圖可以知道 I2C Pin角選\nPA5 SCL 板上 PIN75\nPA4 SDA 板上 PIN76\nBSP 包 直接用 I2C_MultiBytes_Master /* Slave address */\ng_u8DeviceAddr = 0x46;\nBH1750的 ID 是 0x46 (包含第8個 bit)\nI2C_WriteByte(I2C0, device ID (不包含第8個bit), 要傳的命令)\nI2C_WriteByte(I2C0, 0x23, 0x10);\n這裡命令 0x10 是參考下圖\n//I2C_ReadByte(I2C0, device ID (不包含第8個bit));\n//r = I2C_ReadByte(I2C0, 0x23);\n讀到幾個byte = I2C_ReadMultiBytes(I2C0, device ID 不包含第8個bit, 放個陣列ReadData 會存到回到ReadData, 讀取長度len = 2 )\nreceive_byte = I2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\nLA 量測結果 我MCU發送 0x46 (第8bit 值0 方向 write) ID ,並給值 0x10 給 Device\n0x46+1 (第8bit 值1 方向 read)Device 回 MCU 2個值 : 0x00 0xC5\n實體接線 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief\r* Show how to set I2C use Multi bytes API Read and Write data to Slave.\r* Needs to work with I2C_Slave sample code.\r* @copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r*****************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define PLL_CLOCK 192000000\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rvolatile uint8_t g_u8DeviceAddr;\rvolatile uint8_t g_au8MstTxData[3];\rvolatile uint8_t g_u8MstRxData;\rvolatile uint8_t g_u8MstDataLen;\rvolatile uint8_t g_u8MstEndFlag = 0;\rtypedef void (*I2C_FUNC)(uint32_t u32Status);\rvolatile static I2C_FUNC s_I2C0HandlerFn = NULL;\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/* Enable I2C0 peripheral clock */\rCLK_EnableModuleClock(I2C0_MODULE);\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();;\r/* Set I2C0 multi-function pins */\rSET_I2C0_SDA_PA4();\rSET_I2C0_SCL_PA5();\r/* I2C pin enable schmitt trigger */\rPA-\u0026gt;SMTEN |= GPIO_SMTEN_SMTEN4_Msk | GPIO_SMTEN_SMTEN5_Msk;\r}\rvoid I2C0_Init(void)\r{\r/* Open I2C module and set bus clock */\rI2C_Open(I2C0, 100000);\r/* Get I2C0 Bus Clock */\rprintf(\u0026#34;I2C clock %d Hz\\n\u0026#34;, I2C_GetBusClockFreq(I2C0));\r}\rvoid I2C0_Close(void)\r{\r/* Disable I2C0 interrupt and clear corresponding NVIC bit */\rI2C_DisableInt(I2C0);\rNVIC_DisableIRQ(I2C0_IRQn);\r/* Disable I2C0 and close I2C0 clock */\rI2C_Close(I2C0);\rCLK_DisableModuleClock(I2C0_MODULE);\r}\rint32_t main(void)\r{\ruint32_t receive_byte;\ruint8_t ReadData[2];\ruint32_t Lux;\ruint32_t i;\ruint8_t txbuf[256] = {0}, rDataBuf[256] = {0};\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, IP clock and multi-function I/O. */\rSYS_Init();\r/* Configure UART0: 115200, 8-bit word, no parity bit, 1 stop bit. */\rUART_Open(UART0, 115200);\r#ifdef _PZ\r/* For palladium */\rUART0-\u0026gt;BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(153600, 38400);\r#endif\r/*\rThis sample code sets I2C bus clock to 100kHz. Then, Master accesses Slave with Multi Bytes Write\rand Multi Bytes Read operations, and check if the read data is equal to the programmed data.\r*/\rprintf(\u0026#34;+--------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| I2C Driver Sample Code for Multi Bytes Read/Write Test |\\n\u0026#34;);\rprintf(\u0026#34;| Needs to work with I2C_Slave sample code |\\n\u0026#34;);\rprintf(\u0026#34;| |\\n\u0026#34;);\rprintf(\u0026#34;| I2C Master (I2C0) \u0026lt;---\u0026gt; I2C Slave(I2C0) |\\n\u0026#34;);\rprintf(\u0026#34;| !! This sample code requires two borads to test !! |\\n\u0026#34;);\rprintf(\u0026#34;+--------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;\\n\u0026#34;);\r/* Init I2C0 */\rI2C0_Init();\r/* Slave address */\rg_u8DeviceAddr = 0x46;\rI2C_WriteByte(I2C0, 0x23, 0x10);\r//r = I2C_ReadByte(I2C0, 0x23);\rreceive_byte = I2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\rprintf(\u0026#34;receive_byte = %d \\n\u0026#34;, receive_byte);\rprintf(\u0026#34;ReadData[0] = %x \\n\u0026#34;, ReadData[0]);\rprintf(\u0026#34;ReadData[1] = %x \\n\u0026#34;, ReadData[1]);\rLux = ReadData[0] * 256 + ReadData[1];\rwhile(1)\r{\rI2C_ReadMultiBytes(I2C0, 0x23, ReadData, 2);\rLux = ReadData[0] * 256 + ReadData[1];\rprintf(\u0026#34;Lux = %d \\n\u0026#34;, Lux);\r}\r}\r/*** (C) COPYRIGHT 2021 Nuvoton Technology Corp. ***/ ","permalink":"https://weizongchen.github.io/blog/i2c_bh1750/","tags":["Cortex M4"],"title":"使用M460開發版的 I2C 去要 BH1750 照度計sensor的data"},{"categories":["說明文件"],"contents":"BSP EPWM 我是找 BSP 使用的 PWM PIN 角, 但還是用pinconfigure 看一下\n所以根據上圖以及BSP ,\nPWM1 的 Channel0\n會發訊號 給\nPWM1 的 Channel2\n查看開發版的電路圖 是哪兩根PIN EPWM_Capture BSP 的 console 量測邏輯分析儀 EPWM1 的 channel0 發 250 Hz pwm 訊號 30% duty\n/**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Capture the EPWM1 Channel 0 waveform by EPWM1 Channel 2.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r/*---------------------------------------------------------------------------------------------------------*/\r/* Macro, type and constant definitions */\r/*---------------------------------------------------------------------------------------------------------*/\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid CalPeriodTime(EPWM_T *EPWM, uint32_t u32Ch);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\r/*--------------------------------------------------------------------------------------*/\r/* Capture function to calculate the input waveform information */\r/* au32Count[4] : Keep the internal counter value when input signal rising / falling */\r/* happens */\r/* */\r/* time A B C D */\r/* ___ ___ ___ ___ ___ ___ ___ ___ */\r/* ____| |_| |_| |_| |_| |_| |_| |_| |_____ */\r/* index 0 1 2 3 */\r/* */\r/* The capture internal counter down count from 0x10000, and reload to 0x10000 after */\r/* input signal falling happens (Time B/C/D) */\r/*--------------------------------------------------------------------------------------*/\rvoid CalPeriodTime(EPWM_T *EPWM, uint32_t u32Ch)\r{\ruint16_t au16Count[4];\ruint32_t u32i;\ruint16_t u16RisingTime, u16FallingTime, u16HighPeriod, u16LowPeriod, u16TotalPeriod;\r/* Clear Capture Falling Indicator (Time A) */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH);\r/* Wait for Capture Falling Indicator */\rwhile((EPWM1-\u0026gt;CAPIF \u0026amp; EPWM_CAPIF_CFLIF2_Msk) == 0);\r/* Clear Capture Falling Indicator (Time B)*/\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH);\ru32i = 0;\rwhile(u32i \u0026lt; 4)\r{\r/* Wait for Capture Falling Indicator */\rwhile(EPWM_GetCaptureIntFlag(EPWM, u32Ch) \u0026lt; 2);\r/* Clear Capture Falling and Rising Indicator */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);\r/* Get Capture Falling Latch Counter Data */\rau16Count[u32i++] = (uint16_t)EPWM_GET_CAPTURE_FALLING_DATA(EPWM, u32Ch);\r/* Wait for Capture Rising Indicator */\rwhile(EPWM_GetCaptureIntFlag(EPWM, u32Ch) \u0026lt; 2);\r/* Clear Capture Rising Indicator */\rEPWM_ClearCaptureIntFlag(EPWM, u32Ch, EPWM_CAPTURE_INT_RISING_LATCH);\r/* Get Capture Rising Latch Counter Data */\rau16Count[u32i++] = (uint16_t)EPWM_GET_CAPTURE_RISING_DATA(EPWM, u32Ch);\r}\ru16RisingTime = au16Count[1];\ru16FallingTime = au16Count[0];\ru16HighPeriod = au16Count[1] - au16Count[2];\ru16LowPeriod = (uint16_t)(0x10000 - au16Count[1]);\ru16TotalPeriod = (uint16_t)(0x10000 - au16Count[2]);\rprintf(\u0026#34;\\nEPWM generate: \\nHigh Period=17141 ~ 17143, Low Period=39999 ~ 40001, Total Period=57141 ~ 57143\\n\u0026#34;);\rprintf(\u0026#34;\\nCapture Result: Rising Time = %d, Falling Time = %d \\nHigh Period = %d, Low Period = %d, Total Period = %d.\\n\\n\u0026#34;,\ru16RisingTime, u16FallingTime, u16HighPeriod, u16LowPeriod, u16TotalPeriod);\rif((u16HighPeriod \u0026lt; 17141) || (u16HighPeriod \u0026gt; 17143) || (u16LowPeriod \u0026lt; 39999) || (u16LowPeriod \u0026gt; 40001) || (u16TotalPeriod \u0026lt; 57141) || (u16TotalPeriod \u0026gt; 57143))\rprintf(\u0026#34;Capture Test Fail!!\\n\u0026#34;);\relse\rprintf(\u0026#34;Capture Test Pass!!\\n\u0026#34;);\r}\rvoid SYS_Init(void)\r{\r/* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */\rSET_XT1_OUT_PF2();\rSET_XT1_IN_PF3();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable HIRC and HXT clock */\rCLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk | CLK_PWRCTL_HXTEN_Msk);\r/* Wait for HIRC and HXT clock ready */\rCLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk | CLK_STATUS_HXTSTB_Msk);\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/* Enable EPWM1 module clock */\rCLK_EnableModuleClock(EPWM1_MODULE);\r/* Select EPWM1 module clock source */\rCLK_SetModuleClock(EPWM1_MODULE, CLK_CLKSEL2_EPWM1SEL_PCLK1, 0);\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r/* Set multi-function pin for EPWM */\rSET_EPWM1_CH0_PC5();\rSET_EPWM1_CH2_PC3();\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Init System, IP clock and multi-function I/O\rIn the end of SYS_Init() will issue SYS_LockReg()\rto lock protected register. If user want to write\rprotected register, please issue SYS_UnlockReg()\rto unlock protected register if necessary */\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, IP clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART to 115200-8n1 for print message */\rUART0_Init();\rprintf(\u0026#34;\\n\\nCPU @ %dHz(PLL@ %dHz)\\n\u0026#34;, SystemCoreClock, PllClock);\rprintf(\u0026#34;+------------------------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| EPWM Driver Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;| |\\n\u0026#34;);\rprintf(\u0026#34;+------------------------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34; This sample code will use EPWM1 channel 2 to capture\\n the signal from EPWM1 channel 0.\\n\u0026#34;);\rprintf(\u0026#34; I/O configuration:\\n\u0026#34;);\rprintf(\u0026#34; EPWM1 channel 2(PC.3) \u0026lt;--\u0026gt; EPWM1 channel 0(PC.5)\\n\\n\u0026#34;);\rprintf(\u0026#34;Use EPWM1 Channel 2(PC.3) to capture the EPWM1 Channel 0(PC.5) Waveform\\n\u0026#34;);\rwhile(1)\r{\rprintf(\u0026#34;\\n\\nPress any key to start EPWM Capture Test\\n\u0026#34;);\rgetchar();\r/*--------------------------------------------------------------------------------------*/\r/* Set the EPWM1 Channel 0 as EPWM output function. */\r/*--------------------------------------------------------------------------------------*/\r/* Assume EPWM output frequency is 250Hz and duty ratio is 30%, user can calculate EPWM settings by follows.(up counter type)\rduty ratio = (CMR)/(CNR+1)\rcycle time = CNR+1\rHigh level = CMR\rEPWM clock source frequency = PLL/2 = 100000000\r(CNR+1) = EPWM clock source frequency/prescaler/EPWM output frequency\r= 100000000/7/250 = 57142\r(Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)\rCNR = 57141\rduty ratio = 30% ==\u0026gt; (CMR)/(CNR+1) = 30%\rCMR = 17142\rPrescale value is 6 : prescaler= 7\r*/\r/* Set EPWM1 channel 0 output configuration */\rEPWM_ConfigOutputChannel(EPWM1, 0, 250, 30);\r/* Enable EPWM Output path for EPWM1 channel 0 */\rEPWM_EnableOutput(EPWM1, EPWM_CH_0_MASK);\r/* Enable Timer for EPWM1 channel 0 */\rEPWM_Start(EPWM1, EPWM_CH_0_MASK);\r/*--------------------------------------------------------------------------------------*/\r/* Set the EPWM1 channel 2 for capture function */\r/*--------------------------------------------------------------------------------------*/\r/* If input minimum frequency is 250Hz, user can calculate capture settings by follows.\rCapture clock source frequency = PLL = 100000000 in the sample code.\r(CNR+1) = Capture clock source frequency/prescaler/minimum input frequency\r= 100000000/7/250 = 57142\r(Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)\rCNR = 0xFFFF\r(Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)\rCapture unit time = 1/Capture clock source frequency/prescaler\r70 ns = 1/100000000/7\r*/\r/* Set EPWM1 channel 2 capture configuration */\rEPWM_ConfigCaptureChannel(EPWM1, 2, 70, 0);\r/* Enable Timer for EPWM1 channel 2 */\rEPWM_Start(EPWM1, EPWM_CH_2_MASK);\r/* Enable Capture Function for EPWM1 channel 2 */\rEPWM_EnableCapture(EPWM1, EPWM_CH_2_MASK);\r/* Enable falling capture reload */\rEPWM1-\u0026gt;CAPCTL |= EPWM_CAPCTL_FCRLDEN2_Msk;\r/* Wait until EPWM1 channel 2 Timer start to count */\rwhile((EPWM1-\u0026gt;CNT[2]) == 0);\r/* Capture the Input Waveform Data */\rCalPeriodTime(EPWM1, 2);\r/*------------------------------------------------------------------------------------------------------------*/\r/* Stop EPWM1 channel 0 (Recommended procedure method 1) */\r/* Set EPWM Timer loaded value(Period) as 0. When EPWM internal counter(CNT) reaches to 0, disable EPWM Timer */\r/*------------------------------------------------------------------------------------------------------------*/\r/* Set EPWM1 channel 0 loaded value as 0 */\rEPWM_Stop(EPWM1, EPWM_CH_0_MASK);\r/* Wait until EPWM1 channel 0 Timer Stop */\rwhile((EPWM1-\u0026gt;CNT[0] \u0026amp; EPWM_CNT0_CNT_Msk) != 0);\r/* Disable Timer for EPWM1 channel 0 */\rEPWM_ForceStop(EPWM1, EPWM_CH_0_MASK);\r/* Disable EPWM Output path for EPWM1 channel 0 */\rEPWM_DisableOutput(EPWM1, EPWM_CH_0_MASK);\r/*------------------------------------------------------------------------------------------------------------*/\r/* Stop EPWM1 channel 2 (Recommended procedure method 1) */\r/* Set EPWM Timer loaded value(Period) as 0. When EPWM internal counter(CNT) reaches to 0, disable EPWM Timer */\r/*------------------------------------------------------------------------------------------------------------*/\r/* Set loaded value as 0 for EPWM1 channel 2 */\rEPWM_Stop(EPWM1, EPWM_CH_2_MASK);\r/* Wait until EPWM1 channel 2 current counter reach to 0 */\rwhile((EPWM1-\u0026gt;CNT[2] \u0026amp; EPWM_CNT2_CNT_Msk) != 0);\r/* Disable Timer for EPWM1 channel 2 */\rEPWM_ForceStop(EPWM1, EPWM_CH_2_MASK);\r/* Disable Capture Function and Capture Input path for EPWM1 channel 2*/\rEPWM_DisableCapture(EPWM1, EPWM_CH_2_MASK);\r/* Clear Capture Interrupt flag for EPWM1 channel 2 */\rEPWM_ClearCaptureIntFlag(EPWM1, 2, EPWM_CAPTURE_INT_FALLING_LATCH);\r}\r}\r/*** (C) COPYRIGHT 2021 Nuvoton Technology Corp. ***/ ","permalink":"https://weizongchen.github.io/blog/pwm/","tags":["Cortex M4"],"title":" PWM 的 應用範例 "},{"categories":["說明文件"],"contents":"Timer0 電路位置 由pinconfigure 可以知道Timer0 在 pin 1 (PB5) 接著\n設定 Timer0 pin 角 //\u0026mdash;PIN\u0026mdash;- /* Set timer toggle out pin */ SET_TM0_PB5();\nTimer Delay Delay 1 秒:\nTIMER_Delay(TIMER0, 1000000);\nTimer init_TIMER0_Toggle TIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 250000);\n開啟TIMER0 反轉250K\n邏輯分析儀量測 邏輯分析儀 桶著 Pin1 開 Salease 邏輯分析儀 SW 可以發現訊號是125K Hz 波峰 +波谷 就250K Hz\n/*---------------------------------------------------------------------------------------------------------*/\r/* Global Interface Variables Declarations */\r/*---------------------------------------------------------------------------------------------------------*/\rvolatile uint32_t g_au32TMRINTCount[4] = {0};\r//----------------- TIMER0 --------------------\rvoid TMR0_IRQHandler(void)\r{\rif(TIMER_GetIntFlag(TIMER0) == 1)\r{\r/* Clear Timer0 time-out interrupt flag */\rTIMER_ClearIntFlag(TIMER0);\rg_au32TMRINTCount[0]++;\rPH4 ^= 1;\r}\r}\rvoid TMR0_Init(void)\r{\r/* Enable TIMER module clock */\r//---clock---\rCLK_EnableModuleClock(TMR0_MODULE);\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);\r//---PIN----\r/* Set timer toggle out pin */\rSET_TM0_PB5();\r/* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */\rTIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1);\r/* Start Timer0 ~ Timer3 counting */\rTIMER_Start(TIMER0);\r//--- NVIC ----\rTIMER_EnableInt(TIMER0);\r/* Enable Timer0 ~ Timer3 NVIC */\rNVIC_EnableIRQ(TMR0_IRQn);\r/* Check Timer0 ~ Timer3 interrupt counts */\r//g_au32TMRINTCount[0];\r}\rvoid init_TIMER0_Toggle(void)\r{\r/* Enable TIMER module clock */\r//---clock---\rCLK_EnableModuleClock(TMR0_MODULE);\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);\r//---PIN----\r/* Set timer toggle out pin */\rSET_TM0_PB5();\r/* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */\rTIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 250000);\r/* Start Timer0 ~ Timer3 counting */\rTIMER_Start(TIMER0);\r}\r//-------------- HCLK -------------\rvoid init_HCLK(void){\rSYS_UnlockReg();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable HXT clock */\rCLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);\rCLK_WaitClockReady( CLK_STATUS_HXTSTB_Msk);\rSYS_LockReg();\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\ruint16_t cnt = 0;\ruint8_t STA = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rinit_HCLK();\rinit_TIMER0_Toggle();\r// PH4 LED R\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rwhile(1) {\r}\r} ","permalink":"https://weizongchen.github.io/blog/timer_init_timer0_toggle/","tags":["Cortex M4"],"title":"Timer Toggle 使用邏輯分析儀量測timer toggle (by M460)"},{"categories":["說明文件"],"contents":" 新唐 Pinconfigure 地址 https://www.nuvoton.com/resource-download.jsp?tp_GUID=SW1320200319135912\n當發現我要的IC 沒有出現在 我要的M460 沒有在 Pinconfigure 選單\nDownload 新的exe file Pinconfigure 下載\nM460 出現了 ","permalink":"https://weizongchen.github.io/blog/install_and_update_pinconfigure/","tags":["Tool"],"title":"安裝新唐 Pinconfigure "},{"categories":["說明文件"],"contents":"Button 的 狀態討論 /*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\ruint16_t cnt = 0;\ruint8_t STA = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rwhile(1) {\rSTA \u0026lt;\u0026lt;= 1;\rSTA += PH0;\rprintf(\u0026#34;%d \\n\u0026#34;, PH0);\rTIMER_Delay(TIMER0, 1000000);\rSTA \u0026amp;= 3;\rif(STA == 2) {\rcnt++;\r//printf(\u0026#34;%d \u0026#34;, cnt);\r}\r//TIMER_Delay(TIMER0, 1000000);\r}\r} STA 原始值 00000000(0)\n二進制 (十進制)\rSTA :\n第一圈 結果 00000000 左移一次 00000000 00000000+ PH0(1) [沒有按] 00000001 00000001 \u0026amp; 00000011(3) 00000001(1) STA == 2 false 第二圈 結果 00000001 左移一次 00000010 00000010 + PH0(1) [沒有按] 00000011 00000011 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第三圈 結果 00000011 左移一次 00000110 00000110 + PH0(1) [沒有按] 00000111 00000111 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第四圈 結果 00000011 左移一次 00000110 00000110 + PH0(1) [沒有按] 00000111 00000111 \u0026amp; 00000011(3) 00000011(3) STA == 2 false 第五圈 結果 00000011 左移一次 00000110 00000110 + PH0(0) [按下去] 00000110 00000110 \u0026amp; 00000011(3) 00000010(2) STA == 2 true 印數字 (CPU執行很快,可能不小心print到數個數字)\n第六圈 結果 00000010 左移一次 00000100 00000100 + PH0(0) [還按著] 00000100 00000100 \u0026amp; 00000011(3) 00000000(0) STA == 2 false 第七圈 結果 00000000 左移一次 00000000 00000000 + PH0(0) [還按著] 00000000 00000000 \u0026amp; 00000011(3) 00000000(0) STA == 2 false 第八圈 (等於第一圈) 結果 00000000 左移一次 00000000 00000000 + PH0(1) [沒有按] 00000001 00000001 \u0026amp; 00000011(3) 00000001(1) STA == 2 false ","permalink":"https://weizongchen.github.io/blog/btn/","tags":["Cortex M4"],"title":"Button 的各種說明"},{"categories":["說明文件"],"contents":"加入Timer的Driver 在 SYS_Init() 時 ,加入TMR0 的 clock source /*---------------------------------------------------------------------------------------------------------*/\r/* Initialization for sample code */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable TIMER module clock */\rCLK_EnableModuleClock(TMR0_MODULE);\r/* Select TIMER clock source */\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HIRC, 0); 在 SYS_Init() 時 ,加入TMR0 的 clock source while(1) {\rPH4 = 1;\rTIMER_Delay(TIMER0, 1000000);\rPH4 = 0;\rTIMER_Delay(TIMER0, 1000000);\r} 邏輯分析儀量測 LED 訊號 用 Timer0 控制 LED 1秒亮 1秒滅 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Transmit and receive data from PC terminal through RS232 interface.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define RXBUFSIZE 1024\r/*---------------------------------------------------------------------------------------------------------*/\r/* Global variables */\r/*---------------------------------------------------------------------------------------------------------*/\rstatic uint8_t g_u8RecData[RXBUFSIZE] = {0};\rstatic volatile uint32_t g_u32comRbytes = 0;\rstatic volatile uint32_t g_u32comRhead = 0;\rstatic volatile uint32_t g_u32comRtail = 0;\rstatic volatile int32_t g_i32Wait = TRUE;\r/*---------------------------------------------------------------------------------------------------------*/\r/* Define functions prototype */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void);\rvoid UART_TEST_HANDLE(void);\rvoid UART_FunctionTest(void);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\rvoid UART0_IRQHandler(void);\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART module clock */\rCLK_EnableModuleClock(UART0_MODULE);\rCLK_EnableModuleClock(UART1_MODULE);\r/* Select UART module clock source and UART module clock divider */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\rCLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HIRC, CLK_CLKDIV0_UART1(1));\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r/*---------------------------------------------------------------------------------------------------------*/\r/* Initialization for sample code */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Enable TIMER module clock */\rCLK_EnableModuleClock(TMR0_MODULE);\r/* Select TIMER clock source */\rCLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HIRC, 0);\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Reset UART0 */\rSYS_ResetModule(UART0_RST);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rprintf(\u0026#34;test \\n\u0026#34;);\rwhile(1) {\rPH4 = 1;\rTIMER_Delay(TIMER0, 1000000);\rPH4 = 0;\rTIMER_Delay(TIMER0, 1000000);\r}\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* ISR to handle UART Channel 0 interrupt event */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART0_IRQHandler(void)\r{\rUART_TEST_HANDLE();\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* UART Callback function */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART_TEST_HANDLE(void)\r{\ruint8_t u8InChar = 0xFF;\ruint32_t u32IntSts = UART0-\u0026gt;INTSTS;\rif(u32IntSts \u0026amp; UART_INTSTS_RDAINT_Msk)\r{\rprintf(\u0026#34;\\nInput:\u0026#34;);\r/* Get all the input characters */\rwhile(UART_IS_RX_READY(UART0))\r{\r/* Get the character from UART Buffer */\ru8InChar = (uint8_t)UART_READ(UART0);\rprintf(\u0026#34;%c \u0026#34;, u8InChar);\rif(u8InChar == \u0026#39;0\u0026#39;)\r{\rg_i32Wait = FALSE;\r}\r/* Check if buffer full */\rif(g_u32comRbytes \u0026lt; RXBUFSIZE)\r{\r/* Enqueue the character */\rg_u8RecData[g_u32comRtail] = u8InChar;\rg_u32comRtail = (g_u32comRtail == (RXBUFSIZE - 1)) ? 0 : (g_u32comRtail + 1);\rg_u32comRbytes++;\r}\r}\rprintf(\u0026#34;\\nTransmission Test:\u0026#34;);\r/* Forces a write of all user-space buffered data for the given output */\rfflush(stdout);\r}\rif(u32IntSts \u0026amp; UART_INTSTS_THREINT_Msk)\r{\ruint32_t u32Tmp;\ru32Tmp = g_u32comRtail;\rif(g_u32comRhead != u32Tmp)\r{\ru8InChar = g_u8RecData[g_u32comRhead];\rwhile(UART_IS_TX_FULL(UART0)); /* Wait Tx is not full to transmit data */\rUART_WRITE(UART0, u8InChar);\rg_u32comRhead = (g_u32comRhead == (RXBUFSIZE - 1)) ? 0 : (g_u32comRhead + 1);\rg_u32comRbytes--;\r}\r}\r/* Handle transmission error */\rif(UART0-\u0026gt;FIFOSTS \u0026amp; (UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_RXOVIF_Msk))\r{\rUART0-\u0026gt;FIFOSTS = (UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_RXOVIF_Msk);\r}\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* UART Function Test */\r/*---------------------------------------------------------------------------------------------------------*/\rvoid UART_FunctionTest(void)\r{\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| UART Function Test |\\n\u0026#34;);\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| Description : |\\n\u0026#34;);\rprintf(\u0026#34;| The sample code will print input char on terminal |\\n\u0026#34;);\rprintf(\u0026#34;| Please enter any to start (Press \u0026#39;0\u0026#39; to exit) |\\n\u0026#34;);\rprintf(\u0026#34;+-----------------------------------------------------------+\\n\u0026#34;);\r/*\rUsing a RS232 cable to connect UART0 and PC.\rUART0 is set to debug port. UART0 is enable RDA interrupt.\rWhen inputting char to terminal screen, RDA interrupt will happen and\rUART0 will print the received char on screen.\r*/\r/* Enable UART RDA and THRE interrupt */\rNVIC_EnableIRQ(UART0_IRQn);\rUART_EnableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk));\rwhile(g_i32Wait);\r/* Disable UART RDA and THRE interrupt */\rNVIC_DisableIRQ(UART0_IRQn);\rUART_DisableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk));\rg_i32Wait = TRUE;\r} ","permalink":"https://weizongchen.github.io/blog/timer_delay/","tags":["Cortex M4"],"title":"Timer Delay 說明 (by M460)"},{"categories":["說明文件"],"contents":"在Keil IDE 的 Debug Mode 時 Memory window data 突然不實時更新了?\n下圖 右邊的 Memory2 本來會一直更新,但是沒有?\n只要在 View下的 Periodic Window Update 打開就好\n如下影片操作\n","permalink":"https://weizongchen.github.io/blog/keil_debug_memoryupdate/","tags":["Cortex M4"],"title":"Keil IDE Debug Mode Memory window data not update?"},{"categories":["說明文件"],"contents":"Keil IDE 在啟動 project 時,會自己上網下載 一堆不是新唐的pack\n下圖看到時趕緊關掉,不然他會一直download 不是新唐的東西。\n這邊選\u0026quot;是\u0026quot; 跳過這裡\n這個時候,Keil會跟你說沒有這個M460的 pack 包,你如果不安裝 ,compile 也會過,但是每次打開Keil 會就跳出來,滿煩的。\n去新唐的官網,下載Driver 就可以解決這個問題了。\n新唐Driver 位置\nNu-Link_Keil_Driver_V3.09.7380r\n準備安裝\n這裡如果你不懂,就按照指示預設安裝路徑。\n這裡會出現這個視窗,是因為我原本就已經安裝過這個Driver,裡面有M480 NUC505 \u0026hellip; 一堆 但是不包含M460的部分,所以按\u0026quot;是\u0026quot;,就會更新成有包含460的\n這裡步驟就是安裝pack(Nuvoton device family pack)了 一路按\u0026quot;是\u0026quot; 就可以了\n他會把Nuvoton的pack都安裝\n因為我使用新唐的開發版,上面有Nu-Link2-Me 的燒錄器,所以當然也安裝一下它的driver,你如果是 J-Link 、U-Link 、巴拉巴拉Link\u0026hellip;,要自己安裝他們的Driver喔。\n安裝\n再次打開Project 就不會有那些警告視窗拉~\n","permalink":"https://weizongchen.github.io/blog/keil_import_pack/","tags":["Cortex M4"],"title":"Keil IDE 在啟動 project 時,會自己上網下載 一堆不是新唐的pack"},{"categories":["說明文件"],"contents":"如果你不是商業使用 !\n如果你不是商業使用 !\n如果你不是商業使用 !\n很重要所以說三次! 所以如果你是個人評估使用\nARM 對這個 MDK-Community 說明\n簡單說就是支援 : All microcontrollers based on Arm Cortex®-M processors\n你給他E mail 它就給你licence\n把上面 LIC 填到下面\n","permalink":"https://weizongchen.github.io/blog/keil_ide_licence/","tags":["Cortex M4"],"title":"Keil IDE 16K Code size 限制?"},{"categories":["說明文件"],"contents":" 可以直接來這邊下載 https://www.nuvoton.com/tool-and-software/debugger-and-programmer/mass-production-tool/\nICP Tool 新唐燒錄器適用於新唐NuMicro®微控制器的大量生產階段。基於靈活的設定與直觀的操作,使用者可全面掌握量產流程。\n選擇你的series\n如果你電腦插著很多個NuLnk 可以選,點選Radio Button時,那個被指定的NuLnk會閃閃閃閃閃~\n如果你電腦灌過ICP 軟體了,跟這板子原本的ICP版本不匹配,你可以更新,也可以不更新,一般我都直接不更新,反正可以燒就好。\n因為我是要把板子上的APROM的 firmware拿出來存,可以照下圖的方式點選\n最後成功存取\nFile Data 要燒進去板子的FW版本\nOn board flash 板子上面的FW版本\nOffline Flash 在燒入除錯器裡面的版本\n","permalink":"https://weizongchen.github.io/blog/icp_introduce/","tags":["Tool"],"title":"ICP 使用說明"},{"categories":["說明文件"],"contents":" User Manual https://www.nuvoton.com/export/resource-files/UM_NuMaker-ETM-M487_User_Manual_EN_Rev1.01.pdf\n通用 I/O (GPIO) 概述 M480 系列多達118 個通用I/O管腳和其他功能管腳共享,這取決於芯片的配置。 118個管腳分配在PA, PB, PC, PD, PE, PF, PG 和 PH這8個端口上。 PA, PB, PE和PG有16個管腳,PC,PD有15個管腳,PF,PH有12個管腳。每個管腳都是獨立的,都有相應的寄存器位來控制管腳功能模式與數據。\n1. 設定發電廠 (clock) 2. 設定 LED 的腳位 General Port 0~7 為 Low byte, 8~15 為 High byte 所以是Port H 的 0 1 2 是L,如下面黃色的標記\n設定 Port H 0 1 2 腳位為 output\n3. 設定 Button 的腳位 General Port 0~7 為 Low byte, 8~15 為 High byte 所以是Port B 的 15 是H , Port F 的 11 是H,如下面黃色的標記\n設定 Port B 15 和 Port F 11 腳位為 input\n4. 設定 UART0 的腳位 新唐大部分的M4 UART0 腳位是 PB12 RXD / PB13 TXD\n5. 設定中斷 這邊中斷就是用UART0 打印東西,和 toggle LED 的亮滅\n完整程式參考 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief GPIO function for level1 training course\r*\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\r#define LED_R\tPH0\r#define LED_G\tPH1\r#define LED_B\tPH2\r#define LED_ON\t0\r#define LED_OFF\t1\rvolatile uint32_t sw1_int_cnt = 0;\rvolatile uint32_t sw2_int_cnt = 0;\rvoid SYS_Init(void)\r{\r/* Enable HXT clock (external XTAL 12MHz) */\rCLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);\r/* Wait for HXT clock ready */\rCLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);\r/* Enable LIRC clock */\rCLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);\r/* Wait for LIRC clock ready */\rCLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);\r/* Set core clock as PLL_CLOCK from PLL */\rCLK_SetCoreClock(FREQ_192MHZ);\r/* Set PCLK0/PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2);\r/* Enable module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Set module clock */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));\r}\rvoid UART0_Init()\r{\r/* Set GPB multi-function pins to UART0 RXD and TXD */\rSYS-\u0026gt;GPB_MFPH = (SYS-\u0026gt;GPB_MFPH \u0026amp; ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) |\r(SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\rvoid LED_Init(void)\r{\r/* Set PH.0 ~ PH.2 to GPIO */\rSYS-\u0026gt;GPH_MFPL = (SYS-\u0026gt;GPH_MFPL \u0026amp; ~(SYS_GPH_MFPL_PH0MFP_Msk | SYS_GPH_MFPL_PH1MFP_Msk | SYS_GPH_MFPL_PH2MFP_Msk)) |\r(SYS_GPH_MFPL_PH0MFP_GPIO | SYS_GPH_MFPL_PH1MFP_GPIO | SYS_GPH_MFPL_PH2MFP_GPIO);\r/* Set PC.9 ~ PC.11 to GPIO output */\rGPIO_SetMode(PH, (BIT0 | BIT1 | BIT2), GPIO_MODE_OUTPUT);\r/* Let LED off after initialize */\rLED_R = LED_OFF;\rLED_G = LED_OFF;\rLED_B = LED_OFF;\r}\rvoid BTN_Init(void)\r{\r/************** SW2 ***************/\r/* Set PB.15 to GPIO */\rSYS-\u0026gt;GPG_MFPH = (SYS-\u0026gt;GPG_MFPH \u0026amp; ~(SYS_GPG_MFPH_PG15MFP_Msk)) | (SYS_GPG_MFPH_PG15MFP_GPIO);\r/* Set PB.15 to GPIO intput */\rGPIO_SetMode(PG, BIT15, GPIO_MODE_INPUT);\rGPIO_EnableInt(PG, 15, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPG_IRQn);\r/************** SW3 ***************/\r/* Set PF.11 to GPIO */\rSYS-\u0026gt;GPF_MFPH = (SYS-\u0026gt;GPF_MFPH \u0026amp; ~(SYS_GPF_MFPH_PF11MFP_Msk)) | (SYS_GPF_MFPH_PF11MFP_GPIO);\r/* Set PF.11 to GPIO intput */\rGPIO_SetMode(PF, BIT11, GPIO_MODE_INPUT);\rGPIO_EnableInt(PF, 11, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPF_IRQn);\r/* Set de-bounce function */\rGPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_512);\rGPIO_ENABLE_DEBOUNCE(PG, BIT15);\rGPIO_ENABLE_DEBOUNCE(PF, BIT11);\r}\rint main(void)\r{\ruint32_t sw1_cnt = 0, sw2_cnt = 0;\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| Level1 GPIO control Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\\n\u0026#34;);\r/* Init LED */\rLED_Init();\r/* Init BTN */\rBTN_Init();\rwhile(1) {\r/* Check if the SW1 is pressed */\rif (sw1_int_cnt != sw1_cnt) {\rsw1_cnt = sw1_int_cnt;\rprintf(\u0026#34;SW1 interrupt count: %d\\n\u0026#34;, sw1_cnt);\r}\r/* Check if the SW2 is pressed */\rif (sw2_int_cnt != sw2_cnt) {\rsw2_cnt = sw2_int_cnt;\rprintf(\u0026#34;SW2 interrupt count: %d\\n\u0026#34;, sw2_cnt);\r}\r}\r}\r//PG15\rvoid GPG_IRQHandler(void)\r{\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;+------------Detect PG---------------+\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\r/* Check if PG.15 the interrupt occurred */\rif(GPIO_GET_INT_FLAG(PG, BIT15)) {\rLED_R ^= 1;\rsw1_int_cnt++;\r/* Clear PG.15 interrupt flag */\rGPIO_CLR_INT_FLAG(PG, BIT15);\r}else {\r/* Un-expected interrupt. Just clear all PB interrupts */\rPG-\u0026gt;INTSRC = PG-\u0026gt;INTSRC;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r}\r//PF11\rvoid GPF_IRQHandler(void)\r{\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;+------------Detect PF---------------+\\n\u0026#34;);\rprintf(\u0026#34;+---------------------------------------+\\n\u0026#34;);\r/* Check if PF.11 the interrupt occurred */\rif(GPIO_GET_INT_FLAG(PF, BIT11)) {\rLED_G ^= 1;\rsw2_int_cnt++;\r/* Clear PF.11 interrupt flag */\rGPIO_CLR_INT_FLAG(PF, BIT11);\r} else {\r/* Un-expected interrupt. Just clear all PB interrupts */\rPF-\u0026gt;INTSRC = PF-\u0026gt;INTSRC;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r} M460 的控制LED範例 /*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r//Mode\r*(volatile unsigned int *)(0x400041C0) = 0x00001500;\r//value\r*(volatile unsigned int *)(0x400041C8) = 0x0000FF8F;\rwhile(1) {\rint i;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1下\r*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1下\r*(volatile unsigned int *)(0x400041C8) = 0x00000070;\r}\r} *(volatile unsigned int *)(0x400041C0) = 0x00001500;\nRegister 位置\n0x40004000 + 0x1C0\nRegister的值\n0x 0000 1500\n000\u0026hellip;0 1500 如下圖\n*(volatile unsigned int *)(0x400041C8) = 0x00000070;\n0x1C8 是 PH_DOUT (port H out) 的控制\n70 如下圖所示 (0x00000070 全滅 0x00000000 全亮)\nint32_t main(void)\r{\r//Mode\r*(volatile unsigned int *)(0x400041C0) = 0x00001500;\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\r//value\r*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rGPIO_SetMode(PH, BIT4, GPIO_MODE_OUTPUT);\rPH4 = 0;\rPH5 = 0;\rPH6 = 0;\rwhile(1) {\rint i;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1百萬下\r// 全滅\r//*(volatile unsigned int *)(0x400041C8) = 0x00000000;\rPH4 = 1;\rPH5 = 1;\rPH6 = 1;\rfor(i = 0; i \u0026lt; 50000000; i++) {} //等1百萬下\r// 全亮\rPH4 = 0;\rPH5 = 0;\rPH6 = 0;\r}\r} M460 的控制Button範例 /**************************************************************************//**\r* @file main.c\r* @version V3.00\r* @brief Show the usage of GPIO interrupt function.\r*\r* @copyright SPDX-License-Identifier: Apache-2.0\r* @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.\r******************************************************************************/\r#include \u0026lt;stdio.h\u0026gt;\r#include \u0026#34;NuMicro.h\u0026#34;\rvoid GPH_IRQHandler(void);\rvoid SYS_Init(void);\rvoid UART0_Init(void);\r/**\r* @brief GPIO PH IRQ\r*\r* @param None\r*\r* @return None\r*\r* @details The PH default IRQ, declared in startup_m460.s.\r*/\rvoid GPH_IRQHandler(void)\r{\rvolatile uint32_t u32temp;\r/* To check if PH.0 interrupt occurred */\rif(GPIO_GET_INT_FLAG(PH, BIT0))\r{\rGPIO_CLR_INT_FLAG(PH, BIT0);\rprintf(\u0026#34;PH.0 INT occurred.\\n\u0026#34;);\r}\relse if(GPIO_GET_INT_FLAG(PH, BIT1))\r{\rGPIO_CLR_INT_FLAG(PH, BIT1);\rprintf(\u0026#34;PH.1 INT occurred.\\n\u0026#34;);\r}\relse\r{\r/* Un-expected interrupt. Just clear all PH interrupts */\ru32temp = PH-\u0026gt;INTSRC;\rPH-\u0026gt;INTSRC = u32temp;\rprintf(\u0026#34;Un-expected interrupts.\\n\u0026#34;);\r}\r}\rvoid SYS_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init System Clock */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set PCLK0 and PCLK1 to HCLK/2 */\rCLK-\u0026gt;PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);\r/* Set core clock to 200MHz */\rCLK_SetCoreClock(200000000);\r/* Enable all GPIO clock */\rCLK-\u0026gt;AHBCLK0 |= CLK_AHBCLK0_GPACKEN_Msk | CLK_AHBCLK0_GPBCKEN_Msk | CLK_AHBCLK0_GPCCKEN_Msk | CLK_AHBCLK0_GPDCKEN_Msk |\rCLK_AHBCLK0_GPECKEN_Msk | CLK_AHBCLK0_GPFCKEN_Msk | CLK_AHBCLK0_GPGCKEN_Msk | CLK_AHBCLK0_GPHCKEN_Msk;\rCLK-\u0026gt;AHBCLK1 |= CLK_AHBCLK1_GPICKEN_Msk | CLK_AHBCLK1_GPJCKEN_Msk;\r/* Enable UART0 module clock */\rCLK_EnableModuleClock(UART0_MODULE);\r/* Select UART0 module clock source as HIRC and UART0 module clock divider as 1 */\rCLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init I/O Multi-function */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Set multi-function pins for UART0 RXD and TXD */\rSET_UART0_RXD_PB12();\rSET_UART0_TXD_PB13();\r}\rvoid UART0_Init(void)\r{\r/*---------------------------------------------------------------------------------------------------------*/\r/* Init UART */\r/*---------------------------------------------------------------------------------------------------------*/\r/* Reset UART0 */\rSYS_ResetModule(UART0_RST);\r/* Configure UART0 and set UART0 baud rate */\rUART_Open(UART0, 115200);\r}\r/*---------------------------------------------------------------------------------------------------------*/\r/* Main Function */\r/*---------------------------------------------------------------------------------------------------------*/\rint32_t main(void)\r{\r/* Unlock protected registers */\rSYS_UnlockReg();\r/* Init System, peripheral clock and multi-function I/O */\rSYS_Init();\r/* Lock protected registers */\rSYS_LockReg();\r/* Init UART0 for printf */\rUART0_Init();\rprintf(\u0026#34;\\n\\nCPU @ %d Hz\\n\u0026#34;, SystemCoreClock);\rprintf(\u0026#34;+------------------------------------------------+\\n\u0026#34;);\rprintf(\u0026#34;| GPIO PH.0 and PH.1 Interrupt Sample Code |\\n\u0026#34;);\rprintf(\u0026#34;+------------------------------------------------+\\n\\n\u0026#34;);\r/*-----------------------------------------------------------------------------------------------------*/\r/* GPIO Interrupt Function Test */\r/*-----------------------------------------------------------------------------------------------------*/\rprintf(\u0026#34;PH.0 and PH.1 are used to test interrupt ......\\n\u0026#34;);\r/* Configure PH.0 as Input mode and enable interrupt by rising edge trigger */\rGPIO_SetMode(PH, BIT0, GPIO_MODE_INPUT);\rGPIO_EnableInt(PH, 0, GPIO_INT_RISING);\rNVIC_EnableIRQ(GPH_IRQn);\r/* Configure PH.1 as Quasi-bidirection mode and enable interrupt by falling edge trigger */\rGPIO_SetMode(PH, BIT1, GPIO_MODE_QUASI);\rGPIO_EnableInt(PH, 1, GPIO_INT_FALLING);\rNVIC_EnableIRQ(GPH_IRQn);\r/* Enable interrupt de-bounce function and select de-bounce sampling cycle time is 1024 clocks of LIRC clock */\rGPIO_SET_DEBOUNCE_TIME(PH, GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_1024);\rGPIO_SET_DEBOUNCE_TIME(PH, GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_1024);\rGPIO_ENABLE_DEBOUNCE(PH, BIT0);\rGPIO_ENABLE_DEBOUNCE(PH, BIT1);\r/* Waiting for interrupts */\rwhile(1);\r} ","permalink":"https://weizongchen.github.io/blog/gpio_introduce/","tags":["Cortex M4"],"title":"GPIO 說明"},{"categories":["安裝步驟文件"],"contents":"Description Enable the Remoteproc device driver in the Linux kernel.\n$ bitbake linux-ma35d1 -c menuconfig Device Drivers ---\u0026gt;\rRemoteproc drivers ---\u0026gt;\r[*] Support for Remote Processor subsystem\r\u0026lt;*\u0026gt; MA35D1 remoteproc support \u0026lt;Save\u0026gt; and \u0026lt;Exit\u0026gt; Description Modify the device tree node setting of remoteproc in the Linux kernel.\nLINUX_KERENL_PATH/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi Description Compile the Linux kernel.\n$ bitbake linux-ma35d1 -C compile Description Modify the device tree node setting of SSPCC in the TF-A. 怎麼知道是I2S0_SUBM的?\nDescription Modify the device tree node setting of SSPCC in the TF-A. 怎麼知道是這4根pin角的?\nDescription Compile the TF-A.\n$ bitbake tf-a-ma35d1 -C compile Description Build-up Image. Qt 版本:\nbitbake nvt-image-qt5 -c cleanall \u0026amp;\u0026amp; bitbake nvt-image-qt5 Minimal 版本:\n$ bitbake core-image-minimal –c cleanall \u0026amp;\u0026amp; bitbake core-image-minimal Description Burn-in Image into SD card. 燒入SD卡\n$ sudo dd if=nvt-image-qt5-evb-ma35d1-xxxxx.rootfs.sdcard of=/dev/sdb 延展SD的size\rsudo ./ma35d1_resize.sh /dev/sdb 1 apply 把 M4 的.axf 放到SD卡的 /lib/firmware 中\nNote: The following step copy all of RTP (M4) sample codes in the M4_BSP into Filesystem. You can chose the sample code you want to use or replace with the firmware you developed. 執行 M4 axf 的指令\necho -n /lib/firmware \u0026gt; /sys/module/firmware_class/parameters/path\recho -n I2S_Codec_PDMA.elf \u0026gt; /sys/class/remoteproc/remoteproc0/firmware\recho start \u0026gt; /sys/class/remoteproc/remoteproc0/state\recho stop \u0026gt; /sys/class/remoteproc/remoteproc0/state Remoteproc - Keil IDE 設定\nNu-link 的DAP 要設定1\nPS:原本我們開發板的NuLink 是 0 ,MA35D1的要改1 ","permalink":"https://weizongchen.github.io/blog/ma35d1_rtp/","tags":["MA35D1","Cortex M4"],"title":"MA35D1 M4 使用設定"},{"categories":["安裝步驟文件"],"contents":"MA35D16A887C (BGA312) MCP package with DDR3L (256 MB)\n7-inch TFT LCD (1024x600) with touch daughter board\neMMC memory device daughter board\nSPI-NAND flash W25N02JWZEIF (256MB)\nNAND flash W29N01HVS1NA (128MB)\n2 x Giga Ethernet\n2 x High Speed USB\n2 x Camera Capture (CMOS sensor) header connectors\n1 x SIM Card slot\n2 x UART, 2 x RS485, 2 x CAN-FD, 8 x EADC channels\n基本安裝設定 Yocto 項目至少需要 150G 存儲\n在使用 Yocto 項目之前必須安裝必要的包\n$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \\\rbuild-essential chrpath socat cpio python python3 python3-pip python3-pexpect \\\rxz-utils debianutils iputils-ping libsdl1.2-dev xterm curl Update existing list of packages\n$ sudo apt-get update Install a few prerequisite packages which let apt use packages over HTTPS\n$ sudo apt install apt-transport-https ca-certificates curl software-properties-common Add Docker’s official GPG key for the official Docker repository to your system\n$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add Set up the stable repository, add the Docker repository to APT sources\n$ sudo add-apt-repository \u0026#34;deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable\u0026#34; Update the package database with the Docker packages from the newly added repo\n$ sudo apt-get update Install Docker\n$ sudo apt-get install docker-ce docker-ce-cli containerd.io Download the Docker Script for MA35D1\n$ git clone https://github.com/OpenNuvoton/MA35D1_Docker_Script.git Enter docker-yocto folder, setup docker image, and select folder to be share\n$ ./build.sh It may take one hour to get 710 files.\rPlease enter absolute path for shared folders(eg:/home/\u0026lt;user name\u0026gt;) : Enter docker image, and your command line head will be like nuvoton@a24d9e06abe3:~$\n$ ./join.sh\rnua3500_nuvoton\rnuvoton@a24d9e06abe3:~$ Create a folder name yocto under /share\nnuvoton@a24d9e06abe3:~/share$ mkdir yocto The first time you use repo, you need to set up the GIT environment\nnuvoton@a24d9e06abe3:~/share/yocto$ git config --global user.email \u0026#34;test@test.test.test\u0026#34;\rnuvoton@a24d9e06abe3:~/share/yocto$ git config --global user.name \u0026#34;test“\rnuvoton@a24d9e06abe3:~/share/yocto$ git config --global http.sslverify false Go to /share/yocto to setup repo path\nnuvoton@a24d9e06abe3:~/share/yocto$ repo init -u https://github.com/OpenNuvoton/MA35D1_Yocto-v3.1.3.git -m meta-ma35d1/base/ma35d1.xml Download the yocto project\nnuvoton@a24d9e06abe3:~/share/yocto$ repo sync Build Image by Yocto Setup building configuration. The DISTRO option we usually use nvt-ma35d1-directfb\nEVB :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=ma35d1-evb source sources/init-build-env build SOM :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=numaker-som-ma35d16a81 source sources/init-build-env build MACHINE 目前有 SOM 板 或 IOT 板,後面ma35d16a81是 板號,所以客戶可以做他自己的板子,用自己得板號。\nMACHINE=numaker-som-ma35d16a81\nMACHINE=numaker-iot-ma35d16f70 ( f7 =\u0026gt; DDR 128MB )\nMACHINE=numaker-iot-ma35d16f90 ( f9 =\u0026gt; DDR 512MB )\ntest chip SOM :\n~/yocto$ DISTRO=nvt-ma35d1-directfb MACHINE=ma35d1-tc-som source sources/init-build-env build (補充說明) 假設我要改build 不同的板號,從numaker-som-ma35d16a81 改成 numaker-iot-ma35d16f70,有兩個地方要改 local.conf 的 Machine 要改如下 指定編譯 DISTRO=nvt-ma35d1-directfb MACHINE=numaker-iot-ma35d16f70 source sources/init-build-env build Choose what Image you want to build\nImage 包含Qt的版本 (建議)\nbitbake nvt-image-qt5 小 Image 版本\nbitbake core-image-minimal Copy the image to SD $ sudo dd if=nvt-image-qt5-evb-ma35d1-xxxxx.rootfs.sdcard of=/dev/sdb status=progress Fast Application Development Make a toolchain installer\n$ bitbake nvt-image-qt5 -c populate_sdk\r(This may take about 1 hour ) Go to the following path and execute the shell file\n~build/tmp-glibc/deploy/sdk $ ./oecore-x86_x64-aarch64-toolcahin-5.5-dunfell.sh Add toolchain to environment variables\n$ source /usr/local/oecore-x86_64/environment-setup-aarch64-poky-linux Create the source code file for this example: helloworld.c\n#include \u0026lt;stdio.h\u0026gt;\rint main() {\r// printf() displays the string inside console\rprintf(“Hello, World!\\n”);\rreturn 0;\r} Compile it\n$ $CC helloworld.c -o helloworld ","permalink":"https://weizongchen.github.io/blog/ma35d1_install_method/","tags":["MA35D1"],"title":"MA35D1 Yocto 安裝說明"},{"categories":["說明文件"],"contents":" 要找這個Register\n問這個PDBIASEN bit 找不到\u0026hellip;..\nCLK-\u0026gt;LDOCTL |= CLK_LDOCTL_PDBIASEN_Msk;\nClock, LDO control Rigister, PDBIASEN 這個 bit\nbit 18\n忘記在哪一版本TRM 有找到這個register\n右邊表格˙(1) (2) 沒有賣了,所以只是給過去參考,目前就是看(3) 就好~\nCore Coupled Memory Mode (CCM Mode)\nCCM Mode 是 SRAM 跟 SPI Flash 的關係,SPI Flash可以把SRAM當作catch來使用,\nCCMEN 打開 就是一般SRAM,不是catch\nWhen user sets CCMEN(SPIM_CTL1[2]) to 1, the operation mode of cache memory will be core coupled memory mode (CCM mode). In CCM mode, the cache function of SPI Flash controller is disabled by hardware automatically, and MCU can access this core coupled memory as general SRAM. When user sets CCMEN(SPIM_CTL1[2]) to 0 and MCU accesses CCM address range, SPI Flash controller will generate AHB error response to MCU.\n當用戶設置CCMEN(SPIM_CTL1[2])為1時,緩存存儲器操作模式會轉變成內核耦合存儲器模式(CCM模 式)。在CCM模式下,SPI flash控制器的緩存功能會被硬件自動禁用,MCU訪問內核耦合存儲器就像是 SRAM一樣。當用戶設置CCMEN(SPIM_CTL1[2])為0時MCU訪問CCM地址範圍,SPI flash控制器將會 產生AHB錯誤給MCU\n","permalink":"https://weizongchen.github.io/blog/question/","tags":null,"title":"自己的問題筆記"},{"categories":["安裝步驟文件"],"contents":"系統環境 Windows 10 VS 2019 OpenCV 4.5.5 選擇 Windows 版本的OpenCV download下來 解壓縮到指定資料夾 可以在C 根目錄建一個 OpenCV 資料夾,在OpenCV資料夾下再建一個OpenCV4.5.5資料夾,並解押到這裡面\n整理檔案位置,將需要的檔案拿出來就好 因為opencv資料夾的大小很大,可以刪除。如空間夠大可以留下來,以備不時之需。\nbin 資料夾說明 opencv 3 版本之後,只需要opencv_world455.dll就可以了,opencv_world455d.dll 多一個d是指 debug版本的意思。\n設定環境變數 建立一個空的C++專案 建立一個空的C++專案 在這裡應該有solution 和 project 的分別,我們要在solution的位置新增一個專案 建立屬性管理員 Property Manager 方便每次專案可以套用同一個屬性,比如哪天出了opencv新的版本,可以直接套用新的版本的opencv或使用更舊版本的opencv 去view打開屬姓管理員,預設是沒有顯示的。 使用x64的Release版本\n建一個有意義的名子,給x64、opencv版本是455、Release的版本使用的property 已產生此版本的屬性,待會就用這個屬性設定opencv的變數\n使用 Property Manager 設定OpenCV的環境 記得因為我們是使用 Release x64 版本的屬性所以上面要改一下\n基本上打到第2層,就會有提示字出現之後,就表示設定成功了,設定一下起始專案。\n寫一個簡單的程式測試一下 opencv 的設定 // loadimg.cpp : 此檔案包含 \u0026#39;main\u0026#39; 函式。程式會於該處開始執行及結束執行。\r//\r#include \u0026lt;iostream\u0026gt;\r#include \u0026lt;opencv2/core/core.hpp\u0026gt;\r#include \u0026lt;opencv2/highgui/highgui.hpp\u0026gt;\rusing namespace std;\rusing namespace cv;\rint main()\r{\rMat img;\rimg = imread(\u0026#34;C:\\\\Users\\\\b51ak\\\\Pictures\\\\promotion.png\u0026#34;);\rnamedWindow(\u0026#34;figure 1\u0026#34;, WINDOW_AUTOSIZE);\rimshow(\u0026#34;figure 1\u0026#34;, img);\rstd::cout \u0026lt;\u0026lt; \u0026#34;Hello World!\\n\u0026#34;;\rwaitKey(0);\rreturn 0;\r} ","permalink":"https://weizongchen.github.io/blog/opencv_env/","tags":["OpenCV"],"title":"OpenCV 環境安裝"},{"categories":null,"contents":"","permalink":"https://weizongchen.github.io/blog/m460-level0/","tags":null,"title":""}] \ No newline at end of file diff --git a/index.xml b/index.xml index 437641b..76b21ba 100644 --- a/index.xml +++ b/index.xml @@ -6,7 +6,26 @@ Recent content on 暐宗's Blog Hugo -- gohugo.io zh-tw - Fri, 03 Feb 2023 23:24:00 +0800 + Mon, 05 Jun 2023 23:24:00 +0800 + + MA35D1 Control + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + Mon, 05 Jun 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + 要找MA35D1的兩根pin腳給PWM 新唐定義 PG1 PG2 的地方 設定 device tree Kernel configuration settin + + + + M460 Level0 說明 + https://weizongchen.github.io/blog/m460_level0/ + Thu, 25 May 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/m460_level0/ + 控制 LED 0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他 +uint32_t* ptr_mode; ptr_mode = (uint32_t*)(0x40004000 + 0x1c0); *ptr_mode = 0x00000100; uint32_t* ptr_value; ptr_value = (uint32_t*)(0x40004000 + 0x1c8); *ptr_value = 0xFFFFFFEF; 負源觸發 補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示: + + 將Tensorflow Lite Library加到MA35D1的Yocto中 https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/ @@ -254,5 +273,14 @@ Clock, LDO control Rigister, PDBIASEN 這個 bit 系統環境 Windows 10 VS 2019 OpenCV 4.5.5 選擇 Windows 版本的OpenCV download下來 解壓縮到指定資料夾 可以在C 根目錄建一個 OpenCV 資料夾,在OpenCV資料夾下再建一個OpenCV4. + + + https://weizongchen.github.io/blog/m460-level0/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://weizongchen.github.io/blog/m460-level0/ + + + diff --git a/page/2/index.html b/page/2/index.html index 55fd531..a88d541 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -146,6 +146,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -191,23 +194,23 @@

    Social

    @@ -215,23 +218,23 @@

    Social

    @@ -239,23 +242,23 @@

    Social

    @@ -263,23 +266,23 @@

    Social

    @@ -287,23 +290,23 @@

    Social

    @@ -311,23 +314,23 @@

    Social

    @@ -417,6 +420,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/page/3/index.html b/page/3/index.html index 5815bf8..eab4935 100644 --- a/page/3/index.html +++ b/page/3/index.html @@ -146,6 +146,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -191,23 +194,23 @@

    Social

    @@ -215,14 +218,14 @@

    Social

    @@ -239,23 +242,23 @@

    Social

    @@ -263,23 +266,23 @@

    Social

    @@ -287,23 +290,23 @@

    Social

    @@ -311,23 +314,23 @@

    Social

    @@ -417,6 +420,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/page/4/index.html b/page/4/index.html index 98f0621..ef2b3f4 100644 --- a/page/4/index.html +++ b/page/4/index.html @@ -146,6 +146,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -191,23 +194,23 @@

    Social

    @@ -215,23 +218,23 @@

    Social

    @@ -239,23 +242,23 @@

    Social

    @@ -263,23 +266,23 @@

    Social

    @@ -287,23 +290,23 @@

    Social

    @@ -311,23 +314,23 @@

    Social

    @@ -417,6 +420,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/page/5/index.html b/page/5/index.html index 9577db2..ed220ed 100644 --- a/page/5/index.html +++ b/page/5/index.html @@ -146,6 +146,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -188,6 +191,54 @@

    Social

    +
    + +
    + +
    + +
    +
    @@ -297,6 +348,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/search/index.html b/search/index.html index 68bda27..45e3930 100644 --- a/search/index.html +++ b/search/index.html @@ -177,6 +177,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/sitemap.xml b/sitemap.xml index 9361033..2e3c6d0 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,25 +2,37 @@ - https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/ - 2023-02-03T23:24:00+08:00 - https://weizongchen.github.io/blog/ - 2023-02-03T23:24:00+08:00 + 2023-06-05T23:24:00+08:00 https://weizongchen.github.io/categories/ - 2023-02-03T23:24:00+08:00 + 2023-06-05T23:24:00+08:00 https://weizongchen.github.io/tags/ma35d1/ - 2023-02-03T23:24:00+08:00 + 2023-06-05T23:24:00+08:00 + + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + 2023-06-05T23:24:00+08:00 https://weizongchen.github.io/tags/ - 2023-02-03T23:24:00+08:00 + 2023-06-05T23:24:00+08:00 https://weizongchen.github.io/categories/%E5%AE%89%E8%A3%9D%E6%AD%A5%E9%A9%9F%E6%96%87%E4%BB%B6/ - 2023-02-03T23:24:00+08:00 + 2023-06-05T23:24:00+08:00 https://weizongchen.github.io/ + 2023-06-05T23:24:00+08:00 + + https://weizongchen.github.io/blog/m460_level0/ + 2023-05-25T23:24:00+08:00 + + https://weizongchen.github.io/tags/cortex-m4/ + 2023-05-25T23:24:00+08:00 + + https://weizongchen.github.io/categories/%E5%BF%83%E5%BE%97/ + 2023-05-25T23:24:00+08:00 + + https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/ 2023-02-03T23:24:00+08:00 https://weizongchen.github.io/blog/ma35d1_extra_package_yocto/ @@ -37,9 +49,6 @@ https://weizongchen.github.io/blog/ma35d1_spi/ 2022-10-06T23:24:00+08:00 - - https://weizongchen.github.io/tags/cortex-m4/ - 2022-09-13T23:24:00+08:00 https://weizongchen.github.io/blog/ma35d1_rtp_memory/ 2022-09-13T23:24:00+08:00 @@ -118,5 +127,7 @@ https://weizongchen.github.io/search/ 2019-10-29T13:49:23+06:00 + + https://weizongchen.github.io/blog/m460-level0/ diff --git a/tags/cortex-a/index.html b/tags/cortex-a/index.html index 11ab5df..ff4b4a4 100644 --- a/tags/cortex-a/index.html +++ b/tags/cortex-a/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -267,6 +270,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/cortex-m4/index.html b/tags/cortex-m4/index.html index caa5c09..5e7e401 100644 --- a/tags/cortex-m4/index.html +++ b/tags/cortex-m4/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,6 +193,30 @@

    Social

    +
    + +
    +
    + 解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法
    @@ -307,30 +334,6 @@

    Social

    -
    - -
    -
    @@ -351,11 +354,14 @@

    Social

  • 2
  • +
  • + 3 +
  • - +
  • @@ -407,6 +413,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/cortex-m4/index.xml b/tags/cortex-m4/index.xml index a067b93..0e0fecc 100644 --- a/tags/cortex-m4/index.xml +++ b/tags/cortex-m4/index.xml @@ -6,7 +6,17 @@ Recent content in Cortex M4 on 暐宗's Blog Hugo -- gohugo.io zh-tw - Tue, 13 Sep 2022 23:24:00 +0800 + Thu, 25 May 2023 23:24:00 +0800 + + M460 Level0 說明 + https://weizongchen.github.io/blog/m460_level0/ + Thu, 25 May 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/m460_level0/ + 控制 LED 0x4000_4000 是一個32位元的記憶體位址,所以我需要一個 uint32_t* 去接他 +uint32_t* ptr_mode; ptr_mode = (uint32_t*)(0x40004000 + 0x1c0); *ptr_mode = 0x00000100; uint32_t* ptr_value; ptr_value = (uint32_t*)(0x40004000 + 0x1c8); *ptr_value = 0xFFFFFFEF; 負源觸發 補充說明 : 也可以使用 Keil 的 tool 看,如下圖所示: + + 解決 MA35D1 M4 SRAM 128KB 不夠,調用A35 DDR space 384KB 的方法 https://weizongchen.github.io/blog/ma35d1_rtp_memory/ diff --git a/tags/cortex-m4/page/2/index.html b/tags/cortex-m4/page/2/index.html index 36d8ec0..caa218b 100644 --- a/tags/cortex-m4/page/2/index.html +++ b/tags/cortex-m4/page/2/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,6 +193,30 @@

    Social

    +
    + +
    +
    + Timer Delay 說明 (by M460)
    @@ -307,30 +334,6 @@

    Social

    -
    - -
    -
    @@ -351,11 +354,14 @@

    Social

  • 2
  • -
  • - +
  • + 3
  • -
  • - +
  • + +
  • +
  • +
  • @@ -407,6 +413,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/cortex-m4/page/3/index.html b/tags/cortex-m4/page/3/index.html new file mode 100644 index 0000000..118c557 --- /dev/null +++ b/tags/cortex-m4/page/3/index.html @@ -0,0 +1,386 @@ + + + + 暐宗's Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    +
    +
    + + +
    +
    + +
    + +

    About Me

    + + + +

    Embedded Linux System +Andoird App and MySQL Server +Deep Learning

    + Know More + +
    + +
    +

    Category

    + +
    + +
    +

    Tag

    + +
    + +
    +

    Social

    + +
    + +
    +
    + + + +
    +
    + + +
    + +
    + +
    +
    + + + +
    + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/index.html b/tags/index.html index e17ffb5..7a6891b 100644 --- a/tags/index.html +++ b/tags/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -338,6 +341,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/index.xml b/tags/index.xml index caa18a9..0ca8edf 100644 --- a/tags/index.xml +++ b/tags/index.xml @@ -6,11 +6,11 @@ Recent content in Tags on 暐宗's Blog Hugo -- gohugo.io zh-tw - Fri, 03 Feb 2023 23:24:00 +0800 + Mon, 05 Jun 2023 23:24:00 +0800 Ma35d1 https://weizongchen.github.io/tags/ma35d1/ - Fri, 03 Feb 2023 23:24:00 +0800 + Mon, 05 Jun 2023 23:24:00 +0800 https://weizongchen.github.io/tags/ma35d1/ @@ -19,7 +19,7 @@ Cortex M4 https://weizongchen.github.io/tags/cortex-m4/ - Tue, 13 Sep 2022 23:24:00 +0800 + Thu, 25 May 2023 23:24:00 +0800 https://weizongchen.github.io/tags/cortex-m4/ diff --git a/tags/ma35d1/index.html b/tags/ma35d1/index.html index 1b59c3e..4e0c4b7 100644 --- a/tags/ma35d1/index.html +++ b/tags/ma35d1/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,6 +193,30 @@

    Social

    + MA35D1 Control + +
    + + 安裝步驟文件 + + MA35D1 Control + +

    在做Machine Learning 專案的時候,image Classfication的輸送帶要用PWM控制物件的 SG90 伺服馬達

    + read more +
    +
    +
    + +
    +
    + 將Tensorflow Lite Library加到MA35D1的Yocto中
    @@ -307,30 +334,6 @@

    Social

    -
    - -
    -
    @@ -407,6 +410,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/ma35d1/index.xml b/tags/ma35d1/index.xml index 001ba44..ea6fb79 100644 --- a/tags/ma35d1/index.xml +++ b/tags/ma35d1/index.xml @@ -6,7 +6,16 @@ Recent content in Ma35d1 on 暐宗's Blog Hugo -- gohugo.io zh-tw - Fri, 03 Feb 2023 23:24:00 +0800 + Mon, 05 Jun 2023 23:24:00 +0800 + + MA35D1 Control + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + Mon, 05 Jun 2023 23:24:00 +0800 + + https://weizongchen.github.io/blog/ma35d1_pwm_control/ + 要找MA35D1的兩根pin腳給PWM 新唐定義 PG1 PG2 的地方 設定 device tree Kernel configuration settin + + 將Tensorflow Lite Library加到MA35D1的Yocto中 https://weizongchen.github.io/blog/add_tensorflow_lite_to_ma35d1_yocto/ diff --git a/tags/ma35d1/page/2/index.html b/tags/ma35d1/page/2/index.html index bd5194f..4298724 100644 --- a/tags/ma35d1/page/2/index.html +++ b/tags/ma35d1/page/2/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -190,6 +193,30 @@

    Social

    +
    + +
    +
    + MA35D1 M4 使用設定
    @@ -311,6 +338,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/opencv/index.html b/tags/opencv/index.html index ca76b7c..10e991c 100644 --- a/tags/opencv/index.html +++ b/tags/opencv/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -267,6 +270,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • diff --git a/tags/tool/index.html b/tags/tool/index.html index 8b2eee6..4c66f95 100644 --- a/tags/tool/index.html +++ b/tags/tool/index.html @@ -145,6 +145,9 @@

    Category

  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件
  • @@ -339,6 +342,9 @@
    Categories
  • 安裝步驟文件
  • +
  • 心得 +
  • 說明文件