2023年11月20日 星期一

關於 FT260Q 開發版 DS_UMFT260EV1A操作方法(Windows)

 關於 FT260Q 開發版 DS_UMFT260EV1A I2C操作方法(Windows)


FT260Q 對I2C的指令做的比較單純, 大部份FT260Q已包裹起來(類似Linux 的 I2C_dev )

如果想要自己下達I2C每一個步驟的指令, 可以考慮使用CH341A

CH341A優點是可以完全自行控制, 缺點是程式碼要增加百倍.

(CH341也有提供簡單的包裹式指令集)



SCL : GPIO0

SDL : GPIO1

開發版上面還多掛了一顆 EEPROM AT24C02D

Device Address: 0x50

如果要取消這顆EEPROM , 把開發版之 JP8 切斷




開發版 DS_UMFT260EV1A
https://ftdichip.com/products/umft260ev1a/

EEPROM AT24C02D
https://www.microchip.com/en-us/product/at24c02d

FT260Q 
https://ftdichip.com/products/ft260q/


LibFT260
Application Note AN_395 User Guide for LibFT260 
https://www.ftdichip.com/Support/Documents/AppNotes/AN_395_User_Guide_for_LibFT260.pdf
這是原廠提供的一組函式庫,可以將指量傳輸給FT260Q
https://ftdichip.com/software-examples/
最下面那個沒有說明的 Libft260
https://ftdichip.com/wp-content/uploads/2022/10/LibFT260-v1.1.6.zip

解壓縮後
\LibFT260-v1.1.6\imports\LibFT260\inc\LibFT260.h
\LibFT260-v1.1.6\imports\LibFT260\lib\i386\LibFT260.lib, LibFT260.dll 

範例程式 (須要使用 Visual Studio )
\LibFT260-v1.1.6\samples\I2C

原始範例程式可以使用 Device Address  0x50 對EEPROM AT24C02D直接讀寫.

下面是直接修改對EEPROM AT24C256 直接讀寫. 

// Open Device
    FT260_HANDLE mhandle1 = INVALID_HANDLE_VALUE;
    FT260_STATUS ftStatus = FT260_OK;
    DWORD devNum = 0;
    FT260_CreateDeviceList(&devNum);

    // #define VID 0x0403  #define PID 0x6030
    ftStatus = FT260_OpenByVidPid(VID ,PID, 0, &mhandle1) ;
    printf("FT260_OpenByVidPid = %d\n",ftStatus );

    ftStatus = FT260_I2CMaster_Init(mhandle1, 100);


// (5)Read EEPROM 
 unsigned long len;
 DWORD writeLength = 0;
 DWORD readLength = 0;
 char dataw[10], datar[10];

 gI2CAddr = 0x51;
 writeLength = 0;
 dataw[0] = 0x00;
 dataw[1] = 0x00;
 FT260_I2CMaster_Write(mhandle1, gI2CAddr, FT260_I2C_START, &dataw, 2, &writeLength);
 writeLength = 0;
 len = 8;
 FT260_I2CMaster_Read(mhandle1, gI2CAddr, (FT260_I2C_FLAG)(FT260_I2C_REPEATED_START | FT260_I2C_STOP),
     datar, len, &readLength, 5000);



// (6)Write EEPROM 

 unsigned long len;
 DWORD writeLength = 0;
 char data[10];
 char addr;
 FT260_STATUS ftStatusW1, ftStatusW2 = FT260_OK;

 gI2CAddr = 0x51;
 writeLength = 0;
 data[0] = 0x00; // Data Address MSB
 data[1] = 0x00; // Data Address LSB
 
 ftStatusW1 = FT260_I2CMaster_Write(mhandle1, gI2CAddr, FT260_I2C_START, &addr, 2, &writeLength);
 data[0] = 0xAA;  // Write Data 
 data[1] = 0x22;
 data[2] = 0x33;
 data[3] = 0x44;
 data[4] = 0x55;
 data[5] = 0x66;
 data[6] = 0x77;
 data[7] = 0x88;
 ftStatusW2 = FT260_I2CMaster_Write(mhandle1, gI2CAddr, FT260_I2C_STOP, &data[0], 8, &writeLength);

上圖和規格書的要求很類似




比較難的是  I2C_FLAG 的選擇
建議是各種指令都下一次, 使用分析儀來解析其不同之處

enum FT260_I2C_FLAG
{
FT260_I2C_NONE  = 0,
FT260_I2C_START = 0x02,
FT260_I2C_REPEATED_START = 0x03,
FT260_I2C_STOP  = 0x04,
FT260_I2C_START_AND_STOP = 0x06
};

相關解釋可以查看AN_395_User_Guide_for_LibFT260.pdf
Page 20  4.2 I2C Master Functions







2023年11月9日 星期四

ASUS Tinker Board 2S Debian 使用實體電源開關

當  Tinker Board 2S Debian中按了系統左上角的 shotdown後ㄉ

Tinker Board 2S除了拔電源開關讓其啟動, 

只能使用實體電源開關讓其再次啟動,

 

 注意

  這個會和 ASUS Tinker Board 2S 關閉睡眠功能 那邊有點衝突

  當 suspend 被關時, 會出現

  GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Permission denied

  所以要安裝實體電源開關,   不要加入 



Debian 系統設定


2.無段開關


3.

因PCB 沒有印刷, 所以要注意方向, 很容易搞錯.
MASKROM 是用來燒錄UBOOT或EMMC時使用

4.








ASUS Tinker Board 2S Debian 安裝 Teamviewer Host

 下載 https://www.teamviewer.com/hk/download/linux/

 TeamViewer Host  Debian arm64-64bit


$ sudo dpkg -i teamviewer-host_15.47.3_arm64.deb

ASUS Tinker Board 2S 設定 GPIO(Using the sysfs Interface)

 ASUS Tinker Board 2S 設定 GPIO(Using the sysfs Interface)


https://tinker-board.asus.com/forum/index.php?/topic/14984-gpio/


方法一:

 Using the sysfs Interface

就是直接對 Linux File System 的 /sys/class/gpio/ 文字檔進行讀寫

方法二:

使用 ASUS 提供的  GPIO WiringPi for C library

https://github.com/TinkerBoard/TinkerBoard/wiki/User-Guide#sample-code-for-tinker-board-2-series

http://dlcdnet.asus.com/pub/ASUS/mb/Linux/Tinker_Board_2GB/GPIO_API_for_C.ZIP


方法三:

使用 ASUS API Programming方式(只有使用範例, 無原始碼)
https://tinker-board.asus.com/tw/documentation/ter.html#api/

方法一說明:

1. 先到wiki 查詢 2S GPIO pin對應到 Linux Debian之Device Path

  (Tinker Board 2S 每一個GPIO Pin 對應到Linux GPIO Index)

  GPIO Config Table for Tinker Board 2 series:

  https://github.com/TinkerBoard/TinkerBoard/wiki/User-Guide#gpio-config-table-for-tinker-board-2-series






  

 例如本次要試驗的是 Tinker Board 2S GPIO pin-18 

  對應到 Debian之Device Path是 GPIO: /sys/class/gpio/gpio87

  


2. 參考網站

  GPIO Programming: Using the sysfs Interface

    https://www.ics.com/blog/gpio-programming-using-sysfs-interface

  風火輪對 /sys/class/gpio 之解釋文

    https://wiki.youyeetoo.cn/tinker/page/DebianSystem/User_GPIO

3. 設定

  $ sudo bluefish /boot/config.txt

    下面這一行 GPIO pin-18 為 spi5 不可以打開

    #intf:spi5=off

4. 指令

    > Device Path是 GPIO: /sys/class/gpio/gpio87

    $ sudo su

    $ cd /sys/class/gpio

    $ echo 87 >/sys/class/gpio/export

    $ ls /sys/class/gpio/gpio87/

    $ echo out >/sys/class/gpio/gpio87/direction

    $ echo 0 >/sys/class/gpio/gpio87/value

     > 電錶量測 Tinker Board 2S GPIO pin-18 會是 0 

    $ echo 1 >/sys/class/gpio/gpio87/valu

     > 電錶量測 Tinker Board 2S  GPIO pin-18 會是 3.3v


5. C/C++ Example
   How to Control GPIO Hardware from C or C++
   https://www.ics.com/blog/how-control-gpio-hardware-c-or-c
   https://github.com/tranter/blogs/tree/master/gpio/part5


2023年11月8日 星期三

ASUS Tinker Board 2S - Debian I2C TCA9539

 

TI TCA9539

16-bit 1.65- to 5.5-V I2C/SMBus I/O expander with interrupt, reset & config registers


IO-EXPANDER-EVM: I2C and SMBus IO Expander Evaluation Module






1. 修改  /boot/config.txt 內容
intf:i2c6=on    /* 原始前面有個 # 要去除, 把 off 改為on */

2. 連接 I2C
  SCL: IO-EXPANDER J8 SCL
  SDA: IO-EXPANDER J8 SDA
  GND: IO-EXPANDER J7 GND
  VCC: IO-EXPANDER J9 VCC

3.Device Address
PS: IO Expander EVM User's Guide (Rev. A) 這一片是共用PCB.
TCA6424A  0100010 0x22 
TCA9539     1110111 0x77 



  


GPIO設定, 主要是在Registers 6 和7


 但這片 IO Expander EVM 另外拉了幾條線用於顯示LED燈
 可以直接改用J13 來測試GPIO


第一個是 Device Address 
    i2cmsg.addr  = nDevAddr;
第二個是  Registers 6或7
第三個就是 GPIO Pin 0到N 的 GPIO ON/OFF


4. Linux IOCTL 範例程式


#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define DEFAULT_I2C_BUS      "/dev/i2c-6"
// 0100010 0x22 TCA6424A
// 1110111 0x77 TCA9539
#define DEFAULT_TCA9539_ADDR 0x77

int TCA9539_write( int nFile, unsigned int nDevAddr, unsigned int nRegConfig,
                  unsigned char *pBuf, unsigned char nLen)
{
  struct i2c_rdwr_ioctl_data msg_rdwr;
  struct i2c_msg i2cmsg;
  int nRecLen;
  unsigned char sI2cBuf[0xFF];
  unsigned char *pI2cBuf = &sI2cBuf[0];

  msg_rdwr.msgs = &i2cmsg;
  msg_rdwr.nmsgs = 1;

  pI2cBuf[0] = (unsigned char)nRegConfig;
  pI2cBuf[1] = pBuf[0];
  i2cmsg.addr  = nDevAddr;
  i2cmsg.flags = 0;  // Write
  i2cmsg.len   = 2;
  i2cmsg.buf   = pI2cBuf;
  if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr)) < 0)
  {
   perror("W5A-ioctl()");
   fprintf( stderr,"W5B-ioctl %d\n%s\n", nRecLen, strerror(errno));
   return -1;
  }
  else
   return nRecLen;
}

int TCA9539_read( int nFile, unsigned int nDevAddr, unsigned int nRegConfig,
                  unsigned char *pBuf, unsigned char nLen)
{
  struct i2c_rdwr_ioctl_data msg_rdwr;
  struct i2c_msg i2cmsg[2];
  unsigned char sAdsBuf[3];
  unsigned char *pAdsBuf = &sAdsBuf[0];
  int nRecLen;

  msg_rdwr.msgs = i2cmsg;
  msg_rdwr.nmsgs = 2;

  pAdsBuf[0] = (unsigned char)nRegConfig;
  i2cmsg[0].addr  = nDevAddr;
  i2cmsg[0].flags = 0;  // Write
  i2cmsg[0].len   = 1;
  i2cmsg[0].buf   = pAdsBuf; 
    
  i2cmsg[1].addr  = nDevAddr;
  i2cmsg[1].flags = I2C_M_RD;  // read data, from slave to master
  i2cmsg[1].len   = nLen;
  i2cmsg[1].buf   = pBuf;

  if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr))<0)
  {
   perror("R5-TCA9539_read ioctl failed");
   fprintf(stderr,"R6-TCA9539_read ioctl returned %d\n", nRecLen);
   return -1;
  }
  else
  {
   return nRecLen;
  } 
}

int main(void)
{
 int nDevAddr = DEFAULT_TCA9539_ADDR;
 int nFile, nWriteLen, nReadLen, nRecLen; 
 int nRc, nRegConfig;
 const char *pDevice = DEFAULT_I2C_BUS; //"/dev/i2c-6";
 unsigned char sBuf[0x10], sStrBuf[0x10];
 unsigned char *pBuf= &sBuf[0];
 unsigned long nFuncs;
 

 printf("Hello! This is a test prgoram.\n");
 nFile = open( pDevice, O_RDWR);
 if( nFile < 0)
  err( errno, "O1-Tried to open '%s'", pDevice);
 else
  printf( "\nO2-Open dev i2c-6 success.\n");

 if( ioctl( nFile, I2C_FUNCS, &nFuncs) < 0)
 {
  perror("W5A-ioctl()");
  fprintf(stderr, "Error: Could not get the adapter functionality matrix: %s\n",
  strerror(errno));
  close( nFile);
  exit(0);
 }
 ioctl( nFile, I2C_TIMEOUT,2); // TIMEOUT
 ioctl( nFile, I2C_RETRIES,1); // retry count
    
 nRc = ioctl( nFile, I2C_SLAVE, nDevAddr);
 if( nRc < 0)
 {
  err(errno, "O3-Tried to set device address '0x%02x'", nDevAddr);
  exit(0);
 }
 else
 {
  printf("O4-Dev i2c-6 Set Address 0x50 success.\n");
 }

 
 // https://www.ti.com/product/zh-tw/TCA9539 // Pull High
 // Table 7. Registers 6 And 7 (Configuration Registers)
 nDevAddr = DEFAULT_TCA9539_ADDR;
 nRegConfig = 0x06; // Registers 6 Configuration
 pBuf[0] = 0x00;  // Set GPIO Pin-0 to Pin-7 all Pull Low
 nWriteLen = 1;
 nRecLen = TCA9539_write( nFile, nDevAddr, nRegConfig, pBuf, nWriteLen);
 if( nRecLen < 0)
 {
  printf( "W3A-TCA9539_write failed.\n");
  exit(0);
 }
 else
 {
  fprintf( stderr, "W6-Set gpio pin0-7: 0x%02x\n", pBuf[0]);
 } 
 nRegConfig = 0x07;  // Registers 7 Configuration
 pBuf[0] = 0x00;  // Set GPIO Pin-10 to Pin-17 all Pull Low
 nWriteLen = 1;
 nRecLen = TCA9539_write( nFile, nDevAddr, nRegConfig, pBuf, nWriteLen);
 if( nRecLen < 0)
 {
  printf( "W3A-TCA9539_write failed.\n");
  exit(0);
 }
 else
 {
  fprintf( stderr, "W7-Set gpio pin10-17: 0x%02x\n", pBuf[0]);
 } 

 // Read Process
 nDevAddr = DEFAULT_TCA9539_ADDR;
 nRegConfig = 0x06; // Registers 6 Configuration
 pBuf[0] = 0xFF;    // Read GPIO Pin-0 to Pin-7 
 nReadLen = 1;
 nRecLen = TCA9539_read( nFile, nDevAddr, nRegConfig, pBuf, nReadLen);
 if( nRecLen < 0)
 {
  printf("R1-TCA9539_read failed.\n");
  exit(1);
 }
 else
 {
  fprintf( stderr, "W6-Get gpio pin0-7: 0x%02x\n", pBuf[0]);
 }   
 nRegConfig = 0x07; // Registers 7 Configuration
 pBuf[0] = 0xFF;    // Read GPIO Pin-10 to Pin-17 
 nReadLen = 1;
 nRecLen = TCA9539_read( nFile, nDevAddr, nRegConfig, pBuf, nReadLen);
 if( nRecLen < 0)
 {
  printf("R1-TCA9539_read failed.\n");
  exit(1);
 }
 else
 {
  fprintf( stderr, "W6-Get gpio pin10-17: 0x%02x\n", pBuf[0]);
 }   
 close( nFile);
 return 0;
}




5.

















ASUS Tinker Board 2S 關閉睡眠功能

 Disable Suspend and Hibernation

 $ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

 $ reboot

 $ systemctl status sleep.target suspend.target hibernate.target hybrid-sleep.target

 $ sudo vim /etc/systemd/logind.conf 

   [Login] 

   HandleLidSwitch=ignore 

   HandleLidSwitchDocked=ignore 



 Enable Suspend and Hibernation

 $ sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target


ASUS Tinker Board 2S 安裝 Eclipse IDE c++ Developers


  $ sudo apt update

  $ sudo apt list --upgradable

  $ sudo apt upgrade

  $ sudo apt install default-jre

  $ sudo apt-get install  gdb

  $ sudo gbd --version

  > TH2S 開啟 chromium (主畫面下方地球圖示)

   https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2023-09/R/eclipse-cpp-2023-09-R-linux-gtk-aarch64.tar.gz

  > 下載 Eclipse IDE c++ 選擇 AArch64版本

  > 畫面左邊 File System -> linaro -> Downloads

    滑鼠點擊2下 eclipse-cpp-2023-09-R-linux-gtk-aarch64.tar.gz

    開啟目錄 home/linaro/Downloads/eclipse-cpp-2023-09-R-linux-gtk-aarch64/eclipse-installer

    滑鼠點擊 eclipse-inst

    選擇 Eclipse IDE c++

    選擇目錄 home/linaro/eclipse

    滑鼠點擊 home/linaro/eclipse/eclipse

    或左上角 Application-> Other -> Eclipse IDE c++ Developers


    . File -> New -> c/c++ Project

      -> C++ Managed Build

      -> Project name: test

      -> Project type: Hello World C++ Project

      -> Toolchains: Cross GCC

      -> 點擊 Finsh

      -> menu Project->Build All

      -> menu Run->Run

         選擇 Local C/C++ Application


ASUS Tinker Board 2S 燒錄Debian到eMMC

 1. ASUS 官網下載 Debian Imagefile

   https://tinker-board.asus.com/tw/download-list.html?product=tinker-board-2s

   > Tinker Board 2 /2S Debian 11 (kernel 5.10) v3.0.6 023/07/31 1.31 GB




2. 把Debian燒錄到一片 SD Card中(開機用) 

   燒錄完成後把SD Card插入 ASUS Tinker Board 2S

3. 把ASUS Tinker Board 2S的 J3 切換為 MASKROM模式.



4. 把balenaEtcher 把 Debian Imagefile 燒錄到 ASUS Tinker Board 2S

https://etcher.balena.io/#download-etcher



5. 燒錄完成後, 把 ASUS Tinker Board 2 J3 切換為 Default模式

6. 把 ASUS Tinker Board 2 中 SD Card移除

7. 開啟電源

2023年11月7日 星期二

ASUS Tinker Board 2S - Debian I2C AT24C256

  ASUS Tinker Board 2S - Debian I2C  Example

Tinker Board 2 - Wiki

https://tinker-board.asus.com/forum/index.php?/topic/15253-waveshare-tinker-board-2-wiki/


I2C 速度

低速模式, 傳輸速度 100KHz.

快速模式 (Fast-mode, Fm) 傳輸速度 400KHz

高速模式 (High-speed mode, Hs-mode) 3.4MHz

https://tinker-board.asus.com/forum/index.php?/topic/15458-i2c-speed/

Tinker Board 2S預設是 40k (400KHz)



參考網頁

/i2c/dev-interface

https://www.kernel.org/doc/Documentation/i2c/dev-interface

Understanding I2C Communication in Linux

https://www.linkedin.com/pulse/understanding-i2c-communication-linux-beginners-guide-soheil-nazari

Full IOCTL Example
https://stackoverflow.com/questions/9974592/i2c-slave-ioctl-purpose

也可以使用 ASUS API Programming方式(只有使用範例, 無原始碼)
https://tinker-board.asus.com/tw/documentation/ter.html#api/

使用WiringPi C library for Debian也是一個方式
https://github.com/TinkerBoard/TinkerBoard/wiki/Tinker-Board-2-&-2S#3341-wiringpi-c-library-for-debian

Mraa library for android
https://github.com/TinkerBoard/TinkerBoard/wiki/Tinker-Board-2-&-2S#3342-mraa-library-for-android


下面這方式是用Linux內含標準 i2c_dev (ioctl)方法

1. 修改  /boot/config.txt 內容

intf:fiq_debugger=on

#intf:uart0=off

#intf:uart4=off

intf:i2c6=on    /* 原始前面有個 # 要去除, 把 off 改為on */

#intf:i2c7=off

#intf:i2s0=off

#intf:spdif=off

#intf:spi1=off

#intf:spi5=off

#intf:pwm0=off

#intf:pwm1=off

#intf:pwm3a=off

#intf:test_clkout2=off

2. 把連接 I2C

  SCL: pin-3

  SDA:  pin-5

  GND: pin 5

  VCC: pin 1 (3.3V)

3. 蝦皮購買的 AT24C256 EEPROM 儲存模組


https://ww1.microchip.com/downloads/en/devicedoc/doc0670.pdf







 在上圖 AT24C256 EEPROM 儲存模組的 A0,A1,A2 都是 0

 注意: 這顆是AT24C256B 所以只能調整A0及A1 (A2怎調整都是0)
 所以 Device Address 就是  1010000  (不含R/W) 為 0x50
 在填入i2c_msg  中的addr 只要填入 0x50 
  i2cmsg.addr  = 0x50; 
 那個 R/W bit 在 ioctl()的Read或Write時會自動幫忙位移及填寫

 下圖是 A0 設定為 1 這樣Device Address就是 0b1010001 (0x51)




上圖是指 先送1Byte Device Address
再送 2Byte 要寫入的 EEPROM Data Address
(有些EEPROM AT24C02D是只要1個Byte的Data address, 請自行查閱規格書)
後面是實際要寫到 EEPROM 的 Data Buffer
(至於START/ACK/STOP這些旗標,在ioctl內層會幫忙回應硬體)
注意: 這個Device 單次最大64Byte, 還有這EEPROM讀寫速度並不快, 因此處理連續讀寫要慢點.



上圖是指 先送1Byte Device Address
再送 2Byte 要讀取的 EEPROM Data Address
Device會回應1Byte Device Address及要讀取 EEPROM 的 Data Buffer
但i2cmsg.buf    = pI2cBuf;  只會得到後面實際EEPROM 的 Data Buffer
那Device回應的1Byte Device Address  ioctl會自行處理
(至於START/ACK/STOP這些旗標,在ioctl內層會幫忙回應硬體)


下圖是AT24C02D的Page Write Command







4. 在Debian 終端機模式下 

$ mkdir testi2c

$ cd testi2c 

// download testi2c.c and save file

$ cc -version

$ cc -g testi2c.c -o testi2c


  


$ ./testi2c





5. Source Code

Write: 紅框區

Read: 藍框區

Write Command


Read Command




#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include <err.h>

#include <errno.h>

#include <string.h>

#include <linux/types.h>

#include <linux/i2c.h>

#include <linux/i2c-dev.h>


#include <sys/ioctl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>


#define DEFAULT_I2C_BUS        "/dev/i2c-6"

#define DEFAULT_EEPROM_ADDR  0x50            /* the 24C16 sits on i2c address 0x50 */

#define DEFAULT_NUM_PAGES     8                /* we default to a 24C16 eeprom which has 8 pages */

#define BYTES_PER_PAGE         256             /* one eeprom page is 256 byte */

#define MAX_BYTES                256             /* max number of bytes to write in one chunk */


int eeprom_write( int nFile, unsigned int nDevAddr, unsigned int nDataOffset,

                        unsigned char *pBuf, unsigned char nLen)

{

struct i2c_rdwr_ioctl_data msg_rdwr;

struct i2c_msg i2cmsg;

int nRecLen;

  unsigned char sI2cBuf[0xFF];

  unsigned char *pI2cBuf = &sI2cBuf[0];


if( nLen > MAX_BYTES)

{

fprintf(stderr,"W3-I can only write MAX_BYTES bytes at a time!\n");

return -1;

}


if( nLen + nDataOffset > 256)

{

fprintf(stderr,"W4-Sorry, len(%d)+offset(%d) > 256 (page boundary)\n", nLen, nDataOffset);

return -1;

}


msg_rdwr.msgs = &i2cmsg;

msg_rdwr.nmsgs = 1;


  pI2cBuf[0] = ((unsigned char *)&nDataOffset)[1];    

  pI2cBuf[1] = ((unsigned char *)&nDataOffset)[0];

  memcpy( pI2cBuf+2, pBuf, nLen);

  

i2cmsg.addr  = nDevAddr;

i2cmsg.flags = 0;  // Write

i2cmsg.len    = 2+nLen;

i2cmsg.buf    = pI2cBuf;

if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr)) < 0)

{

perror("W5A-ioctl()");

fprintf( stderr,"W5B-ioctl %d\n%s\n", nRecLen, strerror(errno));

    return -1;

}

else

{

if( pBuf != NULL)

{

     fprintf( stderr,"W7-Write %d bytes to eeprom at 0x%02x, offset %08x, Data: 0x%02x\n",

                 nLen, nDevAddr, nDataOffset, pBuf[0]);

    }                  

    return nRecLen;

  } 

}


int eeprom_read( int nFile, unsigned int nDevAddr, unsigned int nDataOffset,

                        unsigned char *pBuf, unsigned char nLen)

{

struct i2c_rdwr_ioctl_data msg_rdwr;

struct i2c_msg i2cmsg[2];

  unsigned char sAdsBuf[3];

  unsigned char *pAdsBuf = &sAdsBuf[0];

int nRecLen;


if( nLen > MAX_BYTES)

{

fprintf(stderr,"R3-I can only write MAX_BYTES bytes at a time!\n");

return -1;

}


msg_rdwr.msgs = i2cmsg;

msg_rdwr.nmsgs = 2;


  pAdsBuf[0] = ((unsigned char *)&nDataOffset)[1];    

  pAdsBuf[1] = ((unsigned char *)&nDataOffset)[0];

i2cmsg[0].addr  = nDevAddr;

i2cmsg[0].flags = 0;  // Write

i2cmsg[0].len    = 2;

i2cmsg[0].buf    = pAdsBuf; 

  i2cmsg[1].addr  = nDevAddr;

  i2cmsg[1].flags = I2C_M_RD;  // read data, from slave to master

i2cmsg[1].len    = nLen;

i2cmsg[1].buf    = pBuf;


if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr))<0)

{

perror("R5-eeprom_read ioctl failed");

fprintf(stderr,"R6-eeprom_read ioctl returned %d\n", nRecLen);

return -1;

}

else

{

   fprintf( stderr,"R7-Read %d bytes from eeprom at 0x%02x, offset %08x, Data: 0x%02x\n",

            nLen, nDevAddr, nDataOffset, pBuf[0]);

   return nRecLen;

  } 

}


int main(void)

{

 int nDevAddr = 0x50, nDataOffset, nRecLen;

 int nFile, nRc, nI, nH;

 int nRWTestCount = 1;


 const char *pDevice = DEFAULT_I2C_BUS; //"/dev/i2c-6";

 unsigned char sBuf[0xFF];

 unsigned char *pBuf= &sBuf[0];

 unsigned long nFuncs;


 printf("Hello! This is a test prgoram.\n");

  nFile = open( pDevice, O_RDWR);

  if( nFile < 0)

  err( errno, "O1-Tried to open '%s'", pDevice);

  else

  printf( "\nO2-Open dev i2c-6 success.\n");

  if (ioctl( nFile, I2C_FUNCS, &nFuncs) < 0)

  {

perror("W5A-ioctl()");

        fprintf(stderr, "Error: Could not get the adapter functionality matrix: %s\n",

      strerror(errno));

   close( nFile);

  exit(0);

}

ioctl( nFile, I2C_TIMEOUT,2);//  TIMEOUT

ioctl( nFile, I2C_RETRIES,1);// retry count

  nRc = ioctl( nFile, I2C_SLAVE, nDevAddr);

  if( nRc < 0)

  {

  err(errno, "O3-Tried to set device address '0x%02x'", nDevAddr);

  exit(0);

  }

  else

  {

    printf("O4-Dev i2c-6 Set Address 0x50 success.\n");

  }


 nDevAddr = 0x50;

 nDataOffset = 0;

 nWriteLen = 8;

 nRWTestCount = 8;

 for( nI = 0; nI < nRWTestCount; nI++)

 {

  sleep(1); // 2sec

  for( nH = 0; nH < 0xFF; nH++)

    pBuf[nH] = 20+nI+nH;

  nDataOffset = nI*nWriteLen;

  nRecLen = eeprom_write( nFile, nDevAddr, nDataOffset, pBuf, nWriteLen);

  if( nRecLen < 0)

  {

    printf( "W3A-eeprom_write failed.\n");

  exit(0);

  }

  else

  {

   fprintf( stderr, "W-%d: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",

            nDataOffset,

            pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]);

  }

 } 


 // Read Process

 fprintf( stderr, "\n\nR0-eeprom_Read start...\n");

 nDevAddr = 0x50;

 nReadLen = 8;

 for( nI = 0; nI < nRWTestCount; nI++)

 {

  for( nH = 0; nH < 0xFF; nH++)

    sBuf[nH] = 0xFF;

  sleep(1); // 2sec

  nDataOffset = nI*nReadLen;

  nRecLen = eeprom_read( nFile, nDevAddr, nDataOffset, pBuf, nReadLen);

  if( nRecLen < 0)

  {

    printf("R1-eeprom_read failed. %d\n", nI);

    exit(1);

  }

  else

  {

  fprintf( stderr, "R-%d: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",

              nDataOffset,

              pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]);

  }

 }    

 close( nFile);

 return 0;

}





2023年11月5日 星期日

Ubuntu 關於teamviewer的問題

 

使用Windows 連線Ubuntu teamviewer, 

Ubuntu 都會出現要求點選分享

不知如何解決


 


2023年11月2日 星期四

Ubuntu install SSH

  $ sudo apt-get install openssh-server

 $ sudo ps -e |grep ssh 

 $ sudo service ssh start

 Windwos 10端使用指令連接 Ubuntu

  C:> ssh XXX@192.168.1.60

Ubuntu 微軟英文字型

 安裝微軟英文字型,減少開啟MS Office文件時的排版移位。

sudo apt-get install ttf-mscorefonts-installer

安裝過程會出現「同意條款」,

請按「Tab鍵」移動光棒,按「空白鍵」選取。

Ubuntu Install unrar

 sudo apt-get install unrar

Ubuntu UltraEdit

 Ubuntu UltraEdit 

 http://www.ultraedit.com/downloads/uex.html

 sudo dpkg -i uex_4.2.0.11_amd64.deb

 30天到期後到用戶目錄下如:/home/michzel/.idm 資料夾下面,刪除uex資料夾

 或

 $ rm -rfd ~/.idm/uex  

 $ rm -rf ~/.idm/*.spl  

 $ rm -rf /tmp/*.spl 

 

 //..... 

 1. https://downloaddevtools-ds1.dlcddt.ir/Download.ashx?request=fcvUnEdWfLhugTVD7n1HgRomMiKPC4rJ75twuvhUSR2meuRdMw6vVlaepUt4dhqAtL%2f%2fyUEXRvcCxOIKf7QLuqD1wDtywalZn1yjKmiexD8InQ3eBRUiHsSQuf5yg%2bQfMGVfhnqJvS09jbKp3PffAmc5J3WEACF3mXqbfOkHPV6hmXyxbk7dwKKqFecx5IiKFT2zq5XOgAM3M7rDMCx5rxKorSyZ4avCiI0RWXwniKbDfwWE6RgS28%2buDMutcaSUfQ43XGrVs%2fpHvySl4JjeGH7m0JzR0olHv4u62%2fXvorc%3d

 https://downloaddevtools.com/en/product/1921/free-download-idm-ultraedit-1

  Files Password : DownloadDevTools.ir

 2. 解壓縮

 3. Ubuntu 檔案管理 -> 點 xxx.deb

    -> 滑鼠右鍵 -> 使用其他應用程式開啟

    -> 點選 "軟體安裝" -> 右上 "選取"

    -> 點選 右上 "安裝"

 4. 把 Crack\uex 複製到 /usr/bin/

 5. sudo chmod +x /usr/bin/uex

 6. sudo nano /etc/hosts

 7. 增加一行 

    127.0.0.1 licensing.ultraedit.com

Ubuntu 安裝 TeamViewer 14 舊版本

  安裝 TeamViewer 14 舊版本

 注意: TeamViewer 14 和 15 之間是不相容

 https://www.teamviewer.com/tw/download/previous-versions/previous-version-14x/

 1. 請先把原有版本移除

  sudo dpkg -r teamviewer

  最好連這目錄也刪除 /home/xxx/.config/teamviewer 

 2. Download teamviewer_14.7.48671_amd64.deb

     https://dl.teamviewer.com/download/linux/version_14x/teamviewer_14.7.48671_amd64.deb

 3. Ubuntu 檔案管理 -> 點 teamviewer_14.7.48671_amd64.deb

    -> 滑鼠右鍵 -> 使用其他應用程式開啟

    -> 點選 "軟體安裝" -> 右上 "選取"

    -> 點選 右上 "安裝"

    

Linux Install Android Studio

Linux  Install Android Studio 

// for Ubuntu x64

 $ sudo apt-get update

 $ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386

 

// Install Open JDK

 $ sudo apt-get update

 $ sudo apt-get install openjdk-8-jdk

 $ java -version

 $ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-*/jre

 

// Download Android Studio and SDK tools

// https://developer.android.com/studio?hl=zh-tw

// https://r1---sn-ipoxu-u2xr.gvt1.com/edgedl/android/studio/ide-zips/2022.3.1.20/android-studio-2022.3.1.20-linux.tar.gz

  $ tar -xf android-studio-2022.3.1.20-linux.tar.gz

  $ cd android-studio

  $ ./bin/studio.sh

   > 選擇 [Do not import settings] 並且按下OK

   開始安裝...

  $ sudo apt install qemu-kvm

  $ sudo adduser <your username> kvm

  $ sudo chown <your username> /dev/kvm

  $ sudo adduser jun kvm

  $ sudo chown jun /dev/kvm

  // 啟動android studio IDE 

  // 就是 android-studio-2022.3.1.20-linux.tar.gz解壓縮後的目錄  

  $ cd android-studio 

  $ cd ./ studio.sh 

  // 先新建一個簡單的專案  

   > Tools->SDK Manager

   > 左邊 Android SDK

   > 右邊 SDK Platforms

     選擇要的 Android API版本

   > 右邊 SDK Tools

   > 勾選 NDK 及其他想要的元件

   > 右下 Apply

   

  // 安裝完成後, 要新增Android Virtual Device (AVD) 才能夠用模擬器執行

   > Tools->Device Manager

      


2023年11月1日 星期三

QT 6.x Open Source Version Download and Install

QT 6.x Open Source Version Download and Install 

https://wiki.qt.io/Online_Installer_4.x#Selecting_a_mirror_for_opensource

QT 6.x 要求在Ubuntu 20.04之後版本才能安裝完成

 https://doc.qt.io/qt-6/supported-platforms.html

 

1. https://www.qt.io/

   右上角 "Download Try."

   右邊 "Download open souce >

   拉到下面 綠色方塊的 "Download the qt online Install

2.

 // Install GCC Compiler from Ubuntu Repositories

 $ sudo apt update

 $ sudo apt install build-essential

 $ gcc --version

 // Install Multiple GCC Versions on Ubuntu

 $ sudo apt install software-properties-common

 $ sudo add-apt-repository ppa:ubuntu-toolchain-r/test

  > enter

 $ sudo apt update 

 $ sudo apt install gcc-12 g++-12 gcc-13 g++-13 -y

 $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12 --slave /usr/bin/g++ g++ /usr/bin/g++-12

 $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 --slave /usr/bin/g++ g++ /usr/bin/g++-13

 $ sudo update-alternatives --config gcc

  > enter

 $ gcc --version


 $ sudo apt install libgl1-mesa-dev

 $ sudo apt install plocate

 $ locate libGL 

  // sudo ln -s /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 /usr/lib/libGL.so

 $ sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.1 /usr/lib/libGL.so


// Install Linux Android Studio 

 (在下方, 也可不裝)


// for Ubuntu x64

 $ sudo apt-get update

 $ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386

 

// Install Open JDK

 $ sudo apt-get update

 $ sudo apt-get install openjdk-8-jdk

 $ java -version

 $ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-*/jre

 

如果要用 QT for Android, 個人建議直接先安裝Android Studio比較容易

如果不需要, 直接跳到 "Install QT 6 Linux " 這一段

// Download Android Studio and SDK tools

// https://developer.android.com/studio?hl=zh-tw

// https://r1---sn-ipoxu-u2xr.gvt1.com/edgedl/android/studio/ide-zips/2022.3.1.20/android-studio-2022.3.1.20-linux.tar.gz

  $ tar -xf android-studio-2022.3.1.20-linux.tar.gz

  $ cd android-studio

  $ ./bin/studio.sh

   > 選擇 [Do not import settings] 並且按下OK

   開始安裝...

  $ sudo apt install qemu-kvm

  $ sudo adduser <your username> kvm

  $ sudo chown <your username> /dev/kvm

  $ sudo adduser jun kvm

  $ sudo chown jun /dev/kvm

  PS: 安裝完成後, 要新增Android Virtual Device (AVD) 才能夠用模擬器執行


 // Install QT 6 for Linux 

 $ cd Downloads

 $ chmod +x qt-unified-linux-x64-4.6.1-online.run

 // 因為官網慢容易出錯, 建議使用 QT mirror server 安裝

 $ ./qt-unified-linux-x64-4.6.1-online.run --mirror http://qt.mirror.constant.com


3.

 安裝過程中會申請一個帳號

 一定要選擇非商業模式的 帳號

 才會是Open Source版本

 (如果原來的E-Mail已申請過商業帳號, 請換另一個E-Mail)

  

=================================

Install Linux Android Studio 

// for Ubuntu x64

 $ sudo apt-get update

 $ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386

 

// Install Open JDK

 $ sudo apt-get update

 $ sudo apt-get install openjdk-8-jdk

 $ java -version

 $ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-*/jre

 

// Download Android Studio and SDK tools

// https://developer.android.com/studio?hl=zh-tw

// https://r1---sn-ipoxu-u2xr.gvt1.com/edgedl/android/studio/ide-zips/2022.3.1.20/android-studio-2022.3.1.20-linux.tar.gz

  $ tar -xf android-studio-2022.3.1.20-linux.tar.gz

  $ cd android-studio

  $ ./bin/studio.sh

   > 選擇 [Do not import settings] 並且按下OK

   開始安裝...

  $ sudo apt install qemu-kvm

  $ sudo adduser <your username> kvm

  $ sudo chown <your username> /dev/kvm

  $ sudo adduser jun kvm

  $ sudo chown jun /dev/kvm

  // 啟動android studio IDE 

  // 就是 android-studio-2022.3.1.20-linux.tar.gz解壓縮後的目錄  

  $ cd android-studio 

  $ cd ./ studio.sh 

  // 先新建一個簡單的專案  

   > Tools->SDK Manager

   > 左邊 Android SDK

   > 右邊 SDK Platforms

     選擇要的 Android API版本

   > 右邊 SDK Tools

   > 勾選 NDK 及其他想要的元件

   > 右下 Apply

   

  // 安裝完成後, 要新增Android Virtual Device (AVD) 才能夠用模擬器執行

   > Tools->Device Manager