USB custom HID device implementation-STM32

Publisher:等放假的LwjLatest update time:2017-01-13 Source: eefocusKeywords:USB  STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

This document uses the USB firmware library and customizes it based on it to complete a USB-HID device. First, the usb_desc.c file stores the existence of various USB descriptors.

#include "usb_desc.h"

 

//USB standard device descriptor

const u8 DinkUsbDeviceDescriptor[DINK_USB_SIZ_DEVICE_DESC] = {

 

    USB_DEVICE_DESC_SIZE, //bLength field. The length of the device descriptor is 18 (0x12) bytes

    USB_DEVICE_DESCRIPTOR_TYPE, //bDescriptorType field. The device descriptor number is 0x01

    WBVAL(0x0200), //bcdUSB field. Here the version is set to USB1.1, which is 0x0110.

    0x00, //bDeviceClass field. We do not define the device class in the device descriptor.

    0x00, //bDeviceSubClass field. When the bDeviceClass field is 0, this field is also 0.

    0x00, //bDeviceProtocol field. When the bDeviceClass field is 0, this field is also 0.

    0x40, //bMaxPacketSize0 field. Maximum packet length of endpoint 0.

    WBVAL(0x7777), //idVender field. Vendor ID number, we use 0x8888 here, for experimental use only.

    WBVAL(0x8888), //idProduct field. Product ID number. Since this is the first experiment, we use 0x0001. \

    WBVAL(0x0100), //Device version

    0x01, //iManufacturer field. The index value of the manufacturer string, for easy memory and management

    0x02, //iProduct field. Index value of the product string. We just used 1, so let’s use 2 here.

    0x03, //iSerialNumber field. The serial number string index value of the device.

    0x01 //bNumConfigurations field. The number of configurations that the device has.

};

 

 

//USB report descriptor definition

const u8 HID_ReportDescriptor[]=

{

0x06,0xA0,0xFF,//Usage page (FFA0h, vendor defined)

0x09, 0x01, // usage (vendor defined)

0xA1, 0x01, // Application

0x09, 0x02 ,//Usage (vendor defined)

0xA1, 0x00, // Collection (Physical)

0x06,0xA1,0xFF,//Usage page (vendor defined)

// Input report

0x09, 0x03, // usage (vendor defined)

0x09, 0x04, // Usage (vendor defined)

0x15, 0x80, //Logical minimum value (0x80 or -128)

0x25, 0x7F, //Logical maximum value (0x7F or 127)

0x35, 0x00, //Physical minimum value (0)

0x45,0xFF,//Physical maximum value (255)

0x75, 0x08, //Report size (8 bits)

0x95, 0x40, //report value (64 fields)

0x81, 0x02, // input (data, variable, absolute)

// Output report

0x09, 0x05, // Usage (vendor defined)

0x09, 0x06, // Usage (vendor defined)

0x15, 0x80, //Logical minimum value (0x80 or -128)

0x25, 0x7F, //Logical maximum value (0x7F or 127)

0x35, 0x00, //Physical minimum value (0)

0x45,0xFF,//Physical maximum value (255)

0x75,0x08,//report length (8 bits)

0x95, 0x40, //report value (64 fields)

0x91, 0x02, // output (data, variable, absolute)

0xC0, //End of collection (Physical)

0xC0 // End of collection (Application)

};

//Through the definition of the report descriptor above, we know that the returned input report has 8 bytes.

//The output report also has 64 bytes. As for what these 64 bytes of data are used for, it is up to the user to determine what they are used for.

//It’s up to you to decide.

//////////////////////////////Report descriptor completed//////////////////////////////

 

 

//usb configuration descriptor

const u8 DinkUsbConfigDescriptor[DINK_USB_SIZ_CONFIG_DESC] = {

    /***************Configuration Descriptor***************************/

    USB_CONFIGUARTION_DESC_SIZE, //bLength field. The length of the configuration descriptor is 9 bytes.

    USB_CONFIGURATION_DESCRIPTOR_TYPE, //bDescriptorType field. The configuration descriptor number is 0x02.

    //wTotalLength field. The total length of the configuration descriptor set,

    //Including the configuration descriptor itself, interface descriptor, class descriptor, endpoint descriptor, etc.

    WBVAL( 

    USB_CONFIGUARTION_DESC_SIZE + //Configuration descriptor

    USB_INTERFACE_DESC_SIZE + //Interface 1 descriptor

    9 + //hid descriptor

    USB_ENDPOINT_DESC_SIZE + //Endpoint descriptor

    USB_ENDPOINT_DESC_SIZE //Endpoint descriptor

    ),

    0x01, //bNumInterfaces field. The number of interfaces included in this configuration, only one interface.

    0x01, //bConfiguration field. The value of this configuration is 1.

    0x00, //iConfigurationz field, string index of the configuration. None here, 0.

    USB_CONFIG_BUS_POWERED , //bmAttributes field, the attributes of the device

    USB_CONFIG_POWER_MA(500), //bMaxPower field, the maximum current required by the device

 

    /*************************The first interface descriptor, hid device**********************/

    USB_INTERFACE_DESC_SIZE, //bLength field. The length of the interface descriptor is 9 bytes.

    USB_INTERFACE_DESCRIPTOR_TYPE, //bDescriptorType field. The interface descriptor number is 0x04.

    0x00, //bInterfaceNumber field. The number of the interface, the first interface, is numbered 0.

    0x00, //bAlternateSetting field. The alternate number of this interface is 0.

    0x02, //bNumEndpoints field. The number of non-zero endpoints. This interface has 2 batch endpoints

 

    USB_DEVICE_CLASS_HUMAN_INTERFACE, //bInterfaceClass field. The class used by this interface. The code for the mass storage device interface class is 0x08. ,

   

    0x00, //bInterfaceSubClass field. The subclass used by this interface. In the HID1.1 protocol,

                                            //Only one subclass is specified: the subclass that supports BIOS boot.

                                            //USB keyboard and mouse belong to this subclass, and the subclass code is 0x01.

                                            //But here we are a custom HID device, so we don't use subclasses.

   

    0x00, //bInterfaceProtocol field. If the subclass is a subclass that supports booting,

                                            //The protocol can select mouse and keyboard. The keyboard code is 0x01 and the mouse code is 0x02.

                                            //Custom HID device, no protocol is used.

 

    0x00, //iConfiguration field. The string index value of the interface. None here, 0.

 

    /*************************HID report descriptor****************************/

    //bLength field. There is only one subordinate descriptor under this HID descriptor, so the length is 9 bytes.

     0x09,

     

     //bDescriptorType field. The HID descriptor number is 0x21.

     0x21,

     

     //bcdHID field. This protocol uses the HID1.1 protocol. Note that the low byte comes first.

     0x10,

     0x01,

     

     //bCountyCode field. The country code for the device. Here, the United States is selected, code 0x21.

     0x21,

     

     //bNumDescriptors field. The number of subordinate descriptors. We only have one report descriptor.

     0x01,

     

     //bDescriptorType field. The type of the lower-level descriptor is a report descriptor, numbered 0x22.

     0x22,

     

     //bDescriptorLength field. The length of the lower-level descriptor. The lower-level descriptor is the report descriptor.

     sizeof(HID_ReportDescriptor)&0xFF,

     (sizeof(HID_ReportDescriptor)>>8)&0xFF,

    /*************************Endpoint Descriptor**********************************/

    /* Endpoint descriptor */

    USB_ENDPOINT_DESC_SIZE, //bLength field. The endpoint descriptor length is 7 bytes.

    USB_ENDPOINT_DESCRIPTOR_TYPE, //bDescriptorType field. The endpoint descriptor number is 0x05.

    USB_ENDPOINT_IN(1), //bEndpointAddress field. The address of the endpoint. We use the input endpoint 1 of D12.

    USB_ENDPOINT_TYPE_INTERRUPT, //bmAttributes field. D1~D0 is the endpoint transfer type selection.

    WBVAL(0x0040), //wMaxPacketSize field. The maximum packet length of this endpoint. The maximum packet length is 64 bytes.

    0x01, //bInterval field. Endpoint query time, endpoint query time, meaningless here.

    /***********************Endpoint Descriptor*******************************************/

    USB_ENDPOINT_DESC_SIZE, //bLength field. The endpoint descriptor length is 7 bytes.

    USB_ENDPOINT_DESCRIPTOR_TYPE, //bDescriptorType field. The endpoint descriptor number is 0x05.

    USB_ENDPOINT_OUT(1), //bEndpointAddress field. The address of the endpoint. We use the input endpoint 1 of D12.

    USB_ENDPOINT_TYPE_INTERRUPT, //bmAttributes field. D1~D0 is the endpoint transfer type selection.

    WBVAL(0x0040), //wMaxPacketSize field. The maximum packet length of this endpoint. The maximum packet length is 64 bytes.

    0x01, //bInterval field. Endpoint query time, endpoint query time, meaningless here.

};

 

 

 

 

 

/****************************Definition of language ID********************/

const u8 DinkUsbLanguageId[DINK_USB_SIZ_STRING_LANGID]=

{

    0x04, //The length of this descriptor

    0x03, // string descriptor

    //0x0409 is the ID for American English

    0x09,

    0x04

};

 

 

////////////////////////////Language ID completed////////////////////////////////////

 

//Unicode string descriptor

//Deng Xiaojun's USB mouse

const u8 DinkUsbManufacturerStringDescriptor[DINK_USB_SIZ_STRING_VENDOR]=

{

    32, //The length of the descriptor is 32 bytes

    0x03, //The type code of the string descriptor is 0x03

    0x44, 0x00, //D

    0x49, 0x00, //I

    0x4e, 0x00, //N

    0x4b, 0x00, //K

    0x5f, 0x00, //_

    0x48, 0x00, //H

    0x49, 0x00, //I

    0x44, 0x00, //D

    0x5f, 0x00, //_

    0x44, 0x00, //D

    0x45, 0x00, //E

    0x56, 0x00, //V

    0x49, 0x00, //I

    0x43, 0x00, //C

    0x45, 0x00  //E

 

};

///////////////////////////End of manufacturer string/////////////////////////////

 

 

//Product string descriptor

const u8 DinkUsbProductStringDescriptor[DINK_USB_SIZ_STRING_PRODUCT]=

{

    32, //The length of the descriptor is 32 bytes

    0x03, //The type code of the string descriptor is 0x03

    0x44, 0x00, //D

    0x49, 0x00, //I

    0x4e, 0x00, //N

    0x4b, 0x00, //K

    0x5f, 0x00, //_

    0x48, 0x00, //H

    0x49, 0x00, //I

    0x44, 0x00, //D

    0x5f, 0x00, //_

    0x44, 0x00, //D

    0x45, 0x00, //E

    0x56, 0x00, //V

    0x49, 0x00, //I

    0x43, 0x00, //C

    0x45, 0x00  //E

};

//////////////////////////End of product string/////////////////////////////

 

//Unicode encoding of the string "2008-07-07"

//8-bit little-endian format

const u8 DinkUsbSerialNumberStringDescriptor[DINK_USB_SIZ_STRING_SERIAL]={

    22, //The length of the descriptor is 22 bytes

    0x03, //The type code of the string descriptor is 0x03

    0x32, 0x00, //2

    0x30, 0x00, //0

    0x31, 0x00, //1

    0x35, 0x00, //5

    0x2d, 0x00, //-

    0x30, 0x00, //0

    0x33, 0x00, //3

    0x2d, 0x00, //-

    0x32, 0x00, //2

    0x31, 0x00  //1

};

///////////////////////End of product serial number string/////////////////////////

 

//Product Serial Number

u8 DinkUsbStringSerialUniqueId[DINK_USB_SIZ_STRING_SERIAL_UNIQUE_ID] =

{

    DINK_USB_SIZ_STRING_SERIAL_UNIQUE_ID, //descriptor length

    0x03 //Descriptor type encoding

/* Serial number The code will be

 

You can modify this file to implement different devices. The second is the usb_prop.c file, which defines a series of callback functions used in the USB enumeration phase.

#include "usb_prop.h"

 

u32 ProtocolValue;

 

//Indicates how many endpoints and how many configurations there are

DEVICE Device_Table =

{

    EP_NUM,

    1

};

 

//static u8 s_Request = 0; //Record the current request value

 

//Device descriptor

ONE_DESCRIPTOR Device_Descriptor =

{

    (u8*)DinkUsbDeviceDescriptor,

    DINK_USB_SIZ_DEVICE_DESC

};

 

//Configuration descriptor

ONE_DESCRIPTOR Config_Descriptor =

{

    (u8*)DinkUsbConfigDescriptor,

    DINK_USB_SIZ_CONFIG_DESC

};

//Report descriptor

ONE_DESCRIPTOR DinkUsb_Report_Descriptor =

{

    (u8*)HID_ReportDescriptor,

    HID_ReportDescSize

};

 

//Report descriptor

ONE_DESCRIPTOR DinkUsb_Hid_Descriptor =

{

    (u8*)(DinkUsbConfigDescriptor+9),

    9

};

 

 

 

// string descriptor

ONE_DESCRIPTOR String_Descriptor[4] =

{

    {(u8*)DinkUsbLanguageId, DINK_USB_SIZ_STRING_LANGID},

    {(u8*)DinkUsbManufacturerStringDescriptor, DINK_USB_SIZ_STRING_VENDOR},

    {(u8*)DinkUsbProductStringDescriptor, DINK_USB_SIZ_STRING_PRODUCT},

    {(u8*)DinkUsbSerialNumberStringDescriptor, DINK_USB_SIZ_STRING_SERIAL}

};

 

 

 

//USB process processing function array

DEVICE_PROP Device_Property =

{

    Dink UsbIns,

    DinkUsbReset,

    DinkUsbStatus_In,

    DinkUsbStatus_Out,

    DinkUsbData_Setup,

    DinkUsbNoDataSetup,

    DinkUsbGetInterfaceSetting,

    DinkUsbGetDeviceDescriptor,

    DinkUsbGetConfigDescriptor,

    DinkUsbGetStringDescriptor,

    0,

    0x40 /*MAX PACKET SIZE*/

};

 

//USB standard data request structure

//Only two are implemented, the rest are solved with nop method

USER_STANDARD_REQUESTS User_Standard_Requests =

{

    DinkUsbGetConfiguration,

    DinkUsbSetConfiguration,

    DinkUsbGetInterface,

    DinkUsbSetInterface,

    DinkUsbGetStatus,

    DinkUsbClearFeature,

    DinkUsbSetEndPointFeature,

    DinkUsbSetDeviceFeature,

    DinkUsbSetDeviceAddress

};

 

 

 

//Device initialization

void DinkUsbInit(void)

{

    Get_SerialNum(); //Build string descriptor

    pInformation->Current_Configuration = 0; //The currently selected configuration is 0

    PowerOn(); //Connect USB

    _SetISTR(0);

    wInterrupt_Mask = IMR_MSK;

    _SetCNTR(wInterrupt_Mask);

    bDeviceState = UNCONNECTED; //Initialize the device status to unconnected

    usb_debug_printf("USB Init\r\n");

}

 

// Device reset

void DinkUsbReset(void)

{

    Device_Info.Current_Configuration = 0; //Select the current configuration as 0

    pInformation->Current_Feature = DinkUsbConfigDescriptor[7]; //Get the current device attribute in the configuration descriptor

    pInformation->Current_Interface = 0; //Set the current device interface

    SetBTABLE(BTABLE_ADDRESS); //Set the buffer address

   

    SetEPType(ENDP0, EP_CONTROL); //Control endpoint

    SetEPTxStatus(ENDP0, EP_TX_STALL);

    SetEPRxAddr(ENDP0, ENDP0_RXADDR); //Set endpoint buffer address

    SetEPTxAddr(ENDP0, ENDP0_TXADDR);

    Clear_Status_Out(ENDP0);

    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); //Set the maximum length of receiving

    SetEPRxValid(ENDP0);

   

    SetEPType(ENDP1, EP_INTERRUPT); //Initialize endpoint 1 to interrupt transfer mode to report some status

    SetEPTxAddr(ENDP1, ENDP1_TXADDR); //Set endpoint address

    SetEPRxAddr(ENDP1, ENDP1_RXADDR); //Set endpoint address

    SetEPRxStatus(ENDP1, EP_RX_VALID); //Enable reception

    SetEPTxStatus(ENDP1, EP_TX_NAK); //Disable transmission

    SetEPRxCount(ENDP1, 64); //Set the maximum length of receiving

    Clear_Status_Out(ENDP1);

 

    bDeviceState = ATTACHED; //Device inserted

   

    SetDeviceAddress(0); //Set the current address to 0

    usb_debug_printf("USB Reset\r\n");

}

 

//I don't know what it's for

void DinkUsbStatus_In(void)

{

    return;

}

//I don't know what it's for

void DinkUsbStatus_Out(void)

{

    return;

}

 

u8 *DinkUsbGetReportDescriptor(u16 Length)

{

    usb_debug_printf("Get report descriptor\r\n");

    return Standard_GetDescriptorData(Length, &DinkUsb_Report_Descriptor);

}

 

u8 *DinkUsbGetHIDDescriptor(u16 Length)

{

    usb_debug_printf("Get HID descriptor\r\n");

    return Standard_GetDescriptorData(Length, &DinkUsb_Hid_Descriptor);

}

 

u8 *DinkUsbGetProtocolValue(u16 Length)

{

    usb_debug_printf("Get protocol\r\n");

    if (Length == 0)

    {

        pInformation->Ctrl_Info.Usb_wLength = 1;

        return NULL;

    }

    else

    {

        return (u8 *)(&ProtocolValue);

    }

}

 

RESULT DinkUsbData_Setup(u8 RequestNo)

{

    u8 *(*CopyRoutine)(u16);

 

    CopyRoutine = NULL;

    if ((RequestNo == GET_DESCRIPTOR)

    && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))

    && (pInformation->USBwIndex0 == 0))

    {

        //Get the report descriptor

        if (pInformation->USBwValue1 == REPORT_DESCRIPTOR)

        {

            CopyRoutine = DinkUsbGetReportDescriptor;

        }

        //Get the HID descriptor

        else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)

        {

            CopyRoutine = DinkUsbGetHIDDescriptor;

        }

 

    }

 

    /*** GET_PROTOCOL ***/

    else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))

       && RequestNo == GET_PROTOCOL)

    {

        CopyRoutine = DinkUsbGetProtocolValue; //Get protocol value

    }

 

 

    if (CopyRoutine == NULL)

    {

        return USB_UNSUPPORT;

    }

 

    pInformation->Ctrl_Info.CopyData = CopyRoutine;

    pInformation->Ctrl_Info.Usb_wOffset = 0;

    (*CopyRoutine)(0);

    return USB_SUCCESS;

}

 

RESULT DinkUsbSetProtocol(void)

{

  u8 wValue0 = pInformation->USBwValue0;

  ProtocolValue = wValue0;

  return USB_SUCCESS;

}

 

RESULT DinkUsbNoDataSetup(u8 RequestNo)

{

    if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))

    && (RequestNo == SET_PROTOCOL))

    {

        usb_debug_printf("Set protocol\r\n");

        return DinkUsbSetProtocol();

    }

    else

    {

        return USB_UNSUPPORT;

    }

}

 

 

RESULT DinkUsbGetInterfaceSetting(u8 Interface, u8 AlternateSetting)

{

    if (AlternateSetting > 0) //Configuration quantity

    {

        usb_debug_printf("Set configuration\r\n");

        return USB_UNSUPPORT;

    }

    else if (Interface > 1) //Number of interfaces

    {

        usb_debug_printf("Set interface\r\n");

        return USB_UNSUPPORT;

    }

    return USB_SUCCESS;

}

 

//Get the device descriptor

u8 *DinkUsbGetDeviceDescriptor(u16 Length)

{

    usb_debug_printf("Get device descriptor\r\n");

    return Standard_GetDescriptorData(Length, &Device_Descriptor);

}

//Configuration descriptor

u8 *DinkUsbGetConfigDescriptor(u16 Length)

{

    usb_debug_printf("Get configuration descriptor\r\n");

    return Standard_GetDescriptorData(Length, &Config_Descriptor);

}

// string descriptor

u8 *DinkUsbGetStringDescriptor(u16 Length)

{

 

    u8 wValue0 = pInformation->USBwValue0;

    usb_debug_printf("Get string descriptor%d\r\n",wValue0);

    if (wValue0 > 4)

    {

        return NULL;

    }

    else

    {

        return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]); //Return string descriptor

    }

}

 

 

 

 

 

//Upload the device status to the configuration data

void DinkUsbSetConfiguration(void)

{

 

    DEVICE_INFO *pInfo = &Device_Info;

    usb_debug_printf("Set configuration\r\n");

    if (pInfo->Current_Configuration != 0)

    {

        bDeviceState = CONFIGURED;

    }

}

//Set the address to upload

void DinkUsbSetDeviceAddress (void)

{

    usb_debug_printf("Set address\r\n");

    bDeviceState = ADDRESSED;

}

 

 

The two most core functions are reset and initialization. When resetting, the endpoint should be configured, and it is best to enable reception, otherwise data cannot be received (you can enable it yourself later). Then there is the endpoint processing function usb_endp.c

#include "usb_endp.h"

 

//Set to 1 if sending is complete Set to 0 if sending is not complete

u8 sendOk = 1;

//When receiving data, this setting should be set to 1, and changed to 0 after data processing is completed

u8 ReceiveOk = 0;

 

void EP1_IN_Callback(void)

{

    //Callback function for the device to send data to the host

    sendOk = 1; //1 if the sending is successful

    SetEPTxStatus(ENDP1, EP_TX_NAK); //Send successfully and wait for the second time to be set as valid

}

 

void EP1_OUT_Callback(void)

{

    //After receiving data once, wait for data processing and set the receiving response to NAK

    //Set to VALID after processing is completed

    SetEPRxStatus(ENDP1, EP_RX_NAK); //NAK reception

    ReceiveOk = 1; //Data flag is 1

 

}

 

To enable these functions, you need to turn on the endpoint response function

In addition, the microcontroller should process or send data, which is done by the usb_data_process.h file.

#include "usb_data_process.h"

 

 

//HID sends data

//Return 1 if sending fails, return 0 if sending succeeds

u8 HID_Send_Data(u8* buffer,u8 length)

{

    if(sendOk == 1)

    {

        if(length == 0)

        {

            SetEPTxStatus(ENDP1, EP_TX_NAK); //Do not send

        }

        else

        {

            UserToPMABufferCopy(buffer, GetEPTxAddr(ENDP1), length);

            SetEPTxCount(ENDP1, length);

            SetEPTxValid(ENDP1); //Enable sending

            sendOk = 0; //Set the sending status to unfinished, waiting for the sending callback function to send data to the host

        }

        return 0;

    }

    else

    {

        return 1; //The last data has not been sent out, so this sending fails

    }

}

 

 

//HID receive data processing

u8 HID_Receive_Data(u8* buffer)

{

    u16 length = 0; //Get the length of the received data

    u8 i = 0;

    if(ReceiveOk == 1)//There is data

    {

        length = GetEPRxCount(ENDP1);

        if(length == 0)return 0;

        else

        {

            PMAToUserBufferCopy(buffer, GetEPRxAddr(ENDP1), length);

            SetEPRxValid(ENDP1); //Enable receiving

            ReceiveOk = 0;

           

            printf("hid receive : ");

            for(i = 0; i < length; i++)

            {

                printf("%c ",buffer[i]);

            }

            printf("\r\n");

           

            return length; //Return the received data

        }

    }

    else

    {

        //No data, directly 0

        return 0;

    }

}

 


Keywords:USB  STM32 Reference address:USB custom HID device implementation-STM32

Previous article:HCSR04 Ultrasonic Sensor Driver
Next article:STM32 general timer TIMx system understanding

Recommended ReadingLatest update time:2024-11-16 19:45

STM32 - Input capture of timer TIME module
The timer module of STM32 has very powerful functions. In addition to the ordinary timing function, it can also perform input capture and output comparison (PWM). PWM has been introduced in other articles. Now let's introduce input capture. Here are two questions I thought of during the test: Question 1: Can the s
[Microcontroller]
STM32 - Input capture of timer TIME module
One data cable goes everywhere, USB4 fully accelerates the innovation of next-generation chips
Have you bought a USB flash drive recently? Have you ever noticed whether you bought USB 2.0, 3.0, 3.2 or 4? Do you know what the USB we often talk about actually means? USB is actually the key technology to achieve data transmission between different devices. It is a protocol specification for data t
[Network Communication]
One data cable goes everywhere, USB4 fully accelerates the innovation of next-generation chips
The interface is finally unified! The European Union announced that all electronic devices will use USB-C from 2024
“The long wait is finally over.” Recently, the European Commission officially announced that from 2024, USB-C will become the common standard for electronic devices in the EU. "This means better charging technology, less e-waste and easier finding the charger you need!" said the European Commission. It is understood
[Mobile phone portable]
STM32 Series 15th - Flexible Static Storage Controller FSMC
FSMC Features FSMC manages 1GB space and has 4 banks to connect to external memory.  Each bank has an independent chip select signal and  each bank has an independent timing configuration. Synchronous bulk transfer access frequency up to 60MHz  fCLK = HCLK /2 Static address mapped memory Supported memory types  SRA
[Microcontroller]
STM32 Series 15th - Flexible Static Storage Controller FSMC
STMicroelectronics adds support for deep quantized neural networks to STM32Cube.AI development tool
STMicroelectronics (ST) has released STM32Cube.AI version 7.2.0, the microcontroller vendor’s first artificial intelligence (AI) development tool supporting ultra-efficient deep quantized neural networks.  STM32Cube.AI converts pre-trained neural networks into C language code that can be run by STM32 microcontro
[Internet of Things]
STMicroelectronics adds support for deep quantized neural networks to STM32Cube.AI development tool
STM32 Getting Started Tutorial System Clock SysTick
1. Background In traditional embedded system software, the Delay(N) function is usually implemented as follows: for(i = 0; i = x; i ++);                 x --- corresponds to the loop value corresponding to N milliseconds For the STM32 series microprocessors, it only takes tens of nanoseconds to execute an instru
[Microcontroller]
STM32 Cortex system timer (SysTick)
SysTick clock, commonly known as "tick timer", can generate an interrupt at a set time. Functions such as delay_ms() can be seen everywhere in control engineering code. But its internal mechanism has never been clear. I spent some time to study it today. First, let’s take a look at the configuration of the SysTick reg
[Microcontroller]
STM32 Cortex system timer (SysTick)
Application of FPGA and USB technology in textile digital printing machine system
Abstract: This paper introduces the design overview of the textile digital printing machine and the characteristics of the USB controller CY7C68013A. It also describes the design of FPGA access control operations on the USB controller, USB controller firmware program design, USB driver design, and PC applicati
[Embedded]
Application of FPGA and USB technology in textile digital printing machine system
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号