Differenze tra le versioni di "CH341"
Riga 64: | Riga 64: | ||
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 | 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 menuconfig | ||
+ | </source> | ||
+ | |||
+ | I parametri da modificare sono i seguenti: | ||
+ | |||
+ | <source> | ||
+ | CONFIG_SPI_DEBUG=y | ||
+ | CONFIG_SPI_BITBANG=y | ||
+ | CONFIG_SPI_GPIO=y | ||
+ | # CONFIG_SPI_PXA2XX is not set | ||
+ | # CONFIG_SPI_PXA2XX_PCI is not set | ||
+ | CONFIG_SPI_SPIDEV=y | ||
+ | CONFIG_SPI_LOOPBACK_TEST=m | ||
+ | CONFIG_GPIO_SYSFS=y | ||
+ | CONFIG_GPIO_GENERIC=y | ||
+ | # CONFIG_GPIO_EXAR is not set | ||
+ | CONFIG_GPIO_GENERIC_PLATFORM=y | ||
+ | # CONFIG_GPIO_ICH is not set | ||
+ | </source> | ||
+ | |||
+ | terminata la scelta dei parametri e salvato si può procedere alla compilazione | ||
+ | |||
+ | <source> | ||
make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1 | make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1 | ||
ls ../*.deb | ls ../*.deb |
Versione delle 20:21, 21 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
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
I parametri da modificare sono i seguenti:
CONFIG_SPI_DEBUG=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_PXA2XX_PCI is not set
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_LOOPBACK_TEST=m
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC=y
# CONFIG_GPIO_EXAR is not set
CONFIG_GPIO_GENERIC_PLATFORM=y
# 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