Пт янв 26, 2018 21:59:35
#ifndef STM32_USB_H
#define STM32_USB_H
#include "../cmsis/inc/stm32f103xb.h"
#include "usb_desc.h"
/* Defines */
#define REG(x) *(uint32_t *)(x)
#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
(((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
#define maxPacketSize 64 /* Maximum size packet */
#define BTABLE_ADDRESS 0 /* Address of the table of the buffer descriptor */
#define USB_ADDR0_TX *(uint32_t *)(USB_PMAADDR)
#define USB_COUNT0_TX *(uint32_t *)(USB_PMAADDR + 0x04) /* USB_PMAADDR + NUMEP * 16 + 4 */
#define USB_ADDR0_RX *(uint32_t *)(USB_PMAADDR + 0x08) /* USB_PMAADDR + NUMEP * 16 + 8 */
#define USB_COUNT0_RX *(uint32_t *)(USB_PMAADDR + 0x0C) /* USB_PMAADDR + NUMEP * 16 + 12 */
#define EPTxADDR(epNum) ((uint32_t *)(((uint16_t)epNum * 8) * 2 + USB_PMAADDR))
#define EPTxCOUNT(epNum) ((uint32_t *)(((uint16_t)epNum * 8 + 2) * 2 + USB_PMAADDR))
#define EPRxADDR(epNum) ((uint32_t *)(((uint16_t)epNum * 8 + 4) * 2 + USB_PMAADDR))
#define EPRxCOUNT(epNum) ((uint32_t *)(((uint16_t)epNum * 8 + 6) * 2 + USB_PMAADDR))
#define USB_COUNT_RX_512 0x3C00
#define USB_COUNT_RX_MASK 0x3ff
#define REG_ADRS_TX(x) *((uint32_t *)(USB_ADDR0_TX + x * 2))
#define REG_ADRS_RX(x) *((uint32_t *)(USB_ADDR0_RX + x * 2))
#define USB_EP0 0
#define USB_EP1 1
#define USB_EP2 2
#define EPxREG(x) REG(USB_BASE + 4 * x)
#define EPxCNT_TX(x) REG(USB_PMAADDR + x * 16 + 4)
#define EPxADR_TX(x) REG(USB_PMAADDR + x * 16)
#define EP_MASK (USB_EP_CTR_RX | USB_EP_SETUP | USB_EP_T_FIELD | USB_EP_KIND | USB_EP_CTR_TX | USB_EPADDR_FIELD)
#define WAITRX(x) while(!(EPxREG(x) & USB_EP_CTR_RX))
#define WAITTX(x) while(!(EPxREG(x) & USB_EP_CTR_TX))
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_DESC_TYPE_DEVICE 1
#define USB_DESC_TYPE_CONFIGURATION 2
#define USB_DESC_TYPE_STRING 3
#define USB_DESC_TYPE_INTERFACE 4
#define USB_DESC_TYPE_ENDPOINT 5
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
/* Structs */
/* USB Default Control Pipe Setup Packet */
typedef struct _USB_SETUP_PACKET {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USB_SETUP_PACKET;
/* Variables */
uint8_t *setup[12];
/* Functions */
void usb_config(void);
#endif /* STM32_USB_H */
#include "stm32_usb.h"
/* Private variables */
uint8_t descDevice[USB_DESC_SIZE] =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
0x00, /* bcdUSB */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USB_VID), /*idVendor*/
HIBYTE(USB_VID), /*idVendor*/
LOBYTE(USB_PID_FS), /*idVendor*/
HIBYTE(USB_PID_FS), /*idVendor*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USB_IDX_MFC_STR, /*Index of manufacturer string*/
USB_IDX_PRODUCT_STR, /*Index of product string*/
USB_IDX_SERIAL_STR, /*Index of serial number string*/
USB_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
static uint8_t devAddr = 0;
uint16_t value = 0;
USB_SETUP_PACKET SetupPacket;
/* Descriptor device */
/* Pprototypes function */
uint8_t *get_setup_packet();
void usb_reset(void);
void usb_read_buff(uint8_t *usrBuff, uint16_t buffAddr, uint16_t numByte);
void usb_read_pma(uint8_t *usrBuf, uint16_t pmaBuffAddr, uint16_t numBytes);
void usb_write_buff(uint8_t *usrBuff, uint16_t buffAddr, uint16_t numByte);
void usb_get_descriptor(void);
uint8_t *get_setup_packet(void);
void usb_set_address(void);
void usb_setup(void);
/* Private function */
// uint8_t get_byte(uint8_t *usrBuff, uint8_t numByte){
// uint32_t temp = (uint16_t) * usrBuff;
// usrBuff += numByte + 1;
// return temp | (uint16_t) * usrBuff << 8;;
// }
void usb_reset(void){
USB->ISTR = 0x0;
USB->BTABLE = BTABLE_ADDRESS; /* Set a address table buffer in memory USB */
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_CTRM;
/* Set a address buffer */
USB_ADDR0_RX = USB_MAX_EP0_SIZE;
USB_ADDR0_TX = USB_MAX_EP0_SIZE;
USB_COUNT0_TX = (uint32_t)0x40;
USB_COUNT0_RX = USB_COUNT0_RX_BLSIZE | USB_COUNT_RX_512;
/* Endpoints 0; Type: CONTROL; RX: VALID; TX: NAK */
EPxREG(0) = USB_EP_CONTROL | USB_EP_RX_VALID | USB_EP_TX_NAK;
USB->DADDR = USB_DADDR_EF; /* Activation device */
}
void usb_zero_length_packet(void){
USB_COUNT0_TX = 0x00;
EPxREG(0) |= USB_EP_CONTROL | USB_EP_TX_VALID;
while(!(USB->EP0R & USB_EP_CTR_TX)){}
}
/*
* @brief USBD_ParseSetupRequest
* Copy buffer into setup structure
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void usb_setup_request(USB_SETUP_PACKET *req, uint8_t *pdata){
// req->bmRequestType = pdata[0];
// req->bRequest = pdata[1];
// req->wValue = pdata[3];
// req->wIndex = pdata[4];
// req->wLength = pdata[6];
// req->bmRequestType = *pdata;
// req->bRequest = *(pdata + 1);
// req->wValue = *(pdata + 2);
// req->wIndex = *(pdata + 4);
// req->wLength = *(pdata + 6);
// req->bmRequestType = *(uint8_t *) (pdata);
// req->bRequest = *(uint8_t *) (pdata + 1);
// value = SWAPBYTE (pdata + 2);
// req->wIndex = SWAPBYTE (pdata + 4);
// req->wLength = SWAPBYTE (pdata + 6);
uint32_t temp1 = 0, temp2 = 0;
temp1 = (uint16_t) * pdata;
pdata++;
temp2 = temp1 | (uint16_t) * pdata << 8;
req->bmRequestType = temp2;
temp1 = (uint16_t) * pdata;
pdata++;
temp2 = temp1 | (uint16_t) * pdata << 8;
req->bRequest = temp2;
temp1 = (uint16_t) * pdata;
pdata++;
temp2 = temp1 | (uint16_t) * pdata << 8;
value = temp2;
temp1 = (uint16_t) * pdata;
pdata++;
temp2 = temp1 | (uint16_t) * pdata << 8;
req->wIndex = temp2;
temp1 = (uint16_t) * pdata;
pdata++;
temp2 = temp1 | (uint16_t) * pdata << 8;
req->wLength = temp2;
}
/*
* @brief Copy a buffer from user memory area to packet memory area (PMA)
* @param usrBuff : pointer to user memory area.
* @param buffAddr : address into PMA.
* @param numByte : number of bytes to be copied.
* @retval None
*/
// void usb_read_buff(uint8_t *usrBuff, uint16_t buffAddr, uint16_t numByte){
// uint32_t nbytes = (numByte + 1) >> 1;/* /2*/
// uint32_t index = 0;
// uint32_t *pdwVal = 0;
// pdwVal = (uint32_t *)(buffAddr * 2 + (uint32_t)(USB_PMAADDR));
// for(index = nbytes; index != 0; index--){
// *(uint16_t*)usrBuff++ = *pdwVal++;
// usrBuff++;
// }
// }
// uint8_t *get_setup_packet(){
// uint32_t *startAddr = ((uint32_t *)(USB_ADDR0_RX * 2 + USB_PMAADDR));
// for(uint8_t i = 0; i < 8; i++){
// setup[i] = *startAddr++;
// }
// return 0;
// }
void usb_read_pma(uint8_t *usrBuf, uint16_t pmaBuffAddr, uint16_t numBytes) {
uint32_t n = (numBytes + 1) >> 1;
uint32_t i;
uint32_t *pdwVal;
pdwVal = (uint32_t *)(pmaBuffAddr * 2 + USB_PMAADDR);
for (i = n; i != 0; i--) {
*(uint16_t*)usrBuf++ = *pdwVal++;
usrBuf++;
}
}
void usb_write_buff(uint8_t *usrBuff, uint16_t buffAddr, uint16_t numByte){
uint32_t nbytes = (numByte + 1) >> 1; /* nbytes = (numByte + 1) / 2 */
uint32_t index = 0, temp1 = 0, temp2 = 0;
uint16_t *pdwVal = 0;
pdwVal = (uint16_t *)(buffAddr * 2 + (uint32_t)USB_PMAADDR);
for (index = nbytes; index != 0; index--){
temp1 = (uint16_t) * usrBuff;
usrBuff++;
temp2 = temp1 | (uint16_t) * usrBuff << 8;
*pdwVal++ = temp2;
pdwVal++;
usrBuff++;
}
}
void usb_get_descriptor(void){
USB->ISTR &= ~USB_ISTR_CTR;
EPxREG(0) &= ~USB_EP_CTR_RX;
EPxREG(0) |= USB_EP_DTOG_TX;
usb_write_buff(descDevice, USB_ADDR0_TX, sizeof(descDevice));
USB_COUNT0_TX = sizeof(descDevice);
EPxREG(0) = USB_EP_CONTROL | USB_EP_TX_VALID;
while(!(USB->EP0R & USB_EP_CTR_TX)){}
}
void usb_set_address(void){
EPxREG(0) &= ~USB_EP_CTR_RX;
EPxREG(0) |= USB_EP_DTOG_TX;
// USB_ADDR0_TX = 0x2;
// usb_write_buff(devAddr, EPTxADDR(0), 1);
// USB_COUNT0_TX = 0x1;
// EPxREG(0) |= USB_EP_CONTROL | USB_EP_TX_VALID;
// while(!(USB->EP0R & USB_EP_CTR_TX)){}
usb_zero_length_packet();
// USB->DADDR |= devAddr;
}
void usb_setup(void){
switch(SetupPacket.bRequest){
case USB_REQ_GET_DESCRIPTOR:
usb_get_descriptor();
break;
case USB_REQ_SET_ADDRESS:
devAddr = value;
usb_set_address();
break;
}
}
/* Public functoin */
/*
* Name: usb_config
* Description: USB Configuration
* Parametrs: none
*/
void usb_config(void){
RCC->APB1ENR |= RCC_APB1ENR_USBEN; /* USB clock enable */
USB->CNTR = USB_CNTR_FRES;/* CNTR_FRES = 1 */
USB->CNTR = 0; /* CNTR_FRES = 0 */
USB->CNTR |= USB_CNTR_PDWN;
/* Reset driver */
USB->CNTR = 0x0;
/* Reset registr flag interrput */
USB->ISTR = 0x0;
/* Allow interrput */
//USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM;
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_CTRM;
/* Clean up buffer */
// for(uint16_t *i = USB_PMAADDR; i <= USB_PMAADDR + 0x3FF; i+=2) *i = 0;
/* Activation interrput */
NVIC_EnableIRQ(USBWakeUp_IRQn);
// NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
}
/* Interrput */
void USB_LP_IRQHandler(void){
uint32_t num;
if(USB->ISTR & USB_ISTR_RESET){
usb_reset(); /* Reset USB device */
return;
}
if(USB->ISTR & USB_ISTR_SUSP){
USB->CNTR |= USB_CNTR_FSUSP; /* Force Suspend */
USB->CNTR |= USB_CNTR_LP_MODE; /* Low Power Mode */
}
if(USB->ISTR & USB_ISTR_WKUP){
USB->CNTR &= ~USB_CNTR_FSUSP;
}
while((USB->ISTR & USB_ISTR_CTR) != 0){
num = USB->ISTR & USB_ISTR_EP_ID;
if(num == 0){ /* Endpoint 0 */
if((USB->ISTR & USB_ISTR_DIR) != 0){
EPxREG(0) &= ~USB_EP_CTR_RX;
EPxREG(0) |= USB_EP_CONTROL;
if(EPxREG(0) & USB_EP_SETUP){ /* SETUP */
// get_setup_packet();
usb_read_pma((uint8_t *)setup, (uint16_t)*EPRxADDR(0), 8);
// uint8_t *setup = (uint32_t *)(USB_ADDR0_RX * 2 + USB_PMAADDR);
// SetupPacket.bmRequestType = *(uint8_t*)(setup++);
// SetupPacket.bRequest = *(setup++);
// setup += 2;
// SetupPacket.wValue = *(uint16_t*)setup;
// setup += 8;
// SetupPacket.wLength = *(uint16_t*)setup;
// setup += 4;
usb_setup_request(&SetupPacket, setup);
usb_setup();
EPxREG(0) |= USB_EP_CONTROL | USB_EP_RX_VALID;
}else{ /* OUT */
}
}else{ /* IN */
EPxREG(0) &= ~USB_EP_CTR_TX;
if(devAddr > 0 && SetupPacket.wLength == 0){
// USB_ADDR0_TX = devAddr;
// USB_COUNT0_TX = 0x1;
USB->DADDR = USB_DADDR_EF | devAddr;
}
// EPxREG(0) |= USB_EP_CONTROL | USB_EP_RX_VALID;
}
}else{ /* num > 0 */
}
}
USB->ISTR = 0x0;
}
Сб янв 27, 2018 11:39:18
Вс мар 04, 2018 17:39:44
Пн мар 05, 2018 16:54:45