STM32F1 USB

Started by tha, April 01, 2021, 07:19:59 AM

Previous topic - Next topic

tha

แต่ละ endpoint ถูกเกี่ยวข้องกับ two packet buffers (โดยปกติจะหนึ่งสำหรับ transmission และอีกหนึ่งสำหรับ reception). Buffers สามารถถูกวางที่ไหนก็ได้ภายใน the packet memory เพราะตำแหน่งของมันและขนาดถูกระบุใน a buffer description table, ซึ่งถูกวางตำแหน่งใน the packet memory อีกด้วยที่ the address ที่แสดงให้เห็นโดย the USB_BTABLE register. แต่ละ table entry ถูกเกี่ยวข้องถึง an endpoint register และมันประกอบด้วย four 16-bit words ดังนั้น table start address ต้องถูกจัดแนวให้ตรงกับ an 8-byte boundary เสมอ (สามบิตต่ำสุดของ USB_BTABLE register เป็น "000" เสมอ). Buffer descriptor table entries ถูกอธิบายใน the Section 23.5.3. ถ้า an endpoint เป็นแบบทิศทางเดียวและไม่ใช่ทั้งแบบ an Isochronous หรือ a double-buffered bulk, เพียง one packet buffer ถูกต้องการ (หนึ่งเดียวที่เกี่ยวพันกับ the supported transfer direction). table locations อื่นที่เกี่ยวพันกับ unsupported transfer directions หรือ unused endpoints, มีให้ใช้งานกับผู้ใช้. Isochronous และ double-buffered bulk endpoints มีการจัดการพิเศษของ packet buffers (อ้างอิงถึง Section 23.4.4 และ Section 23.4.3 ตามลำดับ). ความเกี่ยวพันกันระหว่าง buffer description table entries และ packet buffer areas ถูกให้รายละเอียดใน Figure 221.



แต่ละ packet buffer ถูกใช้อย่างใดอย่างหนึ่งระหว่าง reception หรือ transmission สตาร์ทจาก the bottom. The USB peripheral จะไม่เคยเปลี่ยนสิ่งที่อยู่ภายในของ memory locations ที่อยู่ติดกันกับ the allocated memory buffers; ถ้า a packet ใหญ่กว่า the allocated buffer length ถูกรับ (buffer overrun condition) the data จะถูกคัดลอกไปยัง the memory เฉพาะสูงถึง the last available location.

tha

Endpoint initialization

ขั้นตอนแรกในการเริ่มต้น an endpoint คือเขียนค่าที่เหมาะสมไปยัง the ADDRn_TX/ADDRn_RX registers เพื่อให้ the USB peripheral ค้นหา the data ที่จะถูกส่งพร้อมมีให้ใช้งานและ the data ที่จะถูกรับสามารถถูกบัฟเฟอร์ได้. The EP_TYPE bits ใน the USB_EPnR register ต้องถูกเซ็ตสอดคล้องกับ the endpoint type, ในที่สุดใช้ the EP_KIND bit เพื่อเปิดการใช้งานคุณลักษณะที่จำเป็นพิเศษใดๆ. บน the transmit side, the endpoint ต้องถูกเปิดการใช้งานโดยใช้ the STAT_TX bits ใน the USB_EPnR register และ COUNTn_TX ต้องถูกเริ่มต้น. สำหรับ reception, STAT_RX bits ต้องถูกเซ็ตเพื่อเปิดการใช้งาน reception และ COUNTn_RX ต้องถูกเขียนด้วย the allocated buffer size โดยใช้ the BL_SIZE และ NUM_BLOCK fields. Unidirectional endpoints, ยกเว้น Isochronous และ double-buffered bulk endpoints, จำเป็นต้องเริ่มต้นเฉพาะ bits and registers ที่เกี่ยวพันกับทิศทางที่รองรับ. เมื่อ the transmission และ/หรือ reception ถูกเปิดการใช้งาน, register USB_EPnR และตำแหน่ง ADDRn_TX/ADDRn_RX, COUNTn_TX/COUNTn_RX (ตามลำดับ), ไม่ควรถูกแก้ไขโดย the application software, เนื่องจาก the hardware สามารถเปลี่ยนค่าของมันได้ทันที. เมื่อ the data transfer operation เสร็จสมบูรณ์, จะถูกแจ้งให้ทราบโดย a CTR interrupt event, พวกมันสามารถถูกเข้าถึงอีกครั้งเพื่อเปิดการใช้งานใหม่ a new operation.

tha

IN packets (data transmission)

เมื่อได้รับ an IN token packet, ถ้า the received address ตรงกับที่กำหนดค่าไว้และ endpoint ที่ถูกต้องตัวหนึ่ง, the USB peripheral เข้าถึงสิ่งที่อยู่ภายในของ ADDRn_TX และ COUNTn_TX locations ภายใน buffer descriptor table entry ที่เกี่ยวพันกับ the addressed endpoint. สิ่งที่อยู่ภายในของ locations เหล่านี้ถูกเก็บใน internal 16 bit registers ADDR and COUNT ของมัน(ไม่สามารถเข้าถึงได้โดย software). The packet memory ถูกเข้าถึงอีกครั้งเพื่ออ่าน the first word ที่จะถูกส่ง (อ้างอิงถึง Structure and usage of packet buffers) และสตาร์ทการส่ง a DATA0 หรือ DATA1 PID สอดคล้องกับ USB_EPnR bit DTOG_TX. เมื่อ the PID เสร็จสมบูรณ์, the first byte จาก the word, ถูกอ่านจาก buffer memory, ถูกโหลดลงใน the output shift register เพื่อจะถูกส่งไปบน the USB bus. หลังจาก the last data byte ถูกส่, the computed CRC ถูกส่ง. ถ้า the addressed endpoint ไม่ถูกต้อง, a NAK or STALL handshake packet ถูกส่งแทนที่จะเป็น the data packet, สอดคล้องกับ STAT_TX bits ใน the USB_EPnR register.

The ADDR internal register ถูกใช้เป็น a pointer ไปยัง the current buffer memory location ในขณะที่ COUNT ถูกใช้เพื่อนับจำนวน bytes ที่ยังเหลือที่จะถูกส่ง. แต่ละ word ถูกอ่านจาก the packet buffer memory ถูกส่งไปบน the USB bus โดยเริ่มจาก the least significant byte. Transmission buffer memory ถูกอ่านโดยเริ่มจาก the address ที่ถูกชี้โดย ADDRn_TX for COUNTn_TX/2 words. ถ้า a transmitted packet ถูกประกอบด้วยจำนวนคี่ของ bytes, เฉพาะครึ่งล่างของ the last word ที่ถูกเข้าถึงจะถูกใช้.

ในการรับ the ACK ที่รับโดย the host, the USB_EPnR register ถูกอัปเดตในวิธีต่อไปนี้: DTOG_TX bit ถูกสลับ, the endpoint ถูกทำให้ใช้ไม่ได้โดยการเซ็ต STAT_TX=10 (NAK) และ bit CTR_TX ถูกเซ็ต. The application software ต้องวินิจฉัย the endpoint เป็นอันดับแรก, ซึ่งกำลังร้องขอ microcontroller attention โดยการตรวจสอบ the EP_ID และ DIR bits ใน the USB_ISTR register. การให้บริการของ the CTR_TX event จะเริ่มการเคลียร์ the interrupt bit; the application software จากนั้นเตรียม buffer อื่นที่ data เต็มที่จะถูกส่ง, อัปเดต the COUNTn_TX table location ด้วยจำนวนของ byte ที่จะถูกส่งในระหว่าง the next transfer, และสุดท้ายเซ็ต STAT_TX เป็น '11 (VALID) เพื่อเปิดการใช้งานใหม่ transmissions. ในขณะที่ the STAT_TX bits เท่ากันกับ 10 (NAK), IN request ใดๆที่ส่งไปยัง endpoint นั้นจะถูก NAK, แสดงให้เห็น a flow control condition: the USB host จะลองทำ the transaction อีกครั้งจนกว่าจะสำเร็จ. มันจำเป็นต้องดำเนินการตามลำดับของการทำงานดังที่กล่าวมาข้างต้นเพื่อหลีกเลี่ยงการสูญเสียการแจ้งเตือนของ a second IN transaction ที่ส่งไปยัง the same endpoint ตามมาทันทีที่ตัวแรกซึ่งทริก the CTR interrupt.


tha

OUT and SETUP packets (data reception)

tokens ทั้งสองนี้ถูกจัดการโดย the USB peripheral  ไม่มากก็น้อยในลักษณะเดียวกัน; ความแตกต่างในการจัดการของ SETUP packets ถูกให้รายละเอียดในย่อหน้าต่อไปนี้เกี่ยวกับ control transfers. เมื่อได้รับ an OUT/SETUP PID, ถ้า the address ตรงกับ a valid endpoint, the USB peripheral เข้าถึงสิ่งที่อยู่ภายในของ the ADDRn_RX and COUNTn_RX locations ภายใน the buffer descriptor table entry ที่เกี่ยวพันกับ the addressed endpoint. สิ่งที่อยู่ภายในของ the ADDRn_RX ถูกเก็บโดยตรงใน internal register ADDR ของมัน. ในขณะที่ COUNT ถูกรีเซ็ตเดี๋ยวนี้และค่าของ BL_SIZE และ NUM_BLOCK bit fields, ซึ่งถูกอ่านภายใน COUNTn_RX content ถูกใช้เพื่อเริ่มต้น BUF_COUNT, an internal 16 bit counter, ซึ่งถูกใช้เพื่อตรวจสอบ the buffer overrun condition ( internal registers เหล่านี้ทั้งหมดไม่สามารถเข้าถึงได้โดย software). Data bytes ที่ได้รับตามมาโดย the USB peripheral ถูกแพ็คเป็น words (the first byte ที่ได้รับถูกเก็บเป็น least significant byte) และจากนั้นถูกส่งถ่ายไปยัง the packet buffer เริ่มต้นจาก the address ที่บรรจุใน the internal ADDR register ในขณะที่ BUF_COUNT ถูกลดลงและ COUNT ถูกเพิ่มขึ้นที่แต่ละ byte transfer. เมื่อ the end of DATA packet ถูกตรวจพบ, ความถูกต้องของ the received CRC ถูกตรวจสอบและเฉพาะถ้าไม่มี errors เกิดขึ้นในนระหว่าง the reception, an ACK handshake packet ถูกส่งกลับไปยัง the transmitting host.

tha

ในกรณีของ wrong CRC หรือ errors ประเภทอื่นๆ (bit-stuff violations, frame errors, etc.), data bytes ยังคงถูกคัดลอกลงใน the packet memory buffer, อย่างน้อยก็จนถึง the error detection point, แต่ ACK packet ไม่ถูกส่งและ the ERR bit ใน USB_ISTR register ถูกเซ็ต. อย่างไรก็ตาม, ปกติแล้วไม่มี software action ที่ต้องการในกรณีนี้ : the USB peripheral จะกู้คืนจาก reception errors และยังคงพร้อมสำหรับ the next transaction ที่จะมา. ถ้า the addressed endpoint ไม่ถูกต้อง, a NAK or STALL handshake packet ถูกส่งแทนที่จะเป็น the ACK, สอดคล้องกับ bits STAT_RX ใน the USB_EPnR register และไม่มี data ถูกเขียนใน the reception memory buffers.

tha

Reception memory buffer locations ถูกเขียนเริ่มจาก the address ที่บรรจุใน the ADDRn_RX เป็นจำนวนของ bytes ที่ตรงกันกับ the received data packet length, รวมถึง CRC  (เช่น data payload length + 2), หรือสูงถึง the last allocated memory location, ตามที่กำหนดโดย BL_SIZE and NUM_BLOCK, แล้วแต่ว่ากรณีใดจะเกิดขึ้นก่อน. ด้วยวิธีนี้, the USB peripheral ไม่เคยเขียนเกินกว่า the end of the allocated reception memory buffer area. ถ้า the length of the data packet payload (actual number of bytes ที่ถูกใช้โดย the application) ใหญ่กว่า the allocated buffer, the USB peripheral จะตรวจพบ a buffer overrun condition. ในกรณีนี้, a STALL handshake ถูกส่งแทนที่จะเป็น the usual ACK เพื่อแจ้งให้ทราบปัญหาไปยัง the host, ไม่มี interrupt ถูกสร้างและ the transaction ถูกพิจารณาว่าล้มเหลว

tha

เมื่อ the transaction เสร็จสมบูรณ์อย่างถูกต้อง, โดยการส่ง the ACK handshake packet, the internal COUNT register ถูกคัดลอกกลับใน the COUNTn_RX location ภายใน the buffer description table entry, โดยปล่อยให้ BL_SIZE and NUM_BLOCK fields ไม่ได้รับผลกระทบ, ซึ่งโดยปกติไม่จำเป็นต้องเขียนซ้ำ, และ the USB_EPnR register ถูกอัปเดตในวิธีต่อไปนี้ : DTOG_RX bit ถูกสลับ, the endpoint ถูกทำให้ใช้ไม่ได้โดยการเซ็ต STAT_RX = '10 (NAK) และ bit CTR_RX ถูกเซ็ต. ถ้า the transaction ล้มเหลวเนื่องจาก errors หรือ buffer overrun condition, ไม่มีการดำเนินการใดๆที่ระบุไว้ก่อนหน้านี้เกิดขึ้น. The application software ต้องก่อนอื่นวินิจฉัย the endpoint, ซึ่งกำลังขอ microcontroller attention โดยการตรอจสอบ the EP_ID และ DIR bits ใน the USB_ISTR register. The CTR_RX event ถูกให้บริการโดยการกำหนด the transaction type เป็นอันดับแรก (SETUP bit ใน the USB_EPnR register); the application software ต้องเคลียร์ the interrupt flag bit และได้รับจำนวนของ received bytes โดยอ่าน the COUNTn_RX location ภายใน the buffer description table entry ที่เกี่ยวพันกับ the endpoint ที่กำลังถูกประมวลผล. หลังจาก the received data ถูกประมวลผล, the application software ควรเซ็ต the STAT_RX bits เป็น '11 (Valid) ใน the USB_EPnR, เปิดการใช้งาน transactions ต่อไป. ในขณะที่ the STAT_RX bits เท่ากับ '10 (NAK), OUT request ใดๆที่ส่งไป endpoint นั้นถูก NAK, แสดงให้เห็น a flow control condition: the USB host จะลองทำ the transaction อีกครั้งจนกว่ามันจะประสบผลสำเร็จ. จำเป็นต้องปฏิบัติตามลำดับการทำงานตามที่กล่าวไว้ข้างต้นเพื่อหลีกเลี่ยงการสูญเสียการแจ้งเตือนของ a second OUT transaction ที่ส่งถึง the same endpoint ตามมาทันทีที่ตัวแรกซึ่งทริก the CTR interrupt.

tha

Control transfers

Control transfers ถูกทำจาก a SETUP transaction, ตามด้วยศูนย์หรือมากกว่า data stages, ทิศทางเดียวกันทั้งหมด, ตามด้วย a status stage (a zero-byte transfer ในทิศทางที่ตรงกันข้าม). SETUP transactions ถูกจัดการโดย control endpoints เท่านั้นและคล้ายกันมากกับ OUT transactions (data reception) ยกเว้นว่าค่าของ DTOG_TX และ DTOG_RX bits ของ the addressed endpoint registers ถูกเซ็ตเป็น 1 และ 0 ตามลำดับ, เพื่อเริ่มต้น the control transfer, และทั้ง STAT_TX และ STAT_RX ถูกเซ็ตเป็น '10 (NAK) เพื่อให้ software ตัดสินใจว่าถ้า transactions ที่ตามมาต้องเป็น IN หรือ OUT ขึ้นอยู่กับ the SETUP contents. A control endpoint ต้องตรวจสอบ SETUP bit ใน the USB_EPnR register ที่แต่ละ CTR_RX event เพื่อแยกความแตกต่าง normal OUT transactions จาก SETUP transactions. A USB device สามารถกำหนดจำนวนและทิศทางของ data stages โดยการตีความ the data ที่ส่งถ่ายใน the SETUP stage, และจำเป็นต้อง STALL the transaction ในกรณีของ errors. ในการทำเช่นนั้น, ที่ทุก data stages ก่อนสุดท้าย, ทิศทางที่ไม่ได้ถูกใช้ควรถูกเซ็ตเป็น STALL, ดังนั้น, ถ้า the host กลับ the transfer direction เร็วเกินไป, มันจะได้รับ a STALL เป็น a status stage.