jeudi 31 mai 2012

Overview on power supply management


Dans ce post je vais vous montrer les bases pour gérer et contrôler le voltage dans un circuit électronique. J'ai pu retrouver deux méthodes type pour y arriver et au lieu de trop rentrer dans les détails (ce que je ferais pour chaque méthode dans d'autres posts) je préfère donner une vue d'ensemble à travers une petite vidéo.

Normalement il faudrait dans a peu près tout les cas utiliser des bypass capacitors pour isoler et réduire le bruit de l'alimentation et pour gérer les pics de demandes des différents micro-contrôleurs. Je ne le fais pas ici, car je pense qu'il faudrait vraiment entrer dans les détails, notamment sur le choix de la valeur des capacitors. 



La première méthode utilise des régulateurs de tension. Dans la vidéo, je montre l'utilisation d'un régulateur d'ampérage qui fait perdre 0,5V (LM2937) ainsi que l'utilisation d'un régulateur de tension fixe à 5V (L7805). Cette méthode est largement utiliser puisqu'elle permet d'obtenir un ampérage assez élevé en sortie : le LM2937 peut laisser passer du 500mA; le L7805 du 1,5A.


Figure 1 : Les deux régulateurs en fonctionnement. A droite le L7805, a gauche le LM2937.
Figure 2 : Schéma résultat du fonctionnement d'un régulateur L7805 grâce au logiciel icircuit.


Datasheets : 

Low dropout regulator : LM2937
5V Fixed low dropout regulator : L7805



La deuxième méthode est basé sur le "voltage diviseur" grâce à deux résistances en série. Dans la vidéo, j'ai utilisé deux résistances de 10kOhm chacune. Le problème de cette méthode est que l'ampérage utilisable à la fin peut être très réduite (ici environ 450uA)

Figure 3 : Connection des résistances en série pour réduire le voltage de l'alimentation.
Figure 4 : Schéma résultat du voltage diviseur grâce au logiciel icircuit. La résistance de 1GOhm permet d'empêcher le courant de passer dans la deuxième partie du circuit.


La formule de calcul de VOUT en fonction de VIN, R1 et R2 est plutôt simple : 

- Tout d'abord on sait que U = R.I, donc VIN = I1.R1 + I2.R2
- Dans notre cas I1 = I2 = I = VIN / (R1 + R2)

Ce que l'on veut c'est VOUT :
- VOUT entre R1 et R2 est égale à VOUT = I.R2
- De ce fait, VOUT = (R2.VOUT) / (R1+R2)

Dans notre setup, VIN = 9V et R1 = R2 = 10kOhm, soit : 
- VOUT = (10000.9) / (10000+10000) = 90000 / 20000 = 4,5 V  

Un peu de code networking pour l'iPod jailbreaké

Je me suis un peu planché sur la programmation en C sur iPod jailbreaké. En faite, je me retrouve avec l'environnement de travail typique Mac OS X  (Darwin) avec a peu près les mêmes headers et fonctions.

Première info, le firmware 3.1.3 de l'iPod ne supporte pas l'IPv6. C'est un peu dommage pour l'instant surtout que je doute qu'il existe un autre firmware pour cet iPod qui le supporte.

Pour célébrer ça, je poste donc 2 codes sources qui permettent très simplement de passer l'iPod en mode routeur (le procfs n'existe pas sous Darwin donc il faut passer par Sysctl) et de récupérer des infos utiles sur les interfaces réseau. Ok, il est moins complet qu'ifconfig mais utile pour récupérer des bouts de code pour des programmes plus évolué.


Donc le premier pour passer l'iPod en mode routeur :

 #include <stdio.h>  
 #include <errno.h>  
 #include <sys/types.h>  
 #include <sys/sysctl.h>  
 int main(int argc, char* argv[])  
 {  
      int mib[4], value, newvalue;  
      size_t len, vlen;  
      len=sizeof(mib);  
      sysctlnametomib("net.inet.ip.forwarding",mib,&len);  
      vlen=sizeof(value);  
      if(sysctl(mib,len,&value,&vlen,NULL,0)==-1) {  
        perror("sysctl read failed");  
      }  
      printf("net.inet.ip.forwarding=%d\n",value);  
      if(value==1) newvalue=0; else newvalue=1;  
      if(sysctl(mib,len,NULL,NULL,&newvalue,len)==-1) {  
        perror("sysctl write failed");  
      } else printf("net.inet.ip.forwarding=%d\n",newvalue);  
      return 0;  
 }  


Résultat :


Le second pour récupérer des infos sur les interfaces réseau (avec la méthode pour récupérer l'adresse MAC) :

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <unistd.h>  
 #include <sys/types.h>  
 #include <sys/socket.h>  
 #include <errno.h>  
 #include <string.h>  
 #include <net/if.h>  
 #include <arpa/inet.h>  
 #include <sys/ioctl.h>  
 #include <netdb.h>  
 #include <net/if_dl.h>  
 #include <net/ethernet.h>  
 #include <ifaddrs.h>  
 int main(int argc, char* argv[])  
 {  
      struct ifaddrs* ifa=NULL;  
      struct ifaddrs* ifEntry=NULL;  
      struct ifaddrs* ifLink=NULL;;  
      struct sockaddr_in6* sin6;  
      struct sockaddr_in* sin4;  
      char ipv6addr[INET6_ADDRSTRLEN];  
      char ipv4addr[INET_ADDRSTRLEN];  
      struct sockaddr_dl* sdl;  
      struct ether_addr mac[ETHER_ADDR_LEN];  
      short flags=0;  
      unsigned int index;  
      if(getifaddrs(&ifa)<0) {  
     printf("No interfaces.\n");  
     return EXIT_FAILURE;  
      }  
      for(ifEntry=ifa; ifEntry!=NULL; ifEntry=ifEntry->ifa_next) {  
     if(ifEntry->ifa_addr->sa_family==PF_INET6 || ifEntry->ifa_addr->sa_family==AF_INET) {  
       index=if_nametoindex(ifEntry->ifa_name);  
       printf("Interface name: %s (%d)\n",ifEntry->ifa_name,index);  
       flags=ifEntry->ifa_flags;  
       if((flags & IFF_UP))  
         printf("Status: UP; ");  
       else printf("Status: DOWN; ");  
       if((flags & IFF_LOOPBACK))  
         printf("is loopback; ");  
       if((flags & IFF_MULTICAST))  
         printf("Supports multicast; ");  
       if((flags & IFF_RUNNING))  
         printf("Running\n");  
       else printf("Not running\n");  
       for(ifLink=ifa; ifLink!=NULL; ifLink=ifLink->ifa_next) {  
         if(ifLink->ifa_addr->sa_family==AF_LINK && strncmp(ifEntry->ifa_name,ifLink->ifa_name,IFNAMSIZ)==0) {  
           sdl=(struct sockaddr_dl*)ifLink->ifa_addr;  
           if(sdl->sdl_alen==ETHER_ADDR_LEN) { // sdl_alen = address length; sdl_nlen=name length  
             bzero(mac,ETHER_ADDR_LEN);  
             memcpy(mac,(sdl->sdl_data+sdl->sdl_nlen),ETHER_ADDR_LEN); // sdl_data includes interface name and hardware address  
             printf("Hardware address: %02x:%02x:%02x:%02x:%02x:%02x\n",mac->octet[0],mac->octet[1],mac->octet[2],mac->octet[3],mac->octet[4],mac->octet[5]);  
           }  
         }  
       }  
       if(ifEntry->ifa_addr->sa_family==PF_INET6) {  
         sin6=(struct sockaddr_in6*)ifEntry->ifa_addr;  
         inet_ntop(PF_INET6,&sin6->sin6_addr,ipv6addr,INET6_ADDRSTRLEN);  
         printf("IPv6 address: %s\n",ipv6addr);  
         bzero(ipv6addr,INET6_ADDRSTRLEN);  
       }  
       else {  
         sin4=(struct sockaddr_in*)ifEntry->ifa_addr;  
         inet_ntop(AF_INET,&sin4->sin_addr,ipv4addr,INET_ADDRSTRLEN);  
         printf("IPv4 address: %s\n",ipv4addr);  
         bzero(ipv4addr,INET_ADDRSTRLEN);  
       }  
     }  
   }  
   free(ifa);  
   return EXIT_SUCCESS;  
 }  


Résultat :


mercredi 30 mai 2012

Environnement de programmation sur iPod jailbreaké

Une des grandes questions que je me posais depuis pas mal de temps déjà était : De quoi ai-je besoin pour programmer sur un iPhone jailbreaké (ou autre device Apple) ?

Moi qui suis un grand amoureux du C, la partie graphique n'est pas prioritaire (pour l'instant). Donc il me faudrait un compilateur C (GCC si possible) compatible avec l'iPhone. J'ai donc récupéré un vielle iPod touch de 1ère génération qui trainait dans un tiroir que j'ai jailbreaké pour avoir la main mise sur tout le système. Le firmware 3.1.3 y était installé et il m'a été impossible de le retrouver sur l'Internet pour procéder au jailbreak. Heureusement, le RedSnow 0.9 m'a permit de réaliser le jailbreak sans en avoir besoin.



Pour info, on reconnait l'iPod Touch de 1ère génération par la coque de protection de l'antenne Wi-Fi noir sur le dos qui a une forme plus rectangulaire.


Pour pouvoir programmer en C sur l'iPod, il faut un compilateur C et donc un toolchain (ensemble d'outils pour pouvoir compiler et exécuter un programme) pour le C et compatible iPod (et par extension iPhone). J'ai eu beaucoup de mal à trouver des infos mais je suis finalement tombé sur un site proposant une procédure simple et claire. Que je reproduis donc ici.

Attention! ce qui suit est la procédure pas à pas tel que spécifié par ce site (donc comme on dit, tout droit réservé) : http://blog.syshalt.net/index.php/2010/09/12/compile-c-applications-with-gcc-on-ios-4-iphone/

Quelques annotations apparaissent pour indiquer mon cas spécifique et les probables problèmes que vous pourrez avoir à traiter...


Pré-requis à installer à travers Cydia :


- wget 1.11-3 Cydia/Telesphoreo 300kB Installation sans problème
- APT 0.7 Strict 0.7.25.3-6 Cydia/Telesphoreo 1064kB
J'ai eu un problème d'installation d'APT parceque j'ai fais l'étape 2 avant. Malheureusement, le dpkg n'a pas libéré de lock file (erreur "Could not get lock /var/lib/dpkg/lock"). Un redémarrage de l'iPod à suffit à régler le problème.

- apt-get install nano Installation sans problème

Procédure : 
  1. Connection root en ssh sur l'iPod
  2. wget http://www.syshalt.net/pub/iphone/gcc-iphone/fake-libgcc_1.0_iphoneos-arm.deb Download sans problème
  3. dpkg -i fake-libgcc_1.0_iphoneos-arm.deb Installation sans problème
  4. apt-get install iphone-gcc Installation sans problème
  5. wget http://www.syshalt.net/iphone/gcc-iphone/sdk-2.0-headers.tar.gz Download sans problème
  6. tar -xvzf sdk-2.0-headers.tar.gz
  7. cd include-2.0-sdk-ready-for-iphone
  8. cp –r * /usr/include (pour info le répertoire comprend un répertoire netinet et netinet6)
  9. cd ..
  10. wget http://www.syshalt.net/iphone/gcc-iphone/gcc_files.tar.gz Download sans problème
  11. tar -xvzf gcc_files.tar.gz
  12. cd gcc_files
  13. cp –r * /usr/lib
  14. apt-get install ldid Installation sans problème

-----------Installation terminé-----------------------


Commandes pour compiler et exécuter une application : 

- gcc -o <exec flename> <source filename>
- ldid -S <exec filename> 
- ./<exec filename>

Une copie des fichiers à télécharger :

4 ports Hub USB teardown

Aujourd'hui je me suis intéressé au désassemblage d'un Hub USB de 4 ports pour un peut mieux comprendre les éléments nécessaire pour ce type de périphérique.

  


Ce qui est intéressant c'est qu'avec un seul microprocesseur, on est capable de gérer les 4 ports (la miniaturisation des éléments électronique a du bon). 

La carte propose donc un bloc d'alimentation assez basique où l'entrée est en générale à 5V (port USB mini ou prise jack). Le régulateur permet de fixer le voltage à 3.3V requis pour le micro-contrôleur. Entre la prise jack et le régulateur il y a un petit fusible réarmable pour protéger la carte et quelque bypass capacitors autour des ports downstream. 

Le micro-contrôleur dispose d'une architecture RISK-like de 8-bit gérant 4 port en USB 2.0 High-Speed (HS), Full-Speed (FS) et Low-Speed (LS) pour le downstream et 1 port upstream FS et HS. Une boucle à phase asservie (PLL) avec un multiplicateur de 40 est intégré et également connecté à l'oscillateur de 12 MHz afin d'atteindre la vitesse nominale du HS (près de 480 Mb/s).  
   

Figure 1 : Image de la carte annotée


Datasheet :

Fixed 3.3V Positive Low dropout Regulator : IRU 1117-33
4-ports USB2.0 Hub : GL850A

mardi 29 mai 2012

Apple USB cable teardown

J'ai eu beaucoup de mal a trouver un site montrant les connections dans le cable USB d'Apple. Sur certains sites il est fait état que certaine valeurs de résistance permettent de discriminer le type de périphérique qui sera reconnu par l'iP***. Ma question est donc, cette résistance est-elle dans le cable ou est-elle à ajouter au périphérique ? Mon doute est née du désassemblage d'un cable thunderbolt d'Apple.

Pour info, ce cable est utilisé pour synchroniser et recharger un iPod, iPad, ou iPhone à un ordinateur en USB. On s'attend donc au minimum à 4 fils dans le cable: l'USB +5V, le GND, l'USB Data+ et l'USB Data-.


Voici donc le résultat :






Le sens de connection au iP*** correspond à la troisième figure. Les deux repères de la figure 2 définissent la face arrière. Pour résumer donc :
  • Pin 16 : USB GND
  • Pin 23 : USB +5V
  • Pin 25 : USB Data-
  • Pin 27 : USB Data+

Pour info le mapping des pins de ce type de connecteur peut être trouvé ici : http://pinouts.ru/PortableDevices/ipod_pinout.shtml

Possibilité d'acheter ce type de connecteur pour expérience sur sparkfun : 

Présentation et analyse de la carte Arduino Uno Rev. 3

Le site officiel du constructeur de la carte est disponible a cette adresse: http://arduino.cc/


Voici une présentation des éléments électronique qui compose l'Arduino Uno Rev. 3. Une description des fonctionnalités est disponible ici.
Les schémas de la carte (board et schematic) peuvent être récupérés ici et lu avec le logiciel Eagle (licence gratuite avec contraintes). Pour info, le fichier PSD de la figure 3.


Figure 1: Board annotée de la carte Arduino Uno Rev. 3

Figure 2 : Schématic annotée de la carte Arduino Uno Rev. 3 
Datasheets :

P-MOSFET : FDN340P
5V Low Dropout Regulator : NCP1117ST50T3G
3,3V Low Dropout Regulator : LP2985-33DBVR
Resettable Polyfuse : MF-NSMF050-2
Operational Amplifier : LMV358IDGKR
Power Supply : DC21MMX
USB Microcontroller : ATMEGA16U2-MU
Main Microcontroller : ATMEGA328P-PU




Alimentation :


Il existe trois modes d'alimentation: 
  • USB à travers les entrées USBVCC et USBGND. L'USB fournit une tension de 5V à 500 mA
  • Un transformateur AC-DC de 7 à 20V par l'entrée DC21MMX. 
  • Les entrées VIN et GND accessible sur les Pins de la carte.

L'entrée USBVCC est suivie d'un fusible réarmable afin de protéger la carte de possible surtensions. Si il y a surtension, le circuit est coupé tant que la valeur de la tension dépasse un seuil.

Les micro-contrôleurs USB et DIP28 ont besoin d'un régulateur de tension de 5V. Afin d'assurer le bon fonctionnement des régulateurs, la tension en entrée doit être dans une limite de 1 à 2V par rapport à la sortie désiré. Une Pin à 3,3V est disponible et est fournit à travers un régulateur de tension 3,3V.

Figure 3 : Schéma de connection d'un régulateur afin d'obtenir une tension fixe en sortie.

Ces deux régulateurs ont besoin de capacitors (PC1, PC2, C2, C3) afin de lisser le voltage de sortie (voir Figure 3). A l'entrée du régulateur, le capacitor va gérer la stabilité en entrée du courant si le régulateur est trop loin de la source d'alimentation. En sortie, le capacitor assure la stabilité du courant en sortie. Des capacitors (C6, C7, C8) aux entrées des micro-contrôleurs sont aussi nécessaire pour gérer les pics de demandes et garantir le niveau de tensions (un pic de demande peut apparaître par exemple au démarrage).

Quand l'USB et une entrée VIN sont branché, le P-MOSFET permet de sélectionner la source d'alimentation qui fournira la carte. Le P-MOSFET est composé de 3 interfaces: le Source (S), le Drain (D), et la Gate (G). le courant circule de D vers S quand G est actionné. Dans notre cas G est actionné quand le voltage entre G et S, VGS<=-1.5V (VG-VS<=-1.5). Un tutoriel sur le P-MOSFET est disponible ici.
La Gate est fournit par un voltage réduit de la VIN (à travers deux résistances RN1A et RN1B) et d'une entrée 3,3V en entrée de l'amplificateur opérationnel. Si VIN est fournit, le 3,3V est aussi fournit. Une petite expérience avec un VIN a 9V montre que :
  • USBVCC=5V et VIN=9V : G=5V, S=5V, D=5V (VGS=0V)
  • USBVCC=5V et VIN=0V : G=0V, S=5V, D=5V (VGS=-5V)
  • USBVCC=0V et VIN=9V : G=5V, S=5V, D=0V (VGS=0V)