Popularny post FlyingDutch Napisano Kwiecień 22, 2023 Popularny post Udostępnij Napisano Kwiecień 22, 2023 (edytowany) Cześć, od dłuższego czasu planowałem przeprowadzenie próby wlutowania układu scalonego w obudowie BGA na þlytkę PCB. Coraz trudniej jest dostać zaawansowane układy scalone w obudowach innych niż BGA (MCU, FPGA pamięci różnego rodzaju) stąd moje zainteresowanie możliwością wlutowania układów scalonych w tych typach obudów do płytki drukowanej. Mój wybór do pierwszego eksperymentu lutowania takich obudów padł na pamięć flash (z interfejsem równoległym) w obudowie BGA48. Wybrany układ to pamięć flash o organizacji 16-Mbit (2M × 8-Bit/1M × 16-Bit) w obudowie BGA48 typu S29AL016J. Tutaj link do karty katalogowej: https://www.infineon.com/dgdl/Infineon-S29AL016J_16_MBIT_(2M_X_8_BIT_1M_X_16_BIT)_3_V_BOOT_SECTOR_FLASH-DataSheet-v18_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0ed709c05803 Wybrałem tą pamięć ze względu na małą obudowę BGA48 i niską cenę układu (11PLN w Mouser.com). Zaprojektowałem prostą płytkę drukowaną pozwalającą sprawdzić poprawność lutowania układu S29AL016J korzystając z CAD "EasyEDA". Poniżej schemat i projekt PCB tej płytki: Schematic_Flash_16Mb_S29AL016J_BGA48_2023-04-22.pdf PCB_PCB_Flash_16Mb_S29AL016J_BGA48_Placement_14_production_2023-04-22.pdf Tutaj pliki Gerber dla PCB: Gerber_PCB_Flash_16Mb_S29AL016J_BGA48_Placement_14_production_2023-04-22 (1).zip A tutaj zdjęcie gotowej płytki PCB z wlutowanyym układem scalonym S29AL016J: W celu nakładania pasty lutowniczej kupiłem wcześniej w Aliexpress.com zestaw sit do obudów BGA: https://pl.aliexpress.com/item/4000278609112.html?spm=a2g0o.productlist.main.81.19e84adbTuhuOn&algo_pvid=4e04cc0e-de6c-4a8f-985b-47e2d7ad2b18&algo_exp_id=4e04cc0e-de6c-4a8f-985b-47e2d7ad2b18-40&pdp_npi=3%40dis!PLN!30.95!21.66!!!!!%40211bf3f116821577341587735d075c!10000001137393162!sea!PL!2287185289&curPageLogUid=2RkVKYY91Apz . ale okaząło się, że w tym przypadku nie były potrzebne, bo układ scalony w obudowie BGA miał już kulki z lutowia. Po umieszczeniu układu scalonego na PCB był on wlutowany w piecu konwekcyjnym. Wstępnie sprawdziłem, czy na pinach obudowy BGA wyprowadzonych na złącze goldpin nie ma zwarć pomiedzy sąsiadującymi pinami i test był pozytywany. Znalzłem na Github'ie projekt "ParallelFLASHDumper" za pomocą którego można sprawdzić (korzystając z Arduino UNO) poprawność działania wlutowanej pamieći flash: https://github.com/cyphunk/ParallelFLASHDumper Muszę tylko kupić układy cyfrowe seri 74xxx, których nie mam. Gdyby okazło się, że wlutowana pamieć flash S29AL016J działa poprawnie, to jako nastepny eksperyment planuję zaprojektowanie płytki PCB z układem scalonym (MCU STM32) STM32F103RBH6 w obudowie BGA64: https://www.mouser.pl/ProductDetail/STMicroelectronics/STM32F103RBH6?qs=%2FuY%2BN5FtPGQPlibP5f9V4A%3D%3D A ostatecznie chciałbym móc korzystać w swoich projektach z układów FPGA w obudowach BGA256 np. takich: https://www.mouser.pl/ProductDetail/GOWIN-Semiconductor/GW1N-LV9UG256C6-I5?qs=OlC7AqGiEDkJIRlgPk4JJQ%3D%3D Pozdrawiam Edytowano Kwiecień 22, 2023 przez FlyingDutch 5 Cytuj Link do komentarza Share on other sites More sharing options...
Popularny post FlyingDutch Maj 25, 2023 Autor tematu Popularny post Udostępnij Maj 25, 2023 (edytowany) Cześć, wczoraj miałem trochę czasu powróciłem więc do testu poprawności wlutowania pamięci Flash w obudowie BGA48 (patrz post powyżej). Jak już pisałem planowałwem do tego celu wykorzystać projekt "ParallelFLASHDumper", aby odczytać zawartość pamięci Flash - patrz link do projektu: https://github.com/cyphunk/ParallelFLASHDumper Na stronie Github'a projektu są dwa podprojekty - jeden wykorzystujący "Arduino UNO" i drugi korzystający z Raspberry PI. Postanowiłem wybrać wersję dla Raspbberry Pi ponieważ wymaga mniej dodatkowych układów scalonych i jest prostsza. Posiadam miedzy innymi "Raspberry Pi Zero Lite v.1.3" i na niej oparłem test działania układu Flash. Ponieważ układ S29AL016J to Flash o interfejsie równoległym posiada aż 20-cia linii adresowych - biorąc pod uwagę 16 pinów potrzebnych dla linii danych port GPIO w Raspbbery Pi ma za mało pinów (40), stąd wynika potrzeba użycia dodatkowych układów scalonych SN74HC595 (rejestry z wejściem szeregowym i wyjściami równoległymi - patrz karta katalogowa układu: https://www.ti.com/lit/ds/symlink/sn74hc595.pdf Użyte są trzy takie układy, aby obsłużyć maksymalnie 24 linie adresowe - patrz schemat z projektu: https://github.com/cyphunk/ParallelFLASHDumper/blob/master/ParallelFLASHDumper.fzz.png Na RPI Zero Lite zainstalowałem OS Raspbian, następnie przeszedłem do żródeł programu w C robiącego dump'a pamieci Flash - patrz link: https://github.com/cyphunk/ParallelFLASHDumper/blob/master/ParallelFLASHDumper_rpi.c Z kodu programu wynika, że program korzysta z biblioteki "wiringPi" - więc zainstalowałem ją ze żródeł ze strony Github tej biblioteki: https://github.com/WiringPi/WiringPi Nastepni przeszedłem do kodu programu, aby dostosować program do posiadanej przeze mnie wersji RPI i korzystałem z tej strony z pinoutem mojej płytki: Niestety okazło się po zdefiniowaniu wszystkich potrzebnych pinów, że program nie działa prawidłowo. Program kompilowałem za pomocą komendy z terminala: cc -o ParallelFLASHDumper ParallelFLASHDumper_rpi.c -lwiringPi -lpthread Następnie program był uruchamiany komendą: ./ParallelFLASHDumper <nazwa pliku dump> Zawartośc pliku dump (wartości HEX) była nastepująca (edytor Hexedit): Jak widać wartości zrzuconych kolejnych bajtów pamięci to 0x03 i 0xC3, nie są to poprawne wartości ponieważ "pusty" Flash powinien zawierać same bajty 0xFF (same jedynki). Obejrzałem na oscyloskopie sygnały: #define ADDR_DATAOUT 24 // green #define ADDR_CLOCK 28 // yellow Są to wyjście danych szeregowe do pierwszego rejestu 74HC595, oraz zegar dla lini danych adresu Flash. Na tych liniach nie było przebiegów prostokątnych. Tak wyglądał układ testowy (RPI Zero, płytka pamięci Flash oraz płytka stykowa z układami rejestrów): Zacząłem szukać przyczyny i okazało się, że użyta biblioteka "wiringPi" korzysta z innego pinout'u niż ten domyślny dla RPI. Znalazłem stronę z właściwym pinoutem dla tej biblioteki: https://github.com/ppelleti/hs-wiringPi/blob/master/README.md Patrz numery pinów GPIO oznaczone kolorem niebiskim. Po modyfikacji pinout'u kod źródłowy programu dla RPI wygląda nastepująco: #include <stdio.h> #include <wiringPi.h> /* Written by Gina Hortenbach */ /* This code is intended to run on the Raspberry Pi with the WiriPi Library. It has the advantage over the Arduino version in that less shift registers are required and dumping is significantly faster. WiriPi can cause troubles. If you run into trouble check you have version: wiringPi-78b5c32 The code is currently configured for a dump setup that uses ShiftOut registers for address lines and Rapsberry Pi GPIO pins for input data. See ParallelFLASHDumper_rpi.jpg Compile: cc -o ParallelFLASHDumper_rpi ParallelFLASHDumper_rpi.c -lwiringPi -lpthread */ /* * BEGIN USER DEFINITIONS */ #define ADDR_STROBE 25 // latch orange #define ADDR_DATAOUT 24 // green #define ADDR_CLOCK 28 // yellow #define ADDR_A24 18 // define according to the size of your target chip #define MAX_ADDR 0x40000 // INPUT DATA pins #define IN_DQ00 13 // #define IN_DQ01 11 // #define IN_DQ02 31 // #define IN_DQ03 8 // #define IN_DQ04 9 // #define IN_DQ05 21 // #define IN_DQ06 22 // #define IN_DQ07 16 // #define IN_DQ08 0 // //#define IN_DQ08 31 // #define IN_DQ09 27 // #define IN_DQ10 30 // #define IN_DQ11 7 // #define IN_DQ12 26 // #define IN_DQ13 23 // #define IN_DQ14 12 // #define IN_DQ15 14 // //#define CE // gnd #define OE 10 // #define BYTE 29 #define WP 3 #define RST 4 #define WE 2 #define RYBY 5 /* * END USER DEFINITIONS */ unsigned char input1 = 0; unsigned char input2 = 0; unsigned char input[2]; // assuming LSB shifted out first void shiftOut(int myDataPin, int myClockPin, char byte) { int i; // cant use unsigned or byte otherwise loop never ends pinMode(myClockPin, OUTPUT); pinMode(myDataPin, OUTPUT); char currentbit; for (i=0; i<=7; i++) { // byte 0b11001011 currentbit = (byte & (1 << i )) >> i; // i=0 (0b11001011 & (1 << 0=0b00000001))=0b00000001 >> 0 = 1 // i=1 (0b11001011 & (1 << 1=0b00000010))=0b00000010 >> 1 = 1 // i=2 (0b11001011 & (1 << 2=0b00000100))=0b00000000 >> 2 = 0 // i=3 (0b11001011 & (1 << 3=0b00001000))=0b00001000 >> 3 = 1 digitalWrite(myClockPin, 0); delayMicroseconds(2); digitalWrite(myDataPin, currentbit); digitalWrite(myClockPin, 1); delayMicroseconds(2); } } void sendDataOut(unsigned long value) { digitalWrite(ADDR_STROBE, LOW); unsigned char byte1 = value & 0x0000FF; unsigned char byte2 = (value & 0x00FF00) >> 8; unsigned char byte3 = (value & 0xFF0000) >> 16; unsigned char a24 = (value & 0x01000000) >> 24; // shift out assumes LSB first shiftOut(ADDR_DATAOUT, ADDR_CLOCK, byte1 ); //first byte shiftOut(ADDR_DATAOUT, ADDR_CLOCK, byte2 ); //second byte shiftOut(ADDR_DATAOUT, ADDR_CLOCK, byte3 ); //third byte digitalWrite(ADDR_A24, a24); // LATCH/STROBE: digitalWrite(ADDR_STROBE, HIGH); delayMicroseconds(2); digitalWrite(ADDR_STROBE, LOW); } int main(int argc, char const *argv[]) { FILE* file; if (argc != 2) { printf("provide dump file as argument\n"); return 1; } file = fopen(argv[1], "wb"); //chech if wiringPi build in successfully if (wiringPiSetup () == -1) return 1 ; pinMode(OE, OUTPUT); pinMode(WE, OUTPUT); pinMode(WP, OUTPUT); pinMode(BYTE, OUTPUT); pinMode(RST, OUTPUT); pinMode(RYBY, INPUT); //digitalWrite(CE, LOW); // grounded digitalWrite(OE, LOW); digitalWrite(WE, HIGH); // Not care? digitalWrite(WP, LOW); // Not care? digitalWrite(BYTE, HIGH); // LOW 8bit mode HIGH 16 bit mode digitalWrite(RST, HIGH); // pinMode(ADDR_STROBE, OUTPUT); pinMode(ADDR_DATAOUT, OUTPUT); pinMode(ADDR_CLOCK, OUTPUT); pinMode(ADDR_A24, OUTPUT); pinMode(IN_DQ00, INPUT); pinMode(IN_DQ01, INPUT); pinMode(IN_DQ02, INPUT); pinMode(IN_DQ03, INPUT); pinMode(IN_DQ04, INPUT); pinMode(IN_DQ05, INPUT); pinMode(IN_DQ06, INPUT); pinMode(IN_DQ07, INPUT); pinMode(IN_DQ08, INPUT); pinMode(IN_DQ09, INPUT); pinMode(IN_DQ10, INPUT); pinMode(IN_DQ11, INPUT); pinMode(IN_DQ12, INPUT); pinMode(IN_DQ13, INPUT); pinMode(IN_DQ14, INPUT); pinMode(IN_DQ15, INPUT); // // OUTPUT (address) // pinMode(ADDR_STROBE, OUTPUT); pinMode(ADDR_CLOCK, OUTPUT); pinMode(ADDR_DATAOUT, OUTPUT); //unsigned long addr = 0xFFFFF0; // debug unsigned long addr = 0x000000; while (addr < MAX_ADDR) { delayMicroseconds(4); // // SEND OUTPUT (address) // sendDataOut(addr); //addr += 0x1000; // debug addr += 1; // // READ INPUT (data) // input1 = 0; input2 = 0; input1 = digitalRead(IN_DQ00); input1 = input1 | (digitalRead(IN_DQ01) << 1); input1 = input1 | (digitalRead(IN_DQ02) << 2); input1 = input1 | (digitalRead(IN_DQ03) << 3); input1 = input1 | (digitalRead(IN_DQ04) << 4); input1 = input1 | (digitalRead(IN_DQ05) << 5); input1 = input1 | (digitalRead(IN_DQ06) << 6); input1 = input1 | (digitalRead(IN_DQ07) << 7); input2 = digitalRead(IN_DQ08); input2 = input2 | (digitalRead(IN_DQ09) << 1); input2 = input2 | (digitalRead(IN_DQ10) << 2); input2 = input2 | (digitalRead(IN_DQ11) << 3); input2 = input2 | (digitalRead(IN_DQ12) << 4); input2 = input2 | (digitalRead(IN_DQ13) << 5); input2 = input2 | (digitalRead(IN_DQ14) << 6); input2 = input2 | (digitalRead(IN_DQ15) << 7); // // SAVE/PRINT DATA OUT // // Reverse the order if needbe: //printf("%c", input1); //printf("%c", input2); if (fputc(input1, file) == EOF || fputc(input2, file) == EOF) { printf("error at addr 0x%x\n", addr); return 1; } } return 0; } Po skompilowaniu programu i uruchomieniu poprawionej wersji na liniach danych: #define ADDR_DATAOUT 24 // green #define ADDR_CLOCK 28 // yellow pojawiły się prawidłowe przebiegi prostokatne. Uruchomiłem program ponownie i uzyskałem nowy plik z dumpem zawartości pamięci Flash. Po otworzeniu tego nowego pliku dumpa edytorem Hexedit - zawartość Flash wygląda nastepująco: Jak widać pamięć Flash zawiera same bajty o wartość 0xFF (same jedynki) co jest prawidłową wartością dla "pustej" pamięcii tego typu. Można zatem stwierdzić, że układ Flash S29AL016J wlutowany w płytkę testową działa poprawnie. Następnym testem będzie zaprojektowanie podstawowej płytki developerskiej na układzie STM32F103 w obudowie BGA100: https://eu.mouser.com/ProductDetail/STMicroelectronics/STM32F103VCH6?qs=SU4Xa%2BYHGQrPPNgMrHBJwA%3D%3D Jeśli to zadziała to docelowo chciałbym móc użyć układu FPGA w obudowie BGA256: https://www.mouser.pl/ProductDetail/GOWIN-Semiconductor/GW1N-LV9PG256C7-I6?qs=A6eO%2BMLsxmTHr%2BX%2FAYxjNg%3D%3D Pozdrawiam Edytowano Maj 25, 2023 przez FlyingDutch 4 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!