RTFDS

יש רושם שבעולם האמבדד, לא משנה כמה ניסיון יש לנו וכמה פעמים נכווינו בעבר, אנחנו תמיד חוזרים ונופלים על אותן טעויות. או שאולי זה רק אני? והאם, במקרה עליו אספר כאן, הייתי יכול בכלל לנהוג אחרת? אתם תשפטו.

מיקרו-בקר ATmega32U4 על לוח ארדואינו מיקרו
מיקרו-בקר ATmega32U4 על לוח ארדואינו מיקרו

קיבלתי, אם כן, פרויקט קטן שה"מוח" שלו מבוסס במידה רבה על השבב ATmega32U4, אותו מיקרו-בקר שמככב בלוחות ארדואינו מדגמי לאונרדו ומיקרו. יכולתי לצרוב עליו את ה-Bootloader של ארדואינו ולתכנת אותו דרך סביבת הפיתוח של ארדואינו, מה שהקל מאוד על העבודה. עם זאת, הפרויקט הצריך כתיבה וקריאה מפיני GPIO במהירות גדולה יותר ממה שהפונקציות המובנות של ארדואינו מאפשרות, וזה אומר לעבוד בגישה ישירה לרגיסטרים.

גם זה, איך נאמר, לא אתגר ענק בשבילי. ניהול GPIO דרך רגיסטרים הוא פחות או יותר הצעד הראשון שעושה כל מי שמתחיל להתקדם מעבר לארדואינו. ואכן, הלוגיקה הייתה פשוטה, הקוד התקמפל בלי יותר מדי תלונות… ובכל זאת התוכנה לא עבדה כמו שצריך. בלי להיכנס לפרטים, חלק מהסיגנלים לא הגיעו ליעדם: פיני קלט שהיו אמורים להראות לי 1 או 0 במצבים שונים הראו תמיד 0.

כיוון שלא אני תכננתי את החומרה של הפרויקט, אוטומטית חשדתי ששם התקלה, אבל לצערי לא הצלחתי למצוא שום סימוכין להשערה הזו. אז חזרתי למערכת ומיפיתי בזהירות את הסיגנלים השונים, תוך כדי פעולה, כדי לגלות בדיוק מי מהם עושה קונצים. הסתבר שכולם קשורים לפורט F, בעוד שפינים מפורטים אחרים, שביצעו משימות זהות לגמרי, עבדו בלי בעיה.

ההגדרות של פורט F בתחילת הקוד שלי נראו בסדר גמור, ומה שעוד יותר מרגיז, אם תסתכלו על מיפוי הפינים של המיקרו-בקר הזה לדגם ארדואינו מיקרו, תראו שפורט F משמש גם בלוחות הרשמיים (לא כמו 13 הפינים ש"נשכחו" בארדואינו Nano Every). אז אנחנו יודעים שהוא אמור לעבוד ושהוא יכול לעבוד. למה אצלי הוא לא עובד?

התחלתי לחפש בגוגל עם מילות המפתח הנכונות, ובמהרה עליתי על פוסט משנת 2009, שבו מישהו הזכיר בעיה דומה ומישהו אחר – אחד מזקני השבט העצבניים – נזף בו על כך שלא קרא את ה-Datasheet כמו שצריך. אנשים טובים אחרים השלימו את הפרטים, וזה מה שהסתבר: למיקרו-בקר הזה יש ממשק JTAG(!) לדיבוג, והממשק הזה מופעל כברירת מחדל, ודורס את הפונקציונליות הרגילה של פינים, ויושב (כמובן) על פורט F. כל עוד לא ידעתי את זה, יכולתי לשחק עם הרגיסטרים DDRF, PORTF ו-PINF עד שתעבור הקורונה, כלום לא היה קורה.

אך האם באמת כל כך קל למצוא את המידע הזה בדף הנתונים? גם עכשיו, כשאני יודע בדיוק מה לחפש, זה בכלל לא מובן מאליו. נכון ש-JTAG מוזכר בסעיף ה-Alternate functions של פורט F, אבל לא כתוב שהוא ברירת המחדל, וכמו להכעיס, גם לא כתוב שם איך לנטרל אותו. צריך ממש להתעמק ולאסוף רמזים כדי להבין מה הולך שם. בסופו של דבר מסתבר שיש פיוז שמכבה את ה-JTAG (מוגדר מן הסתם בלוחות הארדואינו הקנויים, אבל לא בפרויקט שלי שבו המיקרו-בקר הגיע מהמפעל), ואם לא רוצים לגעת בפיוז, אפשר לכבות את ה-JTAG גם על ידי כתיבת "1" בביט 7 ברגיסטר MCUCR. פעמיים. תוך 4 מחזורי שעון. ברגע שעשיתי את זה, פורט F חזר לתפקוד רגיל והבאג נעלם לגמרי.

במבט לאחור, אני חושב שהטעות שלי דווקא לא הייתה שלא קראתי את ה-Datasheet. הבאג הגיע מכיוון לגמרי לא צפוי למי שעובד עם ATmega אחרים, "רגילים", וכאמור גם אם הייתי קורא היה לי קשה למצוא את המידע הרלוונטי. הטעות הייתה שצרבתי Bootloader בלי להסתכל על הפיוזים, שמחתי שזה עובד (מה שלגמרי לא מובן מאליו, כשחושבים על זה!) והמשכתי הלאה. אפילו אם רק הייתי מעתיק הגדרות פיוזים קיימות של ארדואינו מיקרו מהאינטרנט, בלי לבדוק מה הן אומרות, הבעיה לא הייתה צצה כלל ולא הייתי יודע על כל הסיפור הזה.

בסופו של דבר, בזכות זה שהתעצלתי עם הפיוזים, למדתי משהו חדש (במחיר של זמן וכאב ראש, כמו שקורה בדרך כלל), ועכשיו גם אתם יודעים, ואנחנו לא נעשה טעות כזו יותר לעולם. נכון? 🙂

נ.ב. ראשי התיבות שבכותרת הם כידוע Read The Friendly Data Sheet.

להרשמה
הודע לי על
0 תגובות
Inline Feedbacks
הראה את כל התגובות