نمایش/عدم نمایش سایدبار
رفتن به بالای صفحه
آزادی حجاز از دست نااهلان
مهدی دمیرچیلو

آموزش آرم میکروکنترلر lpc1768 جلسه 15 usb device controller

به نام خدا : این مطلب ترجمه فصل 11 با عناون USB device controller از دیتاشیت با نام UM10360 مخصوص میکروهای LPC176x/5x هستش؛ تو این مطلب میخوام بحث USB میکرو  LPC1768 رو یکم بررسی کنم، درباره این موضوع کلا تو نت مطلب کم هستش، که خب خیلی بد هستش، طبق روال مطالب قبل، اون قسمت هایی که مشکل داشتم، ترجمش مشکل داره، کلا متنو ترجمه نکردم، بکارم نیومده یا چیزایی تو این مایه ها رو با رنگ صورتی مشخص کردم.
آموزش آرم میکروکنترلر lpc1768 جلسه 15 usb device controller

آموزش آرم میکروکنترلر lpc1768 جلسه 15 usb device controller


توجه مهم : در این مطلب هر عکس دیدید کوچیک هستش، روش کلیک کنید و در اندازه اصلی ببینید اون عکس رو.

توجه : این فصل مبحث USB controller رو توضیح داده که در تمام میکروهای سری LPC176x/5x غیر از LPC1767 وجود داره؛ در برخی از خانوده های LPC176x/5x، واحد USB controller همچینن میتونه پیکربندی بشه به عنوان Host or OTG operation.

خصوصیات واحد usb device controller میکروکنترلر

خصوصیات واحد usb device controller میکروکنترلر

1) کاملا با مشخصات USB 2.0 سازگار است ( مد full speed )
2) پشتیبانی کردن از 32 endpoint فیزیکی ( 16 تا منطقی )
3) پشتیبانی از مدهای تبادل داده : Control، Bulk، Interrupt و Isochronous
4) Scalable realization of endpoints at run time
5) قابلیت تعیین اندازه بافر Endpoint
6) پشتیبانی از ویژگی های SoftConnect و GoodLink
7) پشتیبانی تبادل داده از DMA بجز مد Control
8) Allows dynamic switching between CPU controlled and DMA modes
9) پشتیبانی از بافر دوبل ( Double buffer ) در مدهای Bulk و Isochronous
10) پشتیبانی از remote wake-up

 

پایه های پورت USB

پایه های پورت USB

توضیح پایه های USB
Vbus : این پایه ورودی هستش؛ وقتی پایه P0.30 در نقش Vbus قرار نگیرد، به صورت داخلی مقدار این پایه HIGH میشه ( زمانی که دستگاه قراره تغذیشو از میزبان بگیره، این پایه کاربرد داره )

USB_CONNECT : سیگنال کنترل ویژگی SoftConnect؛ این پایه خروجی هستش، و رو P2.9 سوار هستش.

Signal used to switch an external 1.5KΩ resistor under software control.

USB_UP_LED : سیگنال کنترل LED ویژگی GoodLink؛ این پایه خروجی هستش، نام این پایه USB_UP_LED هستش و رو P1.18 سوار هستش؛ این پایه LOW میشه وقتی که device پیکربندی شده ( non-control endpoint ها فعال شده باشن ) یا وقتی که host فعال شده و یه device روی bus شناسایی کرده؛ این پایه HIGH میشه وقتی که device پیکربندی نشده یا host فعال هستش و هیچ device یی هم روی bus شناسایی نکرده یا در وضعیت تعلیق سراسری قرار داره؛ این سیگنال مقدارش بین LOW و HIGH جابجا میشه ( چشمک میزنه / روشن خاموش میشه ) وقتی که host فعال هستش و یه فعالیت روی bus شناسایی کرده.

+USB_D و -USB_D : این دو پایه هم پایه های سیگنال تفاضلی هستن که برا انتقال دیتا ازشون استفاده میشه؛ این دو پایه رو P0.29 و P0.30 سوار هستند.

 

توضیحات ابتدایی

معاملات ( Transactions ) در درگاه تبادل داده USB بین endpoint های device و host انجام میشه؛ جهت Transaction ها توسط host تعیین میشه؛ تمام Transaction ها توسط host شروع میشه؛ OUT transaction یعنی ارسال داده از طرف host به device و IN transaction یعنی ارسال دیتا از device به host.

در یک عمل OUT transaction، فرستنده گیرنده آنالوگ USB در یک سیگنال دوطرفه +D و -D از USB bus دیتا دریافت میکنند؛ SIE دیتاهای سریال از سمت ATX دریافت میکند و تبدیلش میکنه به یک جریان دیتا موازی ( parallel data stream )؛ دیتای موازی در بافر endpoint متناظر در EP_RAM ذخیره میشن.

برای IN transaction، موتور رابط سریال (SIE) دیتاهای موازی از سمت بافر endpoint در EP_RAM رو میخونه و تبدیلشون میکنه به دیتای سریال، و سپس ارسالشون میکنه به USB bus توسط USB ATX.

یکبار که دیتا ارسال/دریافت شد، بافر endpoint قابل نوشتن/خوندن میشه؛ اینکه چگونه اینکار انجام شده است بستگی به نوع endpoint ها و مد عملیاتی داره؛ دو مد عملیاتی برای هر endpoint عبارتند از Slave ( کنترل شده توسط CPU ) و مد DMA.

در مد SLAVE، سی پی یو ( CPU ) دیتا رو انتقال میده بین RAM و بافر endpoint توسط Register Interface؛ در مد DMA، دی ام ای ( DMA ) دیتا رو انتقال میده بین RAM و بافر endpoint.

USB یک پروتکول 4 سیمه هستش که قابلیت ارتباط بین HOST و یک یا چند ( تا 127 ) peripherals رو ارائه میده؛

تمام معاملات ( تراکنش ها ) توسط host controller آغاز میشوند.

برنامه معاملات ( تراکنش ها ) HOST در قالب ( فریم ) های 1ms یی انجام میشود.

هر فریم حاوی یک (Start-Of-Frame (SOF میباشد ( که مشخص کننده شروع ارسال داده هستش )

دستگاه میتونه حداکثر 16 تا endpoint منطقی یا 32 تا endpoint فیزیکی داشته باشه.

فعالیت در USB bus port میتونه باعث بیدار شدن میکروکنترلر از مد Power-down بشه.

 

جدول لیست Endpoint ها

جدول لیست Endpoint ها

جدول زیر لیست تمام Endpoint ها رو براتون با جزئیات نوشته؛ Endpoint ها در زمان اجرا توسط رجیستر های Endpoint realization تحقق یافته ( realized ) و پیکربندی میشوند :
پیکربندی endpoint های ثابت
خب بریم سراغ توضیح جدول بالا، اول عکس زیر رو ببینید :

usb data size in several mode
توجه : در جدول بالا، با قسمت "سرعت خیلی بالا" کاری نداشته باشید، برای کامل بودن جدول قرارش دادم.
1) میبینید که هر مد انتقال داده، در هر سرعتی، اندازه داده اش یه محدودیتی داره که دو هر دو جدول بالا میتویند این مورد رو ببینید؛ که طبق این اندازه، بافر endpoint فوق ایجاد میشه.
2) در کل 16 تا endpoint داریم که endpoint0 همیشه کنترلی هستش ( منظورم تو تمام چیزهایی که از usb استفاده میکنن )، حالا هر endpoint میتونه یا ورودی باشه یا خروجی؛ لذا میبینید که تو جدول ( عکس ) اولی اطلاعات هر "2 ردیف 2 ردیف" یکسان هستش و فقط فرقشون تو IN یا OUT بودنشون هستش.
3) خب داستان logical endpoint و physical endpoint چیه؟ ما کاری به logical endpoint نداریم، میدونیم که در کل 16 تا endpoint داریم ولی خب هر endpoint هم ورودی خروجی داره فلذا 32 تا endpoint داریم در کل ( 16 تا endpoint ورودی و 16 تا endpoint خروجی )؛ زیاد خودتونو درگیر این اصطلاحات نکنید فعلا، مهم نیستن زیاد؛ همون بدونید که 16 تا endpoint داریم و هر endpoint هم ورودی / خروجی داره لذا درکل 32 تا endpoint داریم، همین، وسلام.
4) یه چیز جالب که تو LPC هستش این داستان بافر دوبل ( Double buffer ) هستش؛ که میاد اندازه بافر رو 2 برابر میکنه؛ حالا چه سود و ظرری داره و ... بعدا با هم میبینیم.
خب دیگه فک نکنم چیز دیگه ای مونده باشه که نگفته باشم، بریم سراغ ادامه مطلب.

 

معماری کنترل کننده دستگاه USB و توضیح هر قسمت

معماری کنترل کننده دستگاه USB

در شکل زیر بلوک دیاگرام ( معماری ) واحد USB device controller رو مشاهده میکنید :

بلوک دیاگرام کنترل کننده دستگاه USB
در ادامه تمام قسمت های بلوک دیاگرام فوق توضیح داده خواهد شد :

فرستنده و گیرنده آنالوگ ( Analog transceiver = ATX )

واحد USB Device Controller از یک فرستنده گیرنده آنالوگ ساخته شده؛ ATX عمل ارسال و دریافت دو طرفه دیتا رو به کمک پایه های +D و -D انجام میدهد.

 

موتور رابط سریال ( Serial Interface Engine = SIE )

( صحت ترجمه این پاراگراف حتما بررسی بشه )
عمل پیاده سازی لایه کامل پروتکول USB بر عهده SIE هستش؛ که کاملا سخت افزاری و سریع هستش و نیاز به مداخله firmware ( سییستم عامل / میکرو ) نداره؛ که انتقال داده بین بافرهای endpoint در EP_RAM و درگاه USB رو مدیریت میکنه؛ توابع این بلوک شامل موارد زیر هستش :

  1. تشخیص الگوی همگام سازی ( synchronization )
  2. تبدیل موازی/سریال ( تبدیل دیتای سریال به موازی و بلعکس؛ مثلا دیتا که میخوایم بفرستیم میایم مقدار 0x12 رو به این واحد میدیم که میاید به صورت یه رشته از بیت های پشت سر هم ارسال میکنه، یعنی دیتای موازی رو به دیتای سریال تبدیل کرد؛ یا مثلا یه سری 0 و 1 دریافت میکنه و تبدیلشون میکنه به یه دیتا مثل 0x27 )
  3. bit stuffing/de-stuffing ( این بحث stuffing بیشتر جهت همگام سازی و جلوگیری از بروز خطا استفاده میشه، که میاد بعد از هر 5-6 تا بیت 1، یک بیت 0 ارسال میکنه، یه چی تو این مایه ها؛ توضیحات بیشتر تو دیتاشیت USB2 بخش "7.1.9 Bit Stuffing " )
  4. بررسی و تولید CRC ( که خب فرمولش تو دیتاشیت USB ذکر شده ولی خب چون خود میکرو این کارارو میکنه و کاربر نقشی نداره تو این موضوع، بهش نمیپردازیم بیشتر از این - البته من هرچی سعی کردم نتونستم فرمول درستشو پیدا کنم! )
  5. بررسی و یا تولید PID
  6. به رسمیت شناختن address ( آدرسی که میزبان به دستگاه میده )
  7. بررسی و یا تولید handshake ( پکیج handshake هم ارسال و دریافتش به صورت خودکار انجام میشه، و تو کدنویسی میکرو، کاربر لازم نی کاری انجام بده )

 

حافظه رم اندپوینت ( Endpoint RAM = EP_RAM )

هر بافر endpoint درواقع یک FIFO مبتنی بر حافظه SRAM هستش؛ که این حافظه SRAM اختصاصی برای این هدف، اسمشو گزاشتن EP_RAM؛ هر endpoint دارای یک حافظه رزرو شده در EP_RAM هستش؛ مجموع تمام فضایی که EP_RAM نیاز داره، بستگی به تعداد endpoint های استفاده شده، حداکثر اندازه پکیج endpoint و یا پشتیبانی endpoint از بافر دوبل ( double buffering ) داره.
توجه : همون طور که قبلا گفتم، مدهای Bulk و Isochronous از بافر دوبل ( Double buffer ) پشتیانی میکنند.

 

کنترل دسترسی EP_RAM

این قسمت وظیفه هندل کردن ( رسیدگی کردن، انتقال داده ) تبادلات داده از/به EP_RAM رو بر عهده داره، و 3 منبع میتونن بهش دسترسی داشته باشن :

  1. CPU ( از طریق رجیسترهای مربوطه اش )
  2. SIE
  3. موتور DMA

 

DMA engine and bus master interface

When enabled for an endpoint, the DMA Engine transfers data between RAM on the AHB bus and the endpoint’s buffer in EP_RAM.
A single DMA channel is shared between all endpoints.
When transferring data, the DMA Engine functions as a master on the AHB bus through the bus master interface.

 

Register interface

رجیستر رابط کاربری، اجازه کنترل عملیات "USB Device Controller" رو به CPU میده؛ همچین فراهم میکنه یک راه برای نوشتن دیتا جهت ارسال در کنترلر و خوندن دیتا دریافتی از کنترلر.

 

ویژگی SoftConnect

The connection to the USB is accomplished by bringing D+ (for a full-speed device) HIGH through a 1.5 kOhm pull-up resistor.
The SoftConnect feature can be used to allow software to finish its initialization sequence before deciding to establish connection to the USB.
Re-initialization of the USB bus connection can also be performed without having to unplug the cable.

To use the SoftConnect feature, the CONNECT signal should control an external switch that connects the 1.5 kOhm resistor between D+ and +3.3V.
Software can then control the CONNECT signal by writing to the CON bit using the SIE Set Device Status command.

 

ویژگی GoodLink

این ویژگی نمایانگر "ارتباط خوب USB" هستش که از طریق تکنولوژی GoodLink فراهم شده است؛ وقتی که device با موفقیت سرشماری و پیکربندی بشه، LED مربوط به "ویژگی GoodLink" روشن میشه؛ در طول تعلیق ارتباط، LED خاموش میشه ( مثلا دستگاه ما به USB وصل شد، به کمک این LED میشه فهمید که ارتباط با Host برقرار شده )
در دیتاشت، این ویژگی با نام USB_UP_LED یا UP_LED اسم برده شده؛ UP_LED از طریق دستورات "SIE Configure Device" کنترل میشه.

 

پاور و کلاک

پاور و کلاک

Power requirements
پروتکول usb بر مدیریت پاور توسط device تاکیید دارد؛ این خیلی حیاتی میشه اگه device پاور اش رو از bus تامین کنه ( bus-powered device )؛ محدودیت های زیر باید رعایت شود توسط bus-powered device :
1) device در وضعیت پیکربندی نشده میتونه حداکثر 100mA از bus بکشه.
2) device در وضعیت پیکربندی شده تنها میتونه تا حداکثر مقدار تعریف شده جریان بکشه، مقدار حداکثر 500mA هستش.
3) یک دستگاه معلق میتونه تا حداکثر 2.5mA جریان بکشه.

 

Clocks
USB device controller clock sources
(توضیح این جدول)

 

Power management support
برای کمک در صرفه جویی پاور، دستگاه usb به صورت خودکار کلاک AHB master و usbclk رو وقتی استفاده نمیشن رو غیر فعال میکنه.

وقتی دستگاه کنترلر USB میره تو وضعیت معلق ( bus برای 3ms بیکاره )، ورودی usbclk  به کنترلر دستگاه به صورت خودکار غیرفعال میشه، تا کمکی به صرفه جویی پاور بکنه؛ با این حال اگه کاربر بخواد دسترسی داشته باشه به رجیسترهای کنترل device، کلاک usbclk باید فعال شود؛ برای اجازه دادن دسترسی به رجیسترهای کنترل device زمانی که در وضعیت تعلیق هستیم، رجیستر های USBClkCtrl و USBClkSt فراهم شده اند.

وقتی کاربر تمایل داره تا دسترسی داشته باشه به رجیسترهای کنترل device، اول باید مطمئن بشه که کلاک usbclk توسط بیت DEV_CLK_EN از رجیستر USBClkCtrl فعال شده باشه و سپس بررسی کنه که بیت DEV_CLK_ON از رجیستر USBClkSt تنظیم شده یا نه؛ بعد از تنظیم، usbclk در وضعیت فعال میمونه تا زمانی که بیت DEV_CLK_EN توسط کاربر پاک بشه.

وقتی تبادل DMA رخ میده، کنترل کننده device به صورت خودکار AHB master clock رو فعال میکنه؛ Once asserted، در وضعیت فعال میونه برا حداقل 2mS ( دو فریم )، برای کمک به اطمینان از این که DMA تحت تاثیر خاموش شده AHB master clock قرار نمیگیره؛ 2mS بعد از آخرین دسترسی DMA، واحد AHB master clock به صورت خودکار غیرفعال میشه تا کمکی در صرفه جویی پاور کرده باشه؛ البته اگه کاربر بخواد میتونه توسط رجیستر USBClkCtrl کلاک رو اجبار کنه تا در وضعیت فعال بمونه.
توجه کنید که AHB slave clock همیشه فعال هستش تا زمانی که بیت PCUSB از رجیستر PCONP فعال هستش؛ وقتی که کنترلر device مورد استفاده قرار نمیگیره، تمام کلاک های کنترلر device باید غیر فعال بشن ( با پاک کردن بیت PCUSB از رجیستر PCONP )

سیگنال USB_NEED_CLK جهت تسهیل در بیدار شدن ( خارج شدن ) میکرو از مد Power-down تعبیه شده سیگنال USB_NEED_CLK رخ میده اگه هر کدوم از بیت های رجیستر USBClkSt فعال بشه.

بعد از وارد شدن به وضعیت معلق با پاک کردن بیت DEV_CLK_EN و AHB_CLK_EN از رجیستر USBClkCtrl، بیت های DEV_CLK_ON و AHB_CLK_ON از رجیستر USBClkSt پاک خواهند شد وقتی که کلاک متناظر خاموش میشه، وقتی هر دو این بیت ها 0 هستش، سیگنال USB_NEED_CLK وضعیتش low میشه تا مشخص کنه که میکرو میتونه به مد Power-down بره ( با تنظیم رجیستر PCON )؛ وضعیت سیگنال USB_NEED_CLK رو میتونید توسط رجیستر USBIntSt بخونید.

هر نوع فعالیتی در bus در وضعیت معلق باعث میشه که سیگنال USB_NEED_CLK رخ بده؛ وقتی که میکرو در مد Power-down هستش و وقفه USB فعال هستش، رخ دادن سیگنال USB_NEED_CLK باعث بیدار شدن میکرو از مد Power-down میشه.

 

Remote wake-up

کنترلر دستگاه USB این قابلیت رو به کاربر میده تا عمل remote wake-up رو شروع کنه؛ عمل remote wake-up شامل ارسال سیگنال ( توسط Device ) روی USB bus میشه؛ این کار با پاک کردن بیت SUS از رجیستر "Set Device Status" انجام میشه؛ قبل از اعمال تغییر در رجیستر فوق، تمام کلاک های کنترلر device باید توسط رجیستر USBClkCtrl فعال بشن.

 

توضیح رجیسترهای واحد USB device controller

توضیح رجیسترهای واحد USB device controller

در جدول زیر لیست رجیستر های واحد USB Device Controller رو مشاهده میکنید که به صورت مستقیم توسط CPU قابل دسترسی هستند؛ SIE رجیسترهای دیگه یی داره که به صورت غیرمستقیم توسط کامند های SIE قابل دسترسی هستند.
USB device register map
برای ساده شدن کار، مثل جدول فوق، ریجسترها رو مبحث به مبحث توضیح میدم :

Clock control registers
رجیستر USBClkCtrl : کنترل کلاک USB
این رجیستر کلاک واحد USB Device Controller رو کنترل میکنه؛ هر زمان که کاربر میخواد رجیسترهای کنترلر device رو کنترل کنه، باید بیت های DEV_CLK_EN و AHB_CLK_EN رو فعال کنیم قبلش.
کاربر مجبور نیست اینکار رو برای دسترسی به هر رجیستری تکرار بکنه، با توجه به این که قبلا بیت های متناظر در رجیستر USBClkCtrl رو فعال کرده؛ توجه کنید که این رجیستر تنها زمانی کار میکنه و عملیاتی هستش که بیت PCONP از رجیستر PCUSB رو فعال کرده باشید؛ وقتی بیت PCONP از رجیستر PCUSB غیر فعال باشه، تمام کلاک های واحد کنترلر device غیر فعال هستن بدون در نظر گرفتن مقدار رجیسترهای دیگه.
توجه : رجیستر USBClkCtrl قابل خوندن/نوشتن هستش.
رجیستر USBClkCtrl
بیت 1 ( DEV_CLK_EN ) : -

Device clock enable. Enables the usbclk input to the device controller

بیت 4 ( AHB_CLK_EN ) : فعال کردن کلاک AHB ( توضیح بیشتر )

رجیستر USBClkSt : وضعیت کلاک USB
این رجیستر وضعیت دسترسی کلاک رو در خودش نگه میداره؛ بیتهای این رجیستر باهمدیگه سیگنال USB_NEED_CLK رو تشکیل میدن؛ وقتی یک کلاک توسط رجیستر USBClkCtrl فعال میشه، کاربر باید بیت متناظر با اون منبع کلاک رو در رجیستر USBClkSt بررسی کنه تا ببینه کلاک فعال شده یا نه، اگه فعال شده بود، اون وقت کاربر میتونه بره با دسترسی به رجیستر ادامه بده؛ کاربر نباید اینکار رو در هر بار دسترسی تکرار کنه، با توجه به این که بیت های رجیستر USBClkCtrl مختل نشدن ( تغییری نکردن - غیر فعال نشدن ).
توجه : رجیستر USBClkSt فقط خواندنی هستش.
رجیستر USBClkSt
بیت DEV_CLK_ON : -

Device clock on. The usbclk input to the device controller is active

بیت AHB_CLK_ON : -

AHB clock on.

Device interrupt registers
رجیستر USBIntSt : وضعیت وقفه USB
USB Device Controller دارای 3 خط وقفه هستش، این رجیستر این امکان رو به کاربر میده که وضعیت این 3 منبع وقفه رو به کمک 1 رجیستر ( یعنی همین رجیستر ) بخونیم؛ تمام این 3 منبع وقفه دارای یک کانال وقفه مشترک در Nested Vectored Interrupt Controller = NVIC هستند؛ این رجیستر همچنین شامل بیت وضعیت USB_NEED_CLK و بیت کنترل EN_USB_INTS هستش.
توجه : این رجیستر قابل خواندن/نوشتن هستش.
رجیستر USBIntSt
بیت USB_INT_REQ_LP : وضعیت خط وقفه با اولیت کم ( Low priority ) - این بیت فقط خواندنی هستش  - وقفه با اولیت کم داستان چیه؟
بیت USB_INT_REQ_HP : وضعیت خط وقفه با اولیت بالا ( High priority ) - این بیت فقط خواندنی هستش  - وقفه با اولیت بالا داستان چیه؟
بیت USB_INT_REQ_DMA : وضعیت خط وقفه DMA
بیت USB_NEED_CLK : واحد USB نیاز به یک "شانسایی کننده" برای کلاک داره، این بیت 1 میشه وقتی که فعالیت USB و یا یک تغییر در وضعیت پایه های دیتای USB شناسایی بشه، و اعلام میکنه که کلاک PLL ( که 48MHz هستش ) مورد نیاز هستش؛ یکبار که بیت USB_NEED_CLK یک میشه، بعد از آخرین پکیج که دریافت/ارسال شد برای مدل زمان 5ms صفر میشه یا 2ms بعد از تغییر وضعیت تعلیق ( SUS_CH ) که وقفه رخ داده؛ تغییر این بیت از 0 به 1 میتونه باعث بیدار شدن میکروکنترلر بشه اگر فعالیت در USB bus انتخاب شده باشه برای بیدار کردن از مد Power-down - این بیت فقط خواندنی هستش.
بیت EN_USB_INTS : فعال کردن تمام وقفه های USB؛ وقتی این بیت پاک میشه،
the Vectored Interrupt Controller does not see the ORed output of the USB interrupt lines

رجیستر USBDevIntSt : وضعیت وقفه USB Device
این رجیستر وضعیت هر کدوم از وقفه ها رو در خودش نگه میداره؛ مقدار 0 ( برا هر کدوم از بیت های این رجیستر ) یعنی وقفه ای نیست و 1 بیانگر وجود یک وقفه هستش.
توجه : بعد از خوندن این رجیستر، باید بیت ( های ) متناظر در USBDevIntClr رو پاک کنم، تا وقفه های فوق در دفعات بعدی بتونن رخ بدن.
توجه : این رجیستر فقط قابل خواندن هستش.
USB Device Interrupt Status register - USBDevIntSt
بیت FRAME : هر  1ms وقتی frame رخ میده، که در مد انتقال بسته همزمان ( isochronous ) مورد استفاده قرار میگیره.
بیت EP_FAST : وقفه Fast endpoint، اگه یک بیت از رجیستر اولیت وقفه  Endpoint ( رجیستر USBEpIntPri ) یک شود، بیت متناظرش در این رجیستر نیز یک میشه ( مشکل ترجمه )
بیت EP_SLOW : وقفه Slow endpoints، اگه یک بیت از رجیستر اولیت وقفه  Endpoint ( رجیستر USBEpIntPri ) یک شود، بیت متناظرش در این رجیستر نیز یک میشه ( مشکل ترجمه )
بیت DEV_STAT : این بیت یک میشه وقتی که USB bus ریست میشه یا تغییر تعلیق USB و یا رخداد تغییر ارتباط رخ میده. توضیح بیشتر
بیت CCEMPTY : رجیستر کد فرمان ( USBCmdCode ) خالی هستش ( و میشه دستوری جدیدی داخلش نوشت ) نفهیمدم
بیت CDFULL : رجیستر داده های فرمان ( USBCmdData ) پر هستش ( اکنون میشه دیتا رو خوند ) نفهیمدم
بیت RxENDPKT : پکیج فعلی در بافر endpoint به CPU منتقل شده.
بیت TxENDPKT : تعداد بایت های دیتا انتقال داده شده به بافر endpoint برابر تعداد بایت های از قبل تعیین شده ( توسط کاربر در 10 بیت PKT_LNGTH از رجیستر USBTxPLen ) هستش.
بیت EP_RLZED : -

Endpoints realized. Set when Realize Endpoint register (USBReEp) or MaxPacketSize register (USBMaxPSize) is updated and the corresponding operation is completed.

بیت ERR_INT : وقفه رخ دادن خطا، هر نوع خطا روی bus از سمت USB device باعث رخ دادان این وقفه میشه.

رجیستر USBDevIntEn : فعال/غیرفعال کردن وقفه های USB Device
1 کردن هر کدوم از بیت های این رجیستر باعث فعال شدن بیت متناظر در رجیستر USBDevIntSt میشه و باعث فعال شدن اون وقفه میشه؛ ( 0 کردن باعث غیر فعال شده وقفه میشه و بطبع 0 شدن بیت متناظر از رجیستر USBDevIntSt )

By default, the interrupt is routed to the USB_INT_REQ_LP interrupt line. Optionally, either the EP_FAST or FRAME interrupt may be routed to the USB_INT_REQ_HP interrupt line by changing the value of USBDevIntPri.

توجه : این رجیستر قابل خواندن/نوشتن هستش.
USB Device Interrupt Enable register _ USBDevIntEn
توجه : برای توضیح بیت های این رجیستر به همون رجیستر USBDevIntSt مراجعه کنید.

رجیستر USBDevIntClr : نوشتن 1 در هر بیت از این رجیستر باعث پاک شدن بیت متناظر از رجیستر USBDevIntSt؛ نوشتن 0 تاثیری نداره.
توجه : قبل از پاک کردن بیت های وقفه EP_SLOW یا EP_FAST، بیت متناظر از وقفه endpoint در رجیستر USBEpIntSt باید پاک بشه.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Device Interrupt Clear register _ USBDevIntClr
توجه : برای توضیح بیت های این رجیستر به همون رجیستر USBDevIntSt مراجعه کنید.

رجیستر USBDevIntSet : نوشتن 1 در هر بیت از این رجیستر باعث فعال شدن بیت متناظر از رجیستر USBDevIntSt میشه؛ نوشتن 0 تاثیری نداره. ( نقش این رجیستر چیه دقیقا؟ من متوجه نمیشم، حالا غیر از تست کردن وقفه، که یکبار بیایم به کمک این رجیستر فعالش کنیم تا رخ بده، کاربردش دقیقا کجا میشه رو نمیدونم )
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Device Interrupt Set register _ USBDevIntSet
توجه : برای توضیح بیت های این رجیستر به همون رجیستر USBDevIntSt مراجعه کنید.

رجیستر USBDevIntPri : اولویت بندی کردن وقفه USB Device ( توضیح بیشتر این رجیستر )

Writing one to a bit in this register causes the corresponding interrupt to be routed to the USB_INT_REQ_HP interrupt line.
Writing zero causes the interrupt to be routed to the USB_INT_REQ_LP interrupt line.
Either the EP_FAST or FRAME interrupt can be routed to USB_INT_REQ_HP, but not both.
If the software attempts to set both bits to one, no interrupt will be routed to USB_INT_REQ_HP.

توجه : این رجیستر فقط قابل نوشتن هستش.
USB Device Interrupt Priority register _ USBDevIntPri
بیت FRAME :
0 :
 وقفه FRAME به  USB_INT_REQ_LP هدایت میشود.
1 :
وقفه FRAME به USB_INT_REQ_HP هدایت میشود.
بیت EP_FAST :
0 : 
وقفه EP_FAST به  USB_INT_REQ_LP هدایت میشود.
1 : وقفه EP_FAST به USB_INT_REQ_HP هدایت میشود.
( خب یعنی چی که وقفه فلان به فلان چیز هدایت میشه؟ )

Endpoint interrupt registers
رجیسترهای این گروه، باعث تسهیل در رسیدگی به وقفه های endpoint میشوند؛ وقفه های Endpoint در مد عملیاتی Slave کاربرد دارن.

رجیستر USBEpIntSt : وضعیت وقفه Endpoint ها
هر physical non-isochronous endpoint ارائه شده توسط یک بیت در این رجیستر، که مشخص میکنه که یه وقفه اجرا شده است؛ تمام non-isochronous OUT endpoints یک وقفه تولید میکنند وقتی یه پکیج ( بدون خطا ) دریافت کردند؛ تمام non-isochronous IN endpoints تولید میکنند یک وقفه وقتی آنها با موفقیت یک بسته رو ارسال کردند یا وقتی که یک NAK handshake ارسال شد روی bus ( و وقفه در ویژگی NAK هم فعال هستش )؛ یک شدن یک بیت از این رجیستر یا یک شدن بیت EP_FAST یا EP_SLOW از رجیستر USBDevIntSt بستگی به بیت متناظر در USBDevIntPri / USBEpIntPri داره.
توجه : در Isochronous endpoints، رسیدگی به بسته های داده وقتی انجام میشه که وقتی FRAME رخ میده.
توجه : همونطور که قبلا ذکر شد در مد isochronous خطایابی نداریم، لذا وقفه های ارسال و دریافت ( که به کمکشون متوجه میشیم دیتا به درستی ارسال/دریافت شده ) رو هم ندارم.
توجه : این رجیستر فقط خواندنی هستش.
USB Endpoint Interrupt Status register _ USBEpIntSt
بیت 0 ( EP0RX ) : بیت وقفه دریافت دیتا مربوط به Endpoint 0
بیت 1 ( EP0TX ) : بیت وقفه ارسال دیتا یا ارسال NAK مربوط به Endpoint 0
توجه : همین تعریف بالا برا Endpoint 1 تا Endpoint 15 هم برقراره.

رجیستر USBEpIntEn : فعال/غیرفعال کردن وقفه های Endpoint
یک کردن هر یک از بیت های این رجیستر باعث یک شدن بیت متناظر در رجیستر USBEpIntSt میشه وقتی یک وقفه رخ میده برای endpoint مرتبط؛ 0 کردن هر یک از بیت های این رجیستر باعث یک شدن بیت متناظر در رجیستر USBDMARSt میشه وقتی یک وقفه رخ میده برای endpoint مرتبط.
توجه : این رجیستر قابل خواندن/نوشتن هستش.
USB Endpoint Interrupt Enable register _ USBEpIntEn

رجیستر USBEpIntClr : نوشتن 1 در هریک از بیتهای این رجیستر باعث میشه که SIE دستور Select Endpoint/Clear Interrupt رو برای physical endpoint متناظر اجرا کنه؛ نوشتن 0 تاثیری نداره؛ قبل از اجرای انتخاب دستور Select Endpoint/Clear Interrupt، بیت CDFULL از رجیستر USBDevIntSt توسط سخت افزار پاک میشه؛ پس از اتمام فرمان، بیت CDFULL از رجیستر USBDevIntSt فعال میشه، رجیستر USBCmdData شامل وضعیت endpoint هستش، بیت متناظر در USBEpIntSt هم پاک میشه.
نکات :

  • وقتی وقفه ای رو توسط رجیستر USBEpIntClr پاک میکنید، باید صبر کنید تا بیت CDFULL یک بشه تا مطمئن بشید که وقفه متناظر پاک شده.
  • پاک کردن چندین بیت به صورت همزمان توسط رجیستر USBEpIntClr ممکن هستش ولی پیشنهاد نمیشه.
  • رجیستر USBEpIntClr همون کاربرد دستور دستور Select Endpoint/Clear Interrupt از SIE رو داره ولی به جهت سهولت، استفاده از این رجیستر توصیه میشه.

هر physical endpoint بیت مختص به خودشو در این رجیستر داره.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Endpoint Interrupt Clear register _ USBEpIntClr

رجیستر USBEpIntSet : نوشتن 1 در هریک از بیت های این رجیستر باعث فعال شدن بیت متناظر در رجیستر USBEpIntSt میشه؛ نوشتن 0 تاثیری نداره  ( نقش این رجیستر چیه دقیقا؟ من متوجه نمیشم، حالا غیر از تست کردن وقفه، که یکبار بیایم به کمک این رجیستر فعالش کنیم تا رخ بده، کاربردش دقیقا کجا میشه رو نمیدونم )
هر endpoint بیت مختص به خودشو در این رجیستر داره.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Endpoint Interrupt Set register _ USBEpIntSet

رجیستر USBEpIntPri : -
این رجیستر متعیین میکنه که وقفه endpoint مرتبط بشه با بیت EP_FAST یا بیت EP_SLOW از رجیستر USBDevIntSt؛ اگه یک بیت از این رجیستر یک بشه، وقفه اش مرتبط میشه به EP_FAST و اگه 0 بشه مرتبط میشه به EP_SLOW؛ ارتباط چندگانه endpoints به EP_FAST یا EP_SLOW ممکن هستش.
توجه شود که رجیستر USBDevIntPri تعیین میکنه که وقفه EP_FAST مرتبط بشه به خط وقفه USB_INT_REQ_HP یا USB_INT_REQ_LP.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Endpoint Interrupt Priority register _ USBEpIntPri

Endpoint realization registers
رجیسترهای این گروه امکان شناسایی و پیکربندی endpoint ها در زمان اجرا رو بهمون میده.

الزامات EP_RAM :
USB device controller از RAM بر مبنای FIFO استفاده میکنه برای هر بافر endpoint؛ حافظه RAM اختصاص داده شده برای این هدف، حافظه رم Endpoint یا به اختصار EP_RAM صدا زده میشه؛ هر endpoint دارای یک فضای رزرو شده در EP_RAM هستش؛ مقدار فضای EP_RAM مورد نیاز برای هر endpoint بستگی داره به MaxPacketSize  و این که دارای بافر دوبل ( double buffer ) هستش یا نه؛ 32 word ( هر word حدود 4 بایت هستش ) EP_RAM مورد استفاده قرار میگیره توسط device برای ذخیره کردن اشاره گرهای بافر endpoint.

The EP_RAM is word aligned but the MaxPacketSize is defined in bytes hence the RAM depth has to be adjusted to the next word boundary.
Also, each buffer has one word header showing the size of the packet length received.

The EP_RAM space (in words) required for the physical endpoint can be expressed as :

مقدار فضای EP_RAM ( بر مبنای word ) مورد نیاز برای physical endpoint از فرمول زیر قابل محاسبه هستش :
EPRAMspace
که برا موارد تک-بافری  مقدار dbstatus = 1 و برا دو-بافری dbstatus = 2 هستش، از آنجایی که تمام endpoint های شناسایی شده فضای EP_RAM رو اشغال میکنه، مجموع EP_RAM مورد نیاز از فرمول زیر محاسبه میشه :
TotalEPRAMspace
که N تعداد endpoint های شناسایی شده هستش، مجموع EP_RAM محاسبه شده نباید بیشتر از 4096 بایت ( 4KB یا 1Kword ) بشه.

رجیستر USBReEp : -
نوشتن 1 در هریک از بیت های این رجیستر باعث میشه endpoint متناظر شناسایی ( realized ) بشه؛ نوشتن 0 باعث unrealized میشه؛ این رجیستر به وضعیت ریست خودش برمیگرده اگه ریستی روی bus رخ بده.
توجه : این رجیستر قابل خواندن/نوشتن هستش.
USB Realize Endpoint register _ USBReEp
بعد از reset، تنها endpoint های کنترلی شناسایی میشن؛ endpoint های دیگر در صورت نیاز شناسایی میشن با برنامه ریزی بیتهای متناظر در رجیستر USBReEp؛ فرمول محاسبه فضای EP_RAM مورد نیاز جهت شانسایی endpoint ها رو هم قبلا گفتم.
شبه کد زیر جهت شناسایی endpoint ها در یک عملیات چند مرحله ای هستش :

device به هر transaction یی که unrealized endpoints هستش، جواب نخواهد داد؛ دستور پیکربندی Device توسط SIE، تنها باعث شناسایی و فعال شدن endpoint ها برای transaction و پاسخ گویی میشه؛ برای توضیحات بیشتر جدول 244 رو ببینید ( چیزی که من فهیمدم : بعد از realize کردن، باید بریم از دستور setEndpointStatus مربوط به قسمت SIE استفاده کنیم و Endpoint مدنظر رو فعال کنیم )

رجیستر USBEpIn : -
هر endpoint یک رجیستر داره که مقدار MaxPacketSize برای اون endpoint رو در خودش ذخیره میکنه؛ این در واقع یک آرایه ای از رجیستر هستش؛ از این رو پیش از نوشتن، این رجیستر آدرس دهی میشه از طریق رجیستر USBEpIn.
این رجیستر ( USBEpIn ) شماره physical endpoint رو در خودش ذخیره میکنه؛
Writing to USBMaxPSize will set the array element pointed to by USBEpIn
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Endpoint Index register _ USBEpIn

رجیستر USBMaxPSize : -
بعد از ریست، مقدار control endpoint برابر 8 بایت میشه ( حداکثر اندازه اندپوینت کنترلی در مد سرعت پایین برابر 8 بایت هستش ) و بقیه endpoint ها 0 میشن؛ تغییر USBMaxPSize باعث خواهد شد تا آدرس بافر endpoint در EP_RAM دوباره محاسبه بشه؛ این یک فرایند چند مرحله ای هستش؛ در پایان بیت EP_RLZED از رجیستر USBDevIntSt یک خواهد شد ( جدول 193 )
توجه : این رجیستر قابل خواندن/نوشتن هستش.
USB MaxPacketSize register _ USBMaxPSize
USBMaxPSize array indexing در شکل زیر نشان داده شده است :
USB MaxPacketSize register array indexing
Endpoint Index توسط رجیستر USBEpIn تنظیم میشه؛ MPS_EP0 تا MPS_EP31 از طریق رجیستر USBMaxPSize قابل دسترسی هستن ( مشکل ترجمه )

USB transfer registers
رجیسترهای این گروه جهت تبادل داده بین بافرهای endpoint و RAM در مد SLAVE کاربرد دارد.

رجیستر USBRxData : برای یک OUT transaction، واحد CPU میاد دیتای توی بافر endpoint رو از طریق این رجیستر میخونه؛ قبل از خوندن این رجیستر، بیت RD_EN و LOG_ENDPOINT از رجیستر USBCtrl باید به درستی فعال بشن؛ در هنگام خوندن این رجیستر،دیتا از سمت بافر endpoint انتخاب شده میاد؛ داده ها در قالب endian کوچکی قرار دارند : بایت اول که از USB bus دریافت شد در موقعیت کم اهمیت ترین بایت USBRxData قرار میگیرد (برای خوندن داده ها، از رجیستر USBRxPLen هم کمک بگیریم )
توجه : بخش مربوط به توضیحات دستور Select Endpoint و Clear Buffer رو هم مطالعه کنید ( در بحث دریافت داده نقش دارند و باید ازشون استفاده کنیم )
توجه : این رجیستر فقط خواندنی هستش.
USB Receive Data register _ USBRxData

رجیستر USBRxPLen : این رجیستر بیانگر تعداد بایت های باقیمانده در بافر endpoint برای پکیج فعلی که شروع به خوندنش کردید توسط رجیستر USBRxData، این رجیستر همچین یه بیت داره که مشخص میکنه که این پکیج داده معتبر هستش یا نه؛ قبل از خوندن این رجیستر، بیت RD_EN و LOG_ENDPOINT از رجیستر USBCtrl باید به درستی مقدار دهی بشن؛ این رجیستر در هر بار خوندن دیتا از رجیستر USBRxData بروزرسانی میشه.
توجه : این رجیستر فقط خواندنی هستش.
USB Receive Packet Length register _ USBRxPLen
فیلد PKT_LNGTH : تعداد بایت های باقی مونده در بافر اندپوینت که هنوز نخوندیم؛ وقتی این فیلد 0 میشه، بیت RxENDPKT از رجیستر USBDevIntSt یک میشه.

بیت DV : بررسی اعتبار دیتا؛ این بیت برای isochronous endpoint ها مفید هستش؛ برای Non-isochronous endpoint ها یک وقفه رخ نمیده ( ترجمه بررسی بشه ) وقتی که یک بسته اشتباه دریافت شده ( منظورش از اشتباه همون بسته ای که درش خطا رخ داده هستش؟ )؛ اما اطلاعات اشتباه با یک bus reset میتونن ایجاد بشن؛ برای isochronous endpoint ها، انتقال داده ها حتی اگر یک بسته نادرست دریافت شود اتفاق می افتد؛ در این حالت بیت DV برای بسته 1 نمیشه.
سوال : هر چی فک میکنم به نظرم اشتباه گفته، چند در مد isochronous عمل خطایابی نداریم، اینطچوری میخواد صحت دیتا رو تشخیص بشه آخه.
0 : دیتا معتبر نیست.
1 : دیتا معتبر است.

بیت PKT_RDY : فید PKT_LNGTH معتبر هستش و بسته آماده خونده شدن هستش.

رجیستر USBTxData : برای یک IN transaction، واحد CPU دیتای endpoint رو در این رجیستر مینویسه؛ قبل از نوشتن در این رجیستر، بیت WR_EN و LOG_ENDPOINT از رجیستر USBCtrl باید به درستی مقدار دهی بشن و طول پکیح باید نوشته بشه در رجیستر USBTxPlen؛ با نوشتن در این رجیستر، دیتا در بافر endpoint انتخاب شده نوشته میشود؛ داده ها در قالب endian کوچکی قرار دارند : بایت اول که به USB bus ارسال شد در موقعیت کم اهمیت ترین بایت USBTxData قرار دارد.
توجه : بخش مربوط به توضیحات دستور Select Endpoint و Validate Buffer رو هم مطالعه کنید ( در بحث ارسال داده نقش دارند و باید ازشون استفاده کنیم )
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Transmit Data register _ USBTxData

رجیستر USBTxPLen : این رجیستر حاوی تعداد بایت های منتقل شده از CPU به بافر endpoint انتخاب شده هستش؛ قبل از نوشتن دیتا در رجیستر USBTxData، کاربر باید ابتدا طول پکیج ( که کوچکتر/مساوی MaxPacketSize هستش ) رو در این رجیستر بنویسه؛ بعد از هربار نوشتن در USBTxData، سخت افزار مقدار USBTxPLen رو 4 واحد کم میکنه ( یعنی انتقال دیتا به صورت 4 بایت 4 بایت هستش - چیزی که فهمیدم! )؛ بیت WR_EN و LOG_ENDPOINT از رجیستر USBCtrl باید فعال بشن برای انتخاب بافر endpoint دلخواه قبل از شروع این پردازش.
برای بافرهای دیتا بزرگتر از endpoint’s MaxPacketSize، کاربر باید دیتا رو در بسته هایی به اندازه MaxPacketSize ثبت کنه، و باقیمانده بایت ها رو در آخرین پکیج ارسال کند؛ برای مثال، اگه MaxPacketSize = 64 باشه و بافر دیتا که قراره ارسال بشه 130 بایت باشه، کاربر باید 2 بسته 64 بایتی ( دو بسته به تعداد بایت MaxPacketSize ) ارسال کنه ( که میشه 128 بایت، و میمونه 2 بایت ) و بقیه بایت ها رو ( که 2 بایت هستش ) رو در آخرین پکیج ارسال کنه، لذا در کل 3 پکیج ارسال میشه به USB.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Transmit Packet Length register _ USBTxPLen

رجیستر USBCtrl : این رجیستر عملیات انتقال دیتا در USB device رو کنترل میکنه؛ که میاد و بافر endpoint یی که قابل دسترسی هستش توسط رجیسترهای USBRxData و USBTxData رو انتخاب میکنه و خواندن و نوشتنشون رو فعال میکنه.
توجه : این رجیستر قابل خواندن/نوشتن هستش.
USB Control register _ USBCtrl
بیت RD_EN : کنترل مد Read؛ فعال کردن خواندن دیتا از بافر OUT endpoint ( که شماره endpoint رو توسط فیلد LOG_ENDPOINT مشخص میکنیم )؛ دیتا توسط رجیستر USBRxData خونده میشه؛ این بیت توسط سخت افزار پاک میشه وقتی که آخرین word پکیج فعلی توسط USBRxData خونده شد.
0 : مد Read غیرفعال هستش.
1 : مد Read فعال هستش.

بیت WR_EN : کنترل مد Write؛ فعال کردن نوشتن دیتا در بافر IN endpoint ( که شماره endpoint رو توسط فیلد LOG_ENDPOINT مشخص میکنیم )؛ دیتا توسط رجیستر USBTxData نوشته میشه؛ این بیت توسط سخت افزار پاک میشه وقتی که به اندازه مقدار رجیستر USBTxPLen دیتا ارسال شد.
0 : مد Write غیر فعال هستش.
1 : مد Write فعال هستش.

فیلد LOG_ENDPOINT : شماره منطقی Endpoint

SIE Command registers
رجیسترهای این گروه، جهت ارتباط با SIE مورد استفاده قرار میگیرند.
رحیستر USBCmdCode : -
این رجیستر جهت ارسال دستور و نوشتن دیتا در SIE بکار میره؛
دستورات نوشته شده در اینجا در SIE پخش میشه و در اینجا اعلام میشه
( This register is used for sending the command and write data to the SIE
پس از اجرای دستور، رجیستر خالی میشه و بیت CCEMPTY از رجیستر USBDevIntSt فعال میشه.
توجه : این رجیستر فقط قابل نوشتن هستش.
USB Command Code register _ USBCmdCode

رجیستر USBCmdData : -
این رجیستر شامل دیتای دریافتی بعد از اجرای دستور SIE هستش ( یعنی چی؟ )؛ وقتی دیتا آماده خوندن هستش، بیت CD_FULL از رجیستر USBDevIntSt فعال میشه.
توجه : این رجیستر فقط قابل خواندن هستش.
USB Command Data register _ USBCmdData

DMA registers
رجیسترهای این گروه برای مد عملیاتی DMA استفاده میشوند.
رجیستر USBDMARSt : -

A bit in this register associated with a non-isochronous endpoint is set by hardware when an endpoint interrupt occurs (see the description of USBEpIntSt) and the corresponding bit in USBEpIntEn is 0.
A bit associated with an isochronous endpoint is set when the corresponding bit in USBEpIntEn is 0 and a FRAME interrupt occurs.
A set bit serves as a flag for the DMA engine to start the data transfer if the DMA is enabled for the corresponding endpoint in the USBEpDMASt register.
The DMA cannot be enabled for control endpoints (EP0 and EP1).
USBDMARSt is a read-only register.

USB DMA Request Status register _ USBDMARSt
رجیستر USBDMARClr : -

Writing one to a bit in this register will clear the corresponding bit in the USBDMARSt register. Writing zero has no effect.

This register is intended for initialization prior to enabling the DMA for an endpoint. When the DMA is enabled for an endpoint, hardware clears the corresponding bit in USBDMARSt on completion of a packet transfer. Therefore, software should not clear the bit using this register while the endpoint is enabled for DMA operation.

USBDMARClr is a write-only register.

The USBDMARClr bit allocation is identical to the USBDMARSt register (Table 223).

USB DMA Request Clear register _ USBDMARClr
رجیستر USBDMARSet : -

Writing one to a bit in this register sets the corresponding bit in the USBDMARSt register. Writing zero has no effect.

This register allows software to raise a DMA request. This can be useful when switching from Slave to DMA mode of operation for an endpoint: if a packet to be processed in DMA mode arrives before the corresponding bit of USBEpIntEn is cleared, the DMA request is not raised by hardware. Software can then use this register to manually start the DMA transfer.

Software can also use this register to initiate a DMA transfer to proactively fill an IN endpoint buffer before an IN token packet is received from the host.

USBDMARSet is a write-only register.

The USBDMARSet bit allocation is identical to the USBDMARSt register (Table 223).

USB DMA Request Set register _ USBDMARSet
رجیستر USBUDCAH : -

The UDCA (USB Device Communication Area) Head register maintains the address where the UDCA is located in the RAM. Refer to Section 11.15.2 “USB device communication area” and Section 11.15.4 “The DMA descriptor” for more details on the UDCA and DMA descriptors. USBUDCAH is a read/write register.

USB UDCA Head register _ USBUDCAH
رجیستر USBEpDMASt : -

Bits in this register indicate whether DMA operation is enabled for the corresponding endpoint. A DMA transfer for an endpoint can start only if the corresponding bit is set in this register. USBEpDMASt is a read-only register.

USB EP DMA Status register _ USBEpDMASt
رجیستر USBEpDMAEn : -

Writing one to a bit to this register will enable the DMA operation for the corresponding endpoint. Writing zero has no effect.The DMA cannot be enabled for control endpoints EP0 and EP1. USBEpDMAEn is a write-only register.

USB EP DMA Enable register _ USBEpDMAEn
رجیستر USBEpDMADis : -

Writing a one to a bit in this register clears the corresponding bit in USBEpDMASt. Writing zero has no effect on the corresponding bit of USBEpDMASt. Any write to this register clears the internal DMA_PROCEED flag. Refer to Section 11.15.5.4 “Optimizing descriptor fetch” for more information on the DMA_PROCEED flag. If a DMA transfer is in progress for an endpoint when its corresponding bit is cleared, the transfer is completed before the DMA is disabled. When an error condition is detected during a DMA transfer, the corresponding bit is cleared by hardware. USBEpDMADis is a write-only register.

USB EP DMA Disable register _ USBEpDMADis
رجیستر USBDMAIntSt : -

Each bit of this register reflects whether any of the 32 bits in the corresponding interrupt status register are set. USBDMAIntSt is a read-only register.

USB DMA Interrupt Status register _ USBDMAIntSt
رجیستر USBDMAIntEn : -

Writing a one to a bit in this register enables the corresponding bit in USBDMAIntSt to generate an interrupt on the USB_INT_REQ_DMA interrupt line when set. USBDMAIntEn is a read/write register.

USB DMA Interrupt Enable register _ USBDMAIntEn
رجیستر USBEoTIntSt : -

When the DMA transfer completes for the current DMA descriptor, either normally (descriptor is retired) or because of an error, the bit corresponding to the endpoint is set in this register. The cause of the interrupt is recorded in the DD_status field of the descriptor. USBEoTIntSt is a read-only register.

USB End of Transfer Interrupt Status register _ USBEoTIntSt
رجیستر USBEoTIntClr : -

Writing one to a bit in this register clears the corresponding bit in the USBEoTIntSt register. Writing zero has no effect. USBEoTIntClr is a write-only register.

USB End of Transfer Interrupt Clear register _ USBEoTIntClr
رجیستر USBEoTIntSet : -

Writing one to a bit in this register sets the corresponding bit in the USBEoTIntSt register. Writing zero has no effect. USBEoTIntSet is a write-only register.

USB End of Transfer Interrupt Set register _ USBEoTIntSet
رجیستر USBNDDRIntSt : -

A bit in this register is set when a transfer is requested from the USB device and no valid DD is detected for the corresponding endpoint. USBNDDRIntSt is a read-only register.

USB New DD Request Interrupt Status register _ USBNDDRIntSt
رجیستر USBNDDRIntClr : -

Writing one to a bit in this register clears the corresponding bit in the USBNDDRIntSt register. Writing zero has no effect. USBNDDRIntClr is a write-only register.

USB New DD Request Interrupt Clear register _ USBNDDRIntClr
رجیستر USBNDDRIntSet : -

Writing one to a bit in this register sets the corresponding bit in the USBNDDRIntSt register. Writing zero has no effect. USBNDDRIntSet is a write-only register.

USB New DD Request Interrupt Set register _ USBNDDRIntSet
رجیستر USBSysErrIntSt : -

If a system error (AHB bus error) occurs when transferring the data or when fetching or updating the DD the corresponding bit is set in this register. USBSysErrIntSt is a read-only register.

USB System Error Interrupt Status register _ USBSysErrIntSt
رجیستر USBSysErrIntClr : -

Writing one to a bit in this register clears the corresponding bit in the USBSysErrIntSt register. Writing zero has no effect. USBSysErrIntClr is a write-only register.

USB System Error Interrupt Clear register _ USBSysErrIntClr
رجیستر USBSysErrIntSet : -

Writing one to a bit in this register sets the corresponding bit in the USBSysErrIntSt register. Writing zero has no effect. USBSysErrIntSet is a write-only register.

USB System Error Interrupt Set register _ USBSysErrIntSet

مدیریت وقفه

مدیریت وقفه

در این بخش درباره این که چگونه یک رخداد وقفه در هر endpoint یی مرتبط میشه به NVIC، شکل 30 بلوک دیاگرام مدیریت رخداد وقفه رو نشون داده.
تمام OUT endpoint ها با مد غیر از isochronous ( یعنی مدهای control و bulk و  interrupt ) یک وقفه تولید میکنند وقتی یک پکیج بدون خطا دریافت میکنند؛ تمام non-isochronous IN endpoint ها یک وقفه تولید میکنند وقتی یک بسته رو با موفقیت ارسال میکنند یا وقتی که یک سیگنال NAK ارسال مییکنند و وقفه NAK هم توسط رجیستر Set_Mode فعال شده باشه. ( این رجیستر در گروه ریجسترهای SIE قرار داره )؛ برای isochronous endpoint ها، وقفه FRAME هر 1ms تولید میشه. ( توضیح بیشتر؟ چرا هر 1ms وقفه تولید میکنه؟ چرا بعد از هربار دیریافت دیتای بدون خطا وقفه تولید نمیکنه؟ )
مدیریت وقفه در مد SLAVE و DMA متفاوت هستش ( از چی متفاوت هستش ؟ )
مد SLAVE :
اگه رخداد وقفه رخ بده در یک endpoint و وقفه endpoint هم فعال شده باشه در رجیستر USBEpIntEn، بیت وضعیت متناظر در رجیستر USBEpIntSt یک میشه؛ برای non-isochronous endpoint ها، رخداد وقفه تمام endpoint ها به نوع تقسیم میشن توسط بیت متناظر در رجیستر USBEpIntPri : رخداد وقفه endpoint سریع و کند؛
All fast endpoint interrupt events are ORed and routed to bit EP_FAST in the USBDevIntSt register.
All slow endpoint interrupt events are ORed and routed to the EP_SLOW bit in USBDevIntSt.

برای isochronous endpoint ها، بیت FRAME در رجیستر USBDevIntSt هر 1ms فعال میشه.
رجیستر USBDevIntSt وضعیت تمام رخدادهای وقفه endpoint رو نگه میداره، همچنین وضعیت وقفه های مختلف دیگر رو؛ به صورت پیشفرض، تمام وقفه ها ( اگه فعال شده باشه در رجیستر USBDevIntEn ) مرتبط میشن با بیت USB_INT_REQ_LP از رجیستر USBIntSt تا درخواست مدیریت وقفه low priority رو بدن ( یکم گیج شدم )؛ با این حال رجیستر USBDevIntPri میتونه مرتبط کنه FRAME یا بیت EP_FAST رو به بیت USB_INT_REQ_HP از رجیستر USBIntSt ( کلا گیج شدم ).
تنها یکی از رخدادهای وقفه EP_FAST یا FRAME میتونه مربتط بشه به بیت USB_INT_REQ_HP؛ اگه تلاش کنید که هر دو بیت فوق رو به USB_INT_REQ_HP مرتبط کنید، هر دو رخداد وقفه به USB_INT_REQ_LP مرتبط میشن.
رخداد وقفه Slow endpoint همیشه بصورت مستقیم به بیت USB_INT_REQ_LP مرتبط میشن برای مدیریت وقفه low priority توسط کاربر ( یکم تناقض وجود داره ).
سیگنال وقفه نهایی به NVIC وارد میشه ( مرتبط میشه ) توسط بیت EN_USB_INTS از رجیستر USBIntSt؛ وقفه USB مرتبط میشه به NVIC تنها اگه بیت EN_USB_INTS از رجیستر USBIntSt فعال بشه ( فرق وقفه نهایی با وقفه USB چیه؟ )
مد DMA : ( فعلا با مد DMA کاری ندارم )

If an interrupt event occurs on a non-control endpoint and the endpoint interrupt is not enabled in the USBEpIntEn register, the corresponding status bit in the USBDMARSt is set by hardware. This serves as a flag for the DMA engine to transfer data if DMA transfer is enabled for the corresponding endpoint in the USBEpDMASt register.

Three types of interrupts can occur for each endpoint for data transfers in DMA mode: End of transfer interrupt, new DD request interrupt, and system error interrupt. These interrupt events set a bit for each endpoint in the respective registers USBEoTIntSt, USBNDDRIntSt, and USBSysErrIntSt. The End of transfer interrupts from all endpoints are then Ored and routed to the EOT bit in USBDMAIntSt. Likewise, all New DD request interrupts and system error interrupt events are routed to the NDDR and ERR bits respectively in the USBDMAStInt register.

The EOT, NDDR, and ERR bits (if enabled in USBDMAIntEn) are ORed to set the USB_INT_REQ_DMA bit in the USBIntSt register. If the EN_USB_INTS bit is set in USBIntSt, the interrupt is routed to the NVIC.

USB Interrupt event handling
بعد از تکمیل توضیحات DMA، بلوک دیاگرام بالا هم تشریح بشه.

 

توضیح دستورات Serial interface engine ) SIE )

توضیح دستورات Serial interface engine ) SIE )

توجه : کل این مبحث مربوطه به مدیریت و کنترل رجیستر های گروه "SIE Command registers" که در بالا مشاهده میکنید.
توابع و رجیستر های SIE توسط دستورات قابل دسترسی هستند، که شامل یک کد فرمان و بدنبالش بایت های داده اختیاری ( قابل خواندن و نوشتن ) هستش ( نفهمیدم )؛ رجیسترهای USBCmdCode و USBCmdData برای دسترسی به رجیستر SIE مورد استفاده قرار میگیرند.
یک دسترسی کامل شامل 2 مرحله هستش :
توجه : فیلد CMD_PHASE از رجیستر USBCmdCode رو بررسی کنید تا دوهزاریتون بیوفته که مقداری که در ادامه بهش میدیم از کجا اومده.
1) مرحله Command : در فیلد CMD_PHASE ( از رجیستر USBCmdCode )، مقدار (0x05 (Command رو مینویسیم و به کمک فیلد CMD_PHASE ( از رجیستر USBCmdCode ) تنظیم میکنیم دستور کد دلخواه رو؛ بعد از کامل شدن دستور، بیت CCEMPTY از رجیستر USBDevIntSt فعال میشه.
2) مرحله Data ( اختیاری ) :
2.1) برای نوشتن : در فیلد CMD_PHASE ( از رجیستر USBCmdCode )، مقدار (0x01 (Write رو مینویسیم و به کمک فیلد CMD_WDATA ( از رجیستر USBCmdCode ) تنظیم میکنیم دیتا دلخواه رو برای عمل write؛ بعد از کامل شدن عمل write، بیت CCEMPTY از رجیستر USBDevIntSt فعال میشه.
2.2) برای خواندن : در فیلد CMD_PHASE ( از رجیستر USBCmdCode )، مقدار (0x01 (Read رو مینویسیم و به کمک فیلد CMD_CODE ( از رجیستر USBCmdCode ) تنظیم میکنیم دیتا دلخواه رو برای عمل read؛ بعد از کامل شدن عمل read، بیت CDFULL از رجیستر USBDevInSt فعال میشه جهت اطلاع از وجود دیتا در رجیستر USBCmdData برای خوندن؛ در مورد رجیسترهای چند-بایتی، بایت کم-ارزش اول در دسترس هستش.
کد زیر یک مثال از خوندن شماره FRAME دستور فعلی هستش ( خواندن 2 بایت ) :

یک مثال از تنظیم آدرس دستور ( نوشتن 1 بایت ) :

جدول زیر لیست تمام دستور کدهای SIE رو ارائه میده :
توجه : در جدول زیر Recipient یعنی گیرنده.
SIE command code table

 

در ادامه تک تک موارد جدول فوق رو توضیح میدم :

Set Address - تعیین آدرس
(Set Address (Command: 0xD0, Data: write 1 byte
تعیین آدرس device مد نظر و فعال کردنش ( مشکل ترجمه )؛ آدرس تنظیم شده برای Device مد نظر، بعد از مرحله وضعیت ( status stage ) ترنزکشن control اعمال خواهد شد ( گیچ شدم )؛ بعد از ریست bus، فیلد DEV_ADDR صفر میشه و بیت DEV_EN یک میشه؛ device به پکیج هایی با آدرس تابع 0x00 پاسخ خواهد داد، endpoint0 ( همان endpoint پیشفرض )
 Set Address command bit description
فیلد DEV_ADDR : آدرس device
بیت DEV_EN : فعال کردن device ( کدوم دیوایس؟ یعنی چی فعال کردن؟ )
Configure Device - پیکربندی دستگاه
(Configure Device (Command: 0xD8, Data: write 1 byte
مقدار 1 در بیت CONF_DEVICE بیان گر این هستش که device پبکربندی شده و به تمام non-control endpoint های فعال پاسخ خواهد داد؛ Control endpoint ها همیشه فعال هستند و پاسخ میدهند حتی اگه device پیکربندی نشده باشه، در وضعیت پیشفرض. ( بررسی ترجمه )
بیت CONF_DEVICE توسط سخت افزار پاک میشه وقتی که یک bus reset رخ میده.
وقتی بیت CONF_DEVICE یک میشه، سیگنال UP_LED مقدارش LOW میشه اگه device در وضعیت معلق نباشه ( SUS = 0 )
توجه : SUS بیت 2 از دستور Set/Get Device Status هستش.
Configure Device command bit description
Set Mode - تنظیم مد
(Set Mode (Command: 0xF3, Data: write 1 byte
Set Mode command bit description
بیت AP_CLK : همیشه PLL Clock فعال باشه ( چیزی که فهمیدم )
0 : USB_NEED_CLK is functional، کلاک 48MHz در صورت رفتن device به وضعیت معلق، میتونه متوقف بشه.
1 : مقدار USB_NEED_CLK یک هستش، کلاک 48MHz در صورت رفتن device به وضعیت معلق، نمیتونه متوقف بشه.
توجه : USB_NEED_CLK بیت 8 از رجیستر USBIntSt هستش.

بیت INAK_CI : وقفه در NAK برای Control IN endpoint
0 : تنها ترنزکشن های موفق وقفه تولید میکنند.
1 : ترنزکشن های موفق و NAKed IN وقفه تولید میکنند.
توجه : host فقط ACK میفرسته، اگه host دیتا رو درست نگیره میره تو وضعیت بیکاری، NACK و ... رو device میفرسته ( تو کتاب خوندم )
توجه : هموطور که قبلا گفتم در حالت IN، میزبان به دستگاه میگه برام دیتا بفرست، اگه در همین حین خطایی رخ داد، دستگاه NAK رو میفرسته، اگه خطایی رخ نداد دستگاه میاد و برا میزبان دیتا میفرسته، اگه مشکلی رخ نداد میزبان ACK میفرسته و اگه خطایی رخ داد، میزبان میره تو وضعیت بیکاری؛ لذا دیتاشیت از اصطلاح "NAKed IN" استفاده کرده.

بیت INAK_CO : وقفه در NAK برای Control OUT endpoint
0 : تنها ترنزکشن های موفق وقفه تولید میکنند.
1 : ترنزکشن های موفق و NAKed OUT وقفه تولید میکنند.
توجه : در حالت OUT، میزبان در دستگاه دیتا مینویسه، حالا اگه دستگاه دیتا رو از میزبان به درستی گرفت و خطایی رخ نداد، دستگاه ACK و اگر خطایی رخ داد NACK ارسال میکنه؛ لذا دیتاشیت از اصطلاح "NAKed OUT" استفاده کرده.

بیت INAK_II و INAK_IO  : این دو بیت شبیه همون بیت های INAK_CI و INAK_CO هستن فقط با این تفاوت که این دو بیت، برای مد انتقال Interrupt هستند و دو بیت INAK_CI و INAK_CO برای مد انتقال Control.

بیت INAK_BI و INAK_BO  : این دو بیت شبیه همون بیت های INAK_CI و INAK_CO هستن فقط با این تفاوت که این دو بیت، برای مد انتقال Bulk هستند و دو بیت INAK_CI و INAK_CO برای مد انتقال Control.

توچه مهم : در مد Isochronous ( همزمان ) چون فاز "تشخیص و تصیح خطا" حذف شده لذا وقفه ای برای بحث تشخیص موفق بودن ترنزکشن و دریافت NAK ( از سمت device ) نداریم؛ فلذا در این قسمت برای این مد بیتی نداریم.

Read Current Frame Number - خواندن شماره فریم فعلی
(Read Current Frame Number (Command: 0xF5, Data: read 1 or 2 bytes
سوال : کاربرد این دستور کجا هستش؟
شماره FRAME آخرین SOF دریافت شده رو برمیگردونه؛ شماره فریم 11 بیت هستش ( یعنی چی؟ )؛ ابتدا بایت کم ارزش ارسال میشود؛ تنها بایت اول مورد نیاز هستش برای خوندن ( بایت دوم کشکه؟ ).

  • در صورتی که هیچ SOF یی در ابتدای FRAME توسط device دریافت نشود، شماره FRAME که ارسال میشه مربوطه به آخرین SOF یی که با موفقیت دریافت شده.
  • در صورتی که SOF دریافتی حاوی خطای CRC باشه، شماره FRAME ارسالی خراب خواهد شد. ( یکم کیچ شدم )
Read Test Register
(Read Test Register (Command: 0xFD, Data: read 2 bytes
Test_Register حاوی 16 بیت هستش؛ که مقدار 0xA50F رو ارسال میکنه اگه کلاک USB ( کلاک usbclk و AHB slave ) در حال اجرا باشد.
سوال : خب یعنی برا این که ببینیم کلاک usb فعال هستش یا نه حتما باید این رجیستر رو بخونیم؟ روش دیگه ای نی؟
Set Device Status - تنظیم وضعیت دستگاه
(Set Device Status (Command: 0xFE, Data: write 1 byte
این دستور، بیت های رجیستر Device Status رو تنظیم میکنه ( کامند های دیگه مقدار کدوم رجیستر رو تنظیم میکنن؟ راستی همین رجیستر Device Status کجا هستش؟ پیداش نکردم که )
Set Device Status command bit description
بیت CON : این بیت وضعیت ارتباط فعلی device رو مشخص میکنه؛ این بیت برا بحث SoftConnect کاربرد داره؛ با خوندن این بیت، از وضعیت پایه CONNECT مطلع میشیم و با نوشن در این بیت، مقدار پایه CONNECT رو تعیین میکنیم؛ این بیت توسط سخت افزار پاک میشه وقتی که وضعیت ورودی Vbus برای بیش از 3ms برابر LOW هستش.
0 : نوشتن 0 باعث میشه پایه CONNECT مقدارش HIGH بشه.
1 : نوشتن 1 باعث میشه پایه CONNECT مقدارش LOW بشه.

بیت CON_CH : تغییر وضعیت ارتباط
0 : بعد از خوندن، این بیت پاک میشه.
1 : وقتی که مقاومت pull-up دستگاه(ها) به دلیل ناپدید شدن Vbus قطع شد، این بیت 1 میشه. ( همون جدا شدن دستگاه متصل به پورت USB )؛ فلذا وقفه DEV_STAT رخ میده.
سوال : یعنی وقتی یه دستگاه از پورت USB جدا میشه این بیت به ما میگه و بعد ما باید بریم دوباره سرشماری کنیم؟

بیت SUS : تعلیق ( معلق ) : این بیت بیانگر وضعیت فعلی تعلیق هستش؛ وقتی دستگاه در حالت معلق هستش (SUS = 1) و CPU مقدار 0 در این بیت مینویسه، دستگاه یه وضعیت remote wake-up تولید میکنه؛ این تنها زمانی رخ میده که دستگاه متصل باشه (CON = 1)؛ وقتی که دستگاه متصل نیست یا معلق نیست، نوشتن 0 یا 1 در این بیت، تاثیری نداره؛
0 : با رخ دادن هر گونه فعالیتی، این بیت 0 میشه.
1 : این بیت 1 میشه وقتی که device هیچگونه فعالیتی در upstream port برای مدت زمان بیش از 3ms نبینه.

بیت SUS_CH : شناسایی تغییر در بیت SUS، مقدار بیت SUS میتونه معکوس شود زیرا :

  • دستگاه به وضعیت معلق میره.
  • دستگاه اتصالش قطع میشه.
  • دستگاه resume signalling رو دریافت میکنه در upstream port

این بیت با خوندن مقدارش پاک میشه.
0 : بیت SUS تغییری نکرده.
1 : بیت SUS تغیر کرده؛ در زمان یکسان وقفه DEV_STAT رخ میده.
سوال : این بیت دیگه برا چیه؟ چه کاریه - مستقیم میریم بیت SUS رو میخونیم دیگه.

بیت RST : بیت Bus Reset؛ در یک bus reset، دستگاه به صورت خودکار به وضعیت پیشفرض میره، در وضعیت پیشفرض :

  1. دستگاه پیکربندی نشده.
  2. به آدرس 0 پاسخ میده.
  3. Control endpoint will be in the Stalled state
  4. تمام endpoint ها unrealized هستند غیر از EP0 و EP1.
  5. Data toggling is reset for all endpoints
  6. تمامی بافر ها پاک میشن.
  7. تغیری در وضعیت وقفه endpoint ها رخ نمیده.
  8. وقفه DEV_STAT رخ میده.

توجه : وقتی دستگاه متصل شده(CON=0)، یک Bus reset در نظر گرفته نمیشود.
0 : این بیت با خودن مقدارش پاک میشه.
1 : این بیت 1 میشه وقتی که یک bus reset دریافت میکنه، وقفه DEV_STAT رخ میده.
سوال : پس این بیت بیانگر دریافت یک bus reset هستش - خب چطوری bus reset ایجاد کنیم؟

Get Device Status - خوندن وضعیت دستگاه
(Get Device Status (Command: 0xFE, Data: read 1 byte
این دستور مقدار بیت های رجیستر Device Status رو میخونه ( این رجیستر رو پیدا نکردم )؛ بیت های این قسمت همانند جدول 246 ( دستور Set_Device_Status ) هستش.
توجه : برای اطمینان از صحت عملیات، بیت DEV_STAT از رجیستر USBDevIntSt باید پاک بشه قبل از استفاده دستور Get_Device_Status.
توجه : کد Get Device Status و Set Device Status یکسان هستش.
Get Error Code
(Get Error Code (Command: 0xFF, Data: read 1 byte
شرایط مختلف خطا میتونه داخل SIE بوجود بیاد؛ این دستور، آخرین کدخطا که رخ داده رو بر میگردونه؛ کد خطا داخل فیلد EC قرار داره؛ که انواع خطا به همراه مقدارش رو در جدول زیر مشاهده میکنید و نیازی به توضیح اضافه نیستش.
Get Error Code command bit description
خطای Babble و Sync چیه دیگه؟
Read Error Status
(Read Error Status (Command: 0xFB, Data: read 1 byte
فرق این دستور با Get_Error_Code چیه اون وقت؟
این دستور، میخونه 8 بیت خطای رجیستر از USB device رو ( مشکل ترجمه )؛ این رجیستر ثبت میکنه که کدام خطاها اخیرا در SIE رخ داده؛ اگه هر کدوم از بیت های جدول زیر 1 بشه، بیت ERR_INT از رجیستر USBDevIntSt فعال میشه؛ بیت های جدول زیر بعد از یکبار خودن این رجیستر پاک میشن.
Read Error Status command bit description
Select Endpoint
((Select Endpoint (Command: 0x00 - 0x1F, Data: read 1 byte (optional
سوال : این دستور Endpoint رو برای چی انتخاب میکنه؟ و کی انتخاب میکنه؟
جواب : برای ارسال دیتا ما باید اول Endpoint رو ( به کمک همین دستور ) انتخاب کنیم؛ بعد بیایم و از دستور Validate Buffer استفاده کنیم تا CPU بیاد و محتوای بافر Endpoint یی که انتخابش کردم رو ارسال کنه؛ بعد از خوندن اطلاعات هم باید Endpoint مدنظر رو انتخاب کنیم و بعد از دستور Clear Buffer استفاده کنیم.

نحوه محاسبه کد Command این دستور : برای این کار شماره فیزیکی endpoint ( که بین 0 تا 31 هستش ) رو با عدد 0 جمع میکنیم لذا کد Command بین 0 تا 31 میشه که کد هگزش میشه : 0x00 تا 0x1F.

Endpoint_0 : 0 + 0x00
Endpoint_1 : 1 + 0x00
.
.
.
Endpoint_x : x + 0x00

این دستور، اشاره گر داخلی رو مقدار دهی اولیه میکنه ( مشکل ترجمه ) تا بافر انتخاب شده در EP_RAM شروع به کار بکنه؛ این دستور یک بایت برمیگردونه که خب خوندنش اختیاری هستش، این بایت دریافتی حاوی یه سری اطلاعات اضافه در پکیج(ها) از بافر(های) endpoint هستش؛ در حالت استفاده از بافر تک کاناله endpoint ( یعنی از بافر دوبل استفاده نمیکیند )، بیت B_2_FULL معتبر نیست ( قابل استفاده نیست )
Select Endpoint command bit description
بیت FE : پر/خالی؛ این بیت وضعیت پر یا خالی بودن بافر(های) endpoint رو مشخص میکنه؛ برای IN endpoint ها، این بیت اند منطقی بیت B_1_FULL و B_2_FULL رو به ما میده؛ برای OUT endpoint ها، این بیت اور منطقی بیت B_1_FULL و B_2_FULL رو به ما میده؛ برای endpoint های تک بافری، این بیت، درواقع مقدار همون بیت B_1_FULL هستش.

0 : For an IN endpoint, at least one write endpoint buffer is empty.
1 : For an OUT endpoint, at least one endpoint read buffer is full.

بیت ST : بیت تشخیص متوقف شدن endpoint.
0 : endpoint انتخاب شده متوقف نشده.
1 : endpoint انتخاب شده متوقف شده.
سوال : این داستان متوقف شده و نشده چیه؟

بیت STP : بیت SETUP؛ محتوی این بیت بروزرسانی میشه بعد از هر بار دریافت موفق پکیچ ( مثلا یک ACKed package در physical endpoint خاص )
0 : این بیت با اجرای دستور "Select Endpoint/Clear Interrupt" در این endpoint، پاک میشه.
1 : آخرین پکیج دریافتی برای endpoint انتخاب شده، یک پکیج SETUP هستش.
بیت PO : بیت پکیج بازنویسی شده.
0 : بیت PO با اجرای دستور "Select Endpoint/Clear Interrupt" پاک میشه.
1 : پکیج دریافت شده قبلی بازنویسی شده توسط پکیج SETUP
بیت EPN : بیت EP NAKed بیانگر ارسال یک NAK هستش؛ اگه هاست یه پکیج OUT به یک بافر OUT پر شده بفرسته، دستگاه NAK ارسال میکنه؛ اگه دستاگه یک پکیج توکن IN به یک بافر خالی IN بفرسته، دستگاه NAK میفرسته ( گیچ شدم- تو کتاب این مورد هستش؟ من ندیدم )
0 : این بیت ریست میشه بعد از این که دستگاه یک ACK ارسال کرد بعد از OUT packet یا وقتی که دستگاه یک ACK دریافت کرد بعد از یک IN packet.
1 : این بیت 1 میشه وقتی که یک NAK ارسال شد و وقفه NAK هم فعال شود.

بین B_1_FULL : بافر وضعیت 1
0 : بافر 1 خالی هستش.
1 : بافر 1 پر هستش.

بین B_2_FULL : بافر وضعیت 2
0 : بافر 2 خالی هستش.
1 : بافر 2 پر هستش.

Select Endpoint/Clear Interrupt
(Select Endpoint/Clear Interrupt (Command: 0x40 - 0x5F, Data: read 1 byte
نحوه محاسبه کد Command این دستور : برای این کار شماره فیزیکی endpoint ( که بین 0 تا 31 هستش ) رو با عدد 64 جمع میکنیم لذا کد Command بین 64 تا 95 میشه که کد هگزش میشه : 0x40 تا 0x5F.

Endpoint_0 : 0 + 0x40
Endpoint_1 : 1 + 0x40
.
.
.
Endpoint_x : x + 0x40

این دستور معادل دستور "Select Endpoint" هستش فقط با تفاومت های زیر :

  • بیت متناظر ( endpoint انتخاب شده ) از رجیستر USBEpIntSt پاک میشه.
  • در مورد یک control OUT endpoint، بیت STP و PO متناظر در رجیستر Select Endpoint پاک میشن.
  • خوندن یک بایت اجباری هستش. ( در دستور Select Endpoint خودن 1 بایت اختیاری بود )

سوال : خب طرف چطوری میفهمه که من منظورم دستور Select Endpoint هستش یا Select Endpoint/Clear Interrupt ؟ کد دستوری جفتشون یکسان هستش - جفتشون هم 1 بایت میخونن - یکسان هستن که -
توجه : این دستور ممکنه توسط رجیستر های USBCmdCode و  USBCmdData فراخونده بشه، یا به وسیله تنظیم بیت متناظر در رجیستر USBEpIntClr؛ برای راحتی استفاده، توصیه میشه که از رجیستر USBEpIntClr استفاده کنید ( تا این دستور )

Set Endpoint Status
((Set Endpoint Status (Command: 0x40 - 0x5F, Data: write 1 byte (optional
توجه : دستور Set Endpoint Status و Select Endpoint/Clear Interrupt کد هردوشون یکسان هستش ولی Set Endpoint Status برا بحث نوشتن 1 بایت و Select Endpoint/Clear Interrupt برا بحث خوندن 1 بایت بکار میروند.
نحوه محاسبه کد Command این دستور : برای این کار شماره فیزیکی endpoint ( که بین 0 تا 31 هستش ) رو با عدد 64 جمع میکنیم لذا کد Command بین 64 تا 95 میشه که کد هگزش میشه : 0x40 تا 0x5F.

Endpoint_0 : 0 + 0x40
Endpoint_1 : 1 + 0x40
.
.
.
Endpoint_x : x + 0x40

توجه : به کمک همین "کد Command" محاسبه شده، در واقع endpoint یی که میخوایم تغییراتی درش بدیم رو انتخاب میکنیم.

توجه : دیتاشیت به اشتباه کد Command این دستور رو نوشته 0x40 تا 0x55 که خب طبق توضیحات خود دیتاشیت هم این مقدار اشباه هستش، و درستش 0x40 تا 0x5F هستش.

تمام بیت ها نمیتونه فعال بشه برای نوع های مختلف endpoint ( یعنی ممکنه بعضی از بیت های زیر رو نتونید برا یک نوع endpoint خاص استفاده کنید )
سوال : خب بیشتر توضیح بده - کدوم بیت ها برا کدوم endpoint ها قابل استفاده نیست؟
 Set Endpoint Status command bit description
بیت ST : بیت Stalled endpoint ( کلا ترجمه مربوط به این بیت مشکل داره )
یک Stalled control endpoint به صورت خودکار unstalled میشه وقتی که SETUP token دریافت میکنه، صرف نظر از محتوای پکیج؛ اگه endpoint باید در وضعیت stalled بمونه، CPU میتونه ببرتش تو وضعیت stall با 1 کردن این بیت؛ وقتی یک stalled endpoint تبدیل میشه به unstalled ( توسط دستور "Set Endpoint Status" یا به وسیله دریافت یک SETUP token ) آن نیز دوباره مقدار دهی میشه ( مشکل ترجمه )؛ این باعث میشه که بافر از بین بره : که در بافر OUT صبر میکنه برای یک DATA 0 PID و در یک بافر IN یک DATA 0 PID تولید میکنه. ( نفهمیدم )؛ تغیری در وضعیت وقفه endpoint ایجاد نمیشه؛ زمانی که unstalled هستش، نوشتن 0 در این بیت راه اندازی میکنه endpoint رو ( یعنی چی که راه اندازی میکنه؟ مشکل ترجمه )؛ وقتی یک endpoint هستش stalled  به وسیله دستور "Set Endpoint Status"، آن نیز هچنیندوباره مقدار دهی اولیه میشه ( مشکل ترجمه )
0 : endpoint هستش unstalled
1 : endpoint هستش stalled

بیت DA : غیر فعال کردن endpoint
0 : فعال کردن endpoint
1 : غیر فعال کردن endpoint

بیت RF_MO : مد Rate Feedback
0 : وقفه endpoint در مد Toggle هستش.
1 : وقفه endpoint در مد Rate Feedback هستش؛  This means that transfer takes place without data toggle bit

بیت CND_ST : -

Conditional Stall bit.
0 : Unstalls both control endpoints.
1 : Stall both control endpoints, unless the STP bit is set in the Select Endpoint register. It is defined only for control OUT endpoints.

Clear Buffer
((Clear Buffer (Command: 0xF2, Data: read 1 byte (optional
توجه : چیزی که من فهمیدم اینه که ابتدا باید به کمک دستور "Select Endpoint" اندپوینت مدنظر رو انتخاب کنیم و سپس از دستور Clear Buffer استفاده کنیم.
وقتی یک بسته OUT که توسط host ارسال شده، با موفقیت دریافت بشه، پرچم وضعیت Buffer_Full مربوط به FIFO داخلی، یک میشه ( مشکل ترجمه )؛ تمام بسته های بعدی ندید گرفته میشن با ارسال یک NAK؛ وقتی کاربر device داده ها رو خوند، باید بافر رو به وسیله "اجرای دستور Clear Buffer" پاک کنه؛ این کار فلگ داخلی Buffer_Full رو پاک میکنه؛ وقتی بافر پاک شد، بسته های جدید پذیرفته میشن.
وقتی بیت PO یک میشه، یعنی بسته قبلی که دریافت شده، دوباره بازنویسی شده توسط بسته SETUP ( یعنی چی؟ )؛ بیت Packet over-written یا همان PO تنها در control transfer مرود استفاده قرار میگیره؛ برطبق خصوصیات USB، پکیج SETUP باید صرف نظر از وضعیت بافر، پذیرفته بشه؛ کاربر باید همیشه بعد از خوندن دیتای SETUP وضعیت بیت PO رو بررسی کنه؛ اگه مقدارش 1 بود، باید دیتای خونده شده قبلی رو ندید بگیره ( دور بندازه )؛ بیت PO توسط اجرای دستور "Select Endpoint/Clear Interrupt" پاک میشه.
توجه : بیت PO تنها برای EP0 قابل استفاده هستش. ( چرا؟ )
سوال : بافر Buffer_Full کجا قرار داره؟ من پیداش نکردم.
Clear Buffer command bit description
Validate Buffer
(Validate Buffer (Command: 0xFA, Data: none
توجه : چیزی که من فهمیدم اینه که ابتدا باید به کمک دستور "Select Endpoint" اندپوینت مدنظر رو انتخاب کنیم و سپس از دستور Validate Buffer استفاده کنیم.
وقتی CPU دیتا رو در IN buffer مینویسه، کاربر باید دستور Validate Buffer رو اجرا کنه؛ که با این کار به سخت افزار میگیم بافر آمده ارسال به USB bus هستش؛ سخت افزار وقتی که IN token بعدی دریافت شد، محتوای بافر رو ارسال میکنه.
سوال : پرچم Buffer_Full تو Validate Buffer و Clear Buffer چه فرقی دارن با همدیگه؟
به صورت داخلی ( Internally، یعنی چی؟ )،یک پرچم وضعیت FIFO سخت افزاری وجود دارد که Buffer_Full صدا زده میشه؛ این پرچم فعال میشه توسط دستور Validate_Buffer و مقدارش پاک میشه وقتی دیتا ارسال شد روی USB bus و بافر خالی هستش. ( کدوم بافر؟ ).
یک بافر control IN  نمیتونه validate بشه وقتی که بافر OUT متناظرش بیت PO اش یک هستش یا شامل یک بسته SETUP در حال انتظار هستش؛ برای control endpoint عمل validate کردن بافر غیر صحیح خواهد بود وقتی بسته SETUP دریافت شده.

 

منبع : میکروکنترلر LPC1768 : فصل 11 با عناون USB device controller از دیتاشیت با نام UM10360

 

توجه : این مطلب به مرور زمان ویرایش و اصلاح میشه، جایی سوالی مشکلی چزی بود بگید بررسی کنم؛ فعلا منتشرش کردم، چون همینطور پیشنویس بمونه برا اصلاح و … میره 2-3 ماه دیگه!

 

خب امیدوارم این مطلب براتون مفید بوده باشه؛ اگه مفید بود یه فاتحه برای تمام اموات مسلمین بخونید ( هزینه این مطلب )؛ فعلا یا علی.

 

حدیث تصویری

گروه پرسش و پاسخ الکترونیکی در سروش
مهدی دمیرچیلو
ارسال دیدگاه
0

1) نظرات غیر فارسی به صورت خودکار حذف میشوند ( حداقل 5 حرف فارسی وارد کنید ).

2) به موارد درخواست پروژه/کد آماده و سوالاتی که بلد نباشم پاسخ داده نمیشه.

3) برای گزاشتن کدهاتون از این سایت استفاده کنید ( طبیعتا لینک کدتون رو باید برای من بفرستید! ) : debian

4) پسورد فایل های سایت : www.dmf313.ir