Differenze tra le versioni di "CH341"

Da raspibo.
Jump to navigation Jump to search
Riga 14: Riga 14:
 
Questa board è interessante perchè ha due switch, uno per la selezione della tensione (3.3Volts oppure 5Volts) ed uno per decidere la modalità di funzionamento del chip (porta seriale oppure spi/i2c).
 
Questa board è interessante perchè ha due switch, uno per la selezione della tensione (3.3Volts oppure 5Volts) ed uno per decidere la modalità di funzionamento del chip (porta seriale oppure spi/i2c).
  
= Configurazione =
+
= Configurazione per SPI=
  
 
http://www.raspibo.org/wiki/index.php?title=CH341&action=history
 
http://www.raspibo.org/wiki/index.php?title=CH341&action=history
Riga 251: Riga 251:
 
Esecuzione:
 
Esecuzione:
 
  sudo ./a.out
 
  sudo ./a.out
 +
 +
= Modalità I2C =
 +
Per la modalità I2C le cose sembrano più semplici, dopo aver compilato e inserito il modulo come da [https://github.com/gschorcht/i2c-ch341-usb istruzioni inserendo l'usb:
 +
<code>dic 22 21:45:14 thinkdeb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio0 gpio=0 irq=0
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio1 gpio=1 irq=1
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio2 gpio=2 irq=2
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio3 gpio=3 irq=3
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio4 gpio=4 irq=4 (hwirq)
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio5 gpio=5 irq=5
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio6 gpio=6 irq=6
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio7 gpio=7 irq=7
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_i2c_probe: created i2c device /dev/i2c-10
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_i2c_set_speed: Change i2c bus speed to 100 kbps
 +
dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_usb_probe: connected</code>
 +
 +
Poi è necessario caricare il modulo i2c-dev
 +
modprobe i2c-dev
 +
 +
Per verificare:
 +
$ ls /dev/i2c-10       
 +
/dev/i2c-10

Versione delle 22:20, 22 dic 2018

CH341

Questa pagina è dedicata al chip CH341, si tratta di un circuito multifunzione di cui si trova poca documentazione.

L'unico rifrimento chiaro che ho trovato è su questa pagina che oltre al datasheet riporta la seguente definizione.

"CH341 is a USBbus convert chip, providing UART, printerport, parallel and synchronous serial with 2-wire or4-wire through USBbus."

Viene venduto già saldato su varie board, mi ci sono imbattuto perchè stavo cercando un circuito per leggere una eeprom tramite il programma flashprog e mi serviva un hardware usb da connettere al pc.

I programmatori che si trovano normalmente hanno tensione a 5 volts e quindi ho poi ripiegato su raspberry utilizzando flshprog per interfacciare la eeprom alla porta spi di raspberry.

Nel frattempo però avevo già ordinato il programmatore in versione a doppio voltaggio (se cercato CH341 electrodragon lo trovate facilmente).

Questa board è interessante perchè ha due switch, uno per la selezione della tensione (3.3Volts oppure 5Volts) ed uno per decidere la modalità di funzionamento del chip (porta seriale oppure spi/i2c).

Configurazione per SPI

http://www.raspibo.org/wiki/index.php?title=CH341&action=history Normalmente il kernel linux riconosce il chip come adattatore USB - seriale creando una porta /dev/ttyUSB0 e questo è utile, ma è na funzionalità abbastanza comune e ci sono diversi chip che hanno questa funzione.

Per riuscire a utilizzare il chip in altra modalità cioè come porta SPI sono necessari due passaggi:

  • compilare uno o due moduli per il kernel a seconda se abbiamo necessità di usare il chip come porta i2c o spi.
  • ricompilare il kernel linux per poter vedere i devices perchè normalmente le porte spi non sono visibili nella cartella /dev.

Compilare i moduli

Per il primo punto ho utilizzato il software di Gunar Schorcht derivato da un primo modulo sviluppato da Tse Lun Bien.

Per l'installazione ho seguito le istruzioni nel README senza registrare problemi.

Vediamo ora in dettaglio il modulo per la funzione spi, una volta compilato ed inserito il modulo se lancio il comando

sudo journalctl -f

sembra che vada tutto correttamente, ma poi non trovo i devices nella cartella /dev.

Li trovo invece con il comando find puntando la cartella /sys

sudo find /sys -name "spi*"

ad esempio

 /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/spi_master
 /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/spi_master/spi0
 /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/spi_master/spi0/spi0.2

Compilare il kernel

A questo punto è necessario passare al secondo punto cioè la compilazione del kernel linux del mio pc.

Il suggerimento viene da questa pagina. Riporto di seguito i comandi perchè si tratta di una operazione che non faccio molto di frequente.... ho fatto riferimento a questa procedura.

La procedura è stata trascritta a postariori, potrebbe non essere precisa.

Sostituire x.yy con la versione di kernel in uso

 mkdir ~/kernel; cd ~/kernel
 apt-cache search ^linux-source
 apt install linux-source
 apt install  dpkg-dev build-essential
 tar -xaf /usr/src/linux-source-x.yy.tar.xz
 cp /boot/config-x.yy ~/kernel/linux-source-x.yy/.config #copia la configurazione del kernel in uso nella cartella del nuovo kernel da compilare
 make menuconfig

I parametri da modificare sono i seguenti:

CONFIG_SPI_DEBUG=y    
CONFIG_SPI_MASTER=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_BUTTERFLY=m    
CONFIG_SPI_GPIO=m
CONFIG_SPI_PXA2XX=m
CONFIG_SPI_PXA2XX_PCI=m
CONFIG_SPI_SPIDEV=y    
CONFIG_SPI_LOOPBACK_TEST=m    
CONFIG_GPIO_SYSFS=y    
CONFIG_GPIO_GENERIC=m  
# CONFIG_GPIO_EXAR is not set
CONFIG_GPIO_GENERIC_PLATFORM=m 
# CONFIG_GPIO_ICH is not set

terminata la scelta dei parametri e salvato si può procedere alla compilazione

 make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
 ls ../*.deb
 dpkg -i  ../*.deb
 apt install xtables-addons-dkms

A questo punto è necessario un reboot.

Al riavvio verificare che GRUB utilizzi il nuovo kernel.

Se tutto è ok lanciando

journalctl -f 

all'inserimento dell'USB si vedrà qualcosa del genere

 dic 21 18:51:43 deb kernel: usb 1-1.2: new full-speed USB device number 6 using ehci-pci
 dic 21 18:51:43 deb kernel: usb 1-1.2: New USB device found, idVendor=1a86, idProduct=5512
 dic 21 18:51:43 deb kernel: usb 1-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_cfg_probe: output cs0 SPI slave with cs=0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_cfg_probe: output cs1 SPI slave with cs=1
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_cfg_probe: output cs2 SPI slave with cs=2
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_cfg_probe: input  gpio4 gpio=0 irq=0 (hwirq)
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_cfg_probe: input  gpio5 gpio=1 irq=1 
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_spi_probe: SPI master connected to SPI bus 0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: registered master spi0
 dic 21 18:51:43 deb kernel: spi spi0.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: registered child spi0.0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_spi_probe: SPI device /dev/spidev0.0 created
 dic 21 18:51:43 deb kernel: spi spi0.1: setup mode 0, 8 bits/w, 1000000 Hz max --> 0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: registered child spi0.1
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_spi_probe: SPI device /dev/spidev0.1 created
 dic 21 18:51:43 deb kernel: spi spi0.2: setup mode 0, 8 bits/w, 1000000 Hz max --> 0
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: registered child spi0.2
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_spi_probe: SPI device /dev/spidev0.2 created
 dic 21 18:51:43 deb kernel: spi-ch341-usb 1-1.2:1.0: ch341_usb_probe: connected

ed un ls nella dir /dev mostrerà correttamente i devices.

~$ ls -l /dev/spidev0.*
crw------- 1 root root 153, 0 dic 21 18:51 /dev/spidev0.0
crw------- 1 root root 153, 1 dic 21 18:51 /dev/spidev0.1
crw------- 1 root root 153, 2 dic 21 18:51 /dev/spidev0.2

Per la verifica di reale funzionamento si può usare questo software caricato su pc interfacciato con arduino.

Lo riporto qui perchè per funzionare su pc ha bisogno di qualche aggiustamento:

/**********************************************************
 SPI_Hello_Arduino
   Configures an Raspberry Pi as an SPI master and  
   demonstrates bidirectional communication with an 
   Arduino Slave by repeatedly sending the text
   "Hello Arduino" and receiving a response
   
Compile String:
g++ -o SPI_Hello_Arduino SPI_Hello_Arduino.cpp
***********************************************************/

#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <fcntl.h>
#include <cstring>
#include <iostream>
#include <unistd.h>

using namespace std;


/**********************************************************
Declare Global Variables
***********************************************************/

int fd;
unsigned char hello[] = {'H','e','l','l','o',' ',
                           'A','r','d','u','i','n','o'};
unsigned char result;

/**********************************************************
Declare Functions
***********************************************************/

int spiTxRx(unsigned char txDat);


/**********************************************************
Main
  Setup SPI
    Open file spidev0.0 (chip enable 0) for read/write 
      access with the file descriptor "fd"
    Configure transfer speed (1MkHz)
  Start an endless loop that repeatedly sends the characters
    in the hello[] array to the Ardiuno and displays
    the returned bytes
***********************************************************/

int main (void)
{


   fd = open("/dev/spidev0.0", O_RDWR);
   if (fd == -1 ) {
   	printf("Errore %d\n",fd);
   	exit(1);
   }
   unsigned int speed = 1000000;
   ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

   while (1)
   {

      for (int i = 0; i < sizeof(hello); i++)
      {
         result = spiTxRx(hello[i]);
         cout << result;
         usleep (1000);
      }

   }

}

/**********************************************************
spiTxRx
 Transmits one byte via the SPI device, and returns one byte
 as the result.

 Establishes a data structure, spi_ioc_transfer as defined
 by spidev.h and loads the various members to pass the data
 and configuration parameters to the SPI device via IOCTL

 Local variables txDat and rxDat are defined and passed by
 reference.  
***********************************************************/

int spiTxRx(unsigned char txDat)
{
 
  unsigned char rxDat;

  struct spi_ioc_transfer spi;

  memset (&spi, 0, sizeof (spi));

  spi.tx_buf        = (unsigned long)&txDat;
  spi.rx_buf        = (unsigned long)&rxDat;
  spi.len           = 1;

  ioctl (fd, SPI_IOC_MESSAGE(1), &spi);

  return rxDat;
}

Compilazione:

 g++ ra_spi.cpp

Esecuzione:

sudo ./a.out

Modalità I2C

Per la modalità I2C le cose sembrano più semplici, dopo aver compilato e inserito il modulo come da [https://github.com/gschorcht/i2c-ch341-usb istruzioni inserendo l'usb: dic 22 21:45:14 thinkdeb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio0 gpio=0 irq=0 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio1 gpio=1 irq=1 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio2 gpio=2 irq=2 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio3 gpio=3 irq=3 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input gpio4 gpio=4 irq=4 (hwirq) dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input gpio5 gpio=5 irq=5 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input gpio6 gpio=6 irq=6 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input gpio7 gpio=7 irq=7 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_i2c_probe: created i2c device /dev/i2c-10 dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_i2c_set_speed: Change i2c bus speed to 100 kbps dic 22 21:45:14 deb kernel: i2c-ch341-usb 1-2:1.0: ch341_usb_probe: connected

Poi è necessario caricare il modulo i2c-dev

modprobe i2c-dev

Per verificare:

$ ls /dev/i2c-10         
/dev/i2c-10