CH341: differenze tra le versioni

Da raspibo.
(Configurazione)
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 =http://www.raspibo.org/wiki/index.php?title=CH341&action=history
+
= Configurazione =
 +
 
 +
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.
 
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.
  
Riga 21: Riga 23:
 
* ricompilare il kernel linux per poter vedere i devices perchè normalmente le porte spi non sono visibili nella cartella /dev.
 
* 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 [https://github.com/gschorcht Gunar Schorcht] derivato da un primo modulo sviluppato da [https://github.com/allanbian1017 Tse Lun Bien].
 
Per il primo punto ho utilizzato il software di [https://github.com/gschorcht Gunar Schorcht] derivato da un primo modulo sviluppato da [https://github.com/allanbian1017 Tse Lun Bien].
  
Riga 43: Riga 46:
 
</source>
 
</source>
  
 +
== Compilare il kernel ==
 
A questo punto è necessario passare al secondo punto cioè la compilazione del kernel linux del mio pc.
 
A questo punto è necessario passare al secondo punto cioè la compilazione del kernel linux del mio pc.
  

Versione delle 18:44, 21 dic 2018

Indice

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

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à è necessario fare un pò di cose:

  • 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-get install dpkg-source  
 apt install  dpkg-dev build-essential
 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 
 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
Strumenti personali
Namespace

Varianti
Azioni
Navigazione
Strumenti