Remove USB, remap a lot of pins
This commit is contained in:
parent
22b6ee1136
commit
04bbaf8e14
|
@ -1 +1 @@
|
|||
191
|
||||
205
|
||||
|
|
|
@ -25,15 +25,18 @@ static void InitStepper(void)
|
|||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
|
||||
GPIOA->CRL = (GPIOA->CRL
|
||||
& ~(0x0f << (4 * PIN_STEPPER_AM))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_AP))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_BM))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_BP)))
|
||||
| (0x01 << (4 * PIN_STEPPER_AM)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_AP)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_BM)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_BP)) // Output, max. 10 MHz
|
||||
// PA15 is used for stepper control, so JTAG has to be disabled
|
||||
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;
|
||||
|
||||
GPIOA->CRH = (GPIOA->CRH
|
||||
& ~(0x0f << (4 * PIN_STEPPER_AM - 32))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_AP - 32))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_BM - 32))
|
||||
& ~(0x0f << (4 * PIN_STEPPER_BP - 32)))
|
||||
| (0x01 << (4 * PIN_STEPPER_AM - 32)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_AP - 32)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_BM - 32)) // Output, max. 10 MHz
|
||||
| (0x01 << (4 * PIN_STEPPER_BP - 32)) // Output, max. 10 MHz
|
||||
;
|
||||
|
||||
TIM3->PSC = 72000000 / 100 / LTP1245_MAX_DRIVE_FREQ - 1;
|
||||
|
@ -46,9 +49,9 @@ static void InitStepper(void)
|
|||
|
||||
static void InitSensors(void)
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
|
||||
GPIOA->CRL = (GPIOA->CRL
|
||||
GPIOB->CRL = (GPIOB->CRL
|
||||
& ~(0x0f << (4 * PIN_HEAD))
|
||||
& ~(0x0f << (4 * PIN_PAPER)))
|
||||
| (0x08 << (4 * PIN_HEAD)) // Input with pull-up/pull-down
|
||||
|
@ -56,7 +59,7 @@ static void InitSensors(void)
|
|||
;
|
||||
|
||||
// Use pull-ups
|
||||
GPIOA->BSRR = (1 << PIN_HEAD) | (1 << PIN_PAPER);
|
||||
GPIOB->BSRR = (1 << PIN_HEAD) | (1 << PIN_PAPER);
|
||||
}
|
||||
|
||||
static void InitDataLines(void)
|
||||
|
@ -138,12 +141,12 @@ static void InitThermistor(void)
|
|||
|
||||
static bool HasPaper(void)
|
||||
{
|
||||
return !(GPIOA->IDR & (1 << PIN_PAPER));
|
||||
return !(GPIOB->IDR & (1 << PIN_PAPER));
|
||||
}
|
||||
|
||||
static bool HeadDown(void)
|
||||
{
|
||||
return !(GPIOA->IDR & (1 << PIN_HEAD));
|
||||
return !(GPIOB->IDR & (1 << PIN_HEAD));
|
||||
}
|
||||
|
||||
void ActivateHead(int mask)
|
||||
|
@ -152,7 +155,7 @@ void ActivateHead(int mask)
|
|||
while(TIM2->CR1 & TIM_CR1_CEN);
|
||||
|
||||
// Set activation pulse width
|
||||
TIM2->ARR = (PulseWidth / 5) + 1;
|
||||
TIM2->ARR = (PulseWidth / 10) + 1;
|
||||
|
||||
TIM2->CCER = 0;
|
||||
if(mask & 1)
|
||||
|
|
18
src/main.c
18
src/main.c
|
@ -2,25 +2,23 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
USB_Init();
|
||||
LTP1245_Init();
|
||||
|
||||
// LTP1245_FeedPaper(10);
|
||||
|
||||
uint8_t buff[LTP1245_LINEWIDTH / 8 * 16];
|
||||
for(int i = 0; i < sizeof(buff); i++)
|
||||
{
|
||||
int shift = (i * 8 / (64 * 6)) % 8;
|
||||
buff[i] = (0x11 << shift) | (0x11 >> (8 - shift));
|
||||
}
|
||||
char buff[30];
|
||||
itoa(BUILD_NUMBER, buff, 10);
|
||||
Print_Text(buff, &Messe_Duesseldorf_39);
|
||||
|
||||
// LTP1245_Print(buff, 16);
|
||||
// LTP1245_Print(buff, 5);
|
||||
// LTP1245_FeedPaper(10);
|
||||
// Print_Text("Testy McTestFace", &Arpegius_32);
|
||||
// Print_Text("123555bcD", &Messe_Duesseldorf_39);
|
||||
Print_Text("Abcdef Ghi Jkl", &Hannover_Messe_Serif_26);
|
||||
LTP1245_FeedPaper(16);
|
||||
Print_Text("Abcdef Ghi Jkl", &Hannover_Messe_Serif_26);
|
||||
Print_Text("Abcdef Ghi Jkl", &Hannover_Messe_Serif_26);
|
||||
Print_Text("Abcdef Ghi Jkl", &Hannover_Messe_Serif_26);
|
||||
Print_Text("Abcdef Ghi Jkl", &Hannover_Messe_Serif_26);
|
||||
LTP1245_FeedPaper(100);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#define MAIN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
#include "pinning.h"
|
||||
#include "buildid.h"
|
||||
#include "debug.h"
|
||||
#include "usb.h"
|
||||
#include "ltp1245.h"
|
||||
#include "print.h"
|
||||
#include "font_hannover_messe_serif_26.h"
|
||||
|
|
|
@ -1,20 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
// Port A
|
||||
#define PIN_STEPPER_AP 0 // PA0 - Stepper phase A positive
|
||||
#define PIN_STEPPER_BP 1 // PA1 - Stepper phase B positive
|
||||
#define PIN_HEAD 2 // PA2 - Head up sensor
|
||||
#define PIN_PAPER 3 // PA3 - Paper detect
|
||||
#define PIN_STEPPER_AM 4 // PA4 - Stepper phase A negative
|
||||
#define PIN_STEPPER_BM 5 // PA5 - Stepper phase B negative
|
||||
|
||||
#define PIN_USB_DM 11 // PA11 - USB D-
|
||||
#define PIN_USB_DP 12 // PA12 - USB D+
|
||||
#define PIN_CAMERA_DB0 0 // PA0 - Camera data line 0
|
||||
#define PIN_CAMERA_DB1 1 // PA1 - Camera data line 1
|
||||
#define PIN_CAMERA_DB2 2 // PA2 - Camera data line 2
|
||||
#define PIN_CAMERA_DB3 3 // PA3 - Camera data line 3
|
||||
#define PIN_CAMERA_DB4 4 // PA4 - Camera data line 4
|
||||
#define PIN_CAMERA_DB5 5 // PA5 - Camera data line 5
|
||||
#define PIN_CAMERA_DB6 6 // PA6 - Camera data line 6
|
||||
#define PIN_CAMERA_DB7 7 // PA7 - Camera data line 7
|
||||
#define PIN_CAMERA_MCLK 8 // PA8 - Camera main clock (MCO/TIM1_CH1)
|
||||
#define PIN_CAMERA_PCLK 9 // PA9 - Camera pixel clock (TIM1_CH2)
|
||||
#define PIN_STEPPER_AP 10 // PA10 - Stepper phase A positive
|
||||
#define PIN_STEPPER_BP 11 // PA11 - Stepper phase B positive
|
||||
#define PIN_STEPPER_AM 12 // PA12 - Stepper phase A negative
|
||||
#define PIN_STEPPER_BM 15 // PA15 - Stepper phase B negative
|
||||
|
||||
// Port B
|
||||
#define PIN_THERMISTOR 0 // PB0 - Thermistor
|
||||
#define PIN_THERMISTOR 0 // PB0 - Thermistor (ADC12_IN8)
|
||||
#define PIN_VBATT 1 // PB1 - Battery monitor (ADC12_IN9)
|
||||
#define PIN_SUPPLY 2 // PB2 - Voltage regulator enable
|
||||
#define PIN_PAPER 3 // PB3 - Paper detect
|
||||
#define PIN_CAMERA_VSYNC 4 // PB4 - Camera VSYNC (TIM3_CH1)
|
||||
#define PIN_CAMERA_HSYNC 5 // PB5 - Camera VSYNC (TIM3_CH2)
|
||||
#define PIN_HEAD 6 // PB6 - Head up sensor
|
||||
#define PIN_PAPER_CUT 7 // PB7 - Paper cutter servo (TIM4_CH2)
|
||||
#define PIN_CAMERA_SCL 8 // PB8 - Camera control I2C (I2C1_SCL)
|
||||
#define PIN_CAMERA_SDA 9 // PB9 - Camera control I2C (I2C1_SDA)
|
||||
#define PIN_DST1 10 // PB10 - Head drive signal 1 (TIM2_CH3)
|
||||
#define PIN_DST2 11 // PB11 - Head drive signal 2 (TIM2_CH4)
|
||||
#define PIN_CAMERA_RESET 12 // PB12 - Camera reset (active low)
|
||||
#define PIN_SCK 13 // PB13 - Thermal printer SCK (SPI2)
|
||||
#define PIN_LATCH 14 // PB14 - Thermal printer data latch
|
||||
#define PIN_DIN 15 // PB15 - Thermal printer MOSI (SPI2)
|
||||
|
|
376
src/usb.c
376
src/usb.c
|
@ -1,376 +0,0 @@
|
|||
#include "usb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_com.h"
|
||||
|
||||
uint8_t USB_DeviceStatus[2] = {0x00, 0x01};
|
||||
volatile unsigned int USB_ResetCount = 0;
|
||||
volatile unsigned int USB_Address = 0;
|
||||
|
||||
static inline void USB_SetEPR(volatile uint16_t *EPR, uint16_t status)
|
||||
{
|
||||
// Caution: This function does a read-modify-write and is prone to
|
||||
// unexpected behaviour when there are transactions going one, because the
|
||||
// register contents might change during the funciton's execution. Thus, only
|
||||
// use this function in initialisation code!
|
||||
volatile uint16_t v = *EPR;
|
||||
status ^= v & (USB_EP0R_DTOG_RX | USB_EP0R_STAT_RX |\
|
||||
USB_EP0R_DTOG_TX | USB_EP0R_STAT_TX);
|
||||
*EPR = status;
|
||||
}
|
||||
|
||||
static inline void USB_SetEPRXStatus(volatile uint16_t *EPR, uint16_t status)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v ^= status & USB_EP0R_STAT_RX;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA | USB_EP0R_STAT_RX;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_SetEPTXStatus(volatile uint16_t *EPR, uint16_t status)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v ^= status & USB_EP0R_STAT_TX;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA | USB_EP0R_STAT_TX;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_SetEPType(volatile uint16_t *EPR, uint16_t type)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA;
|
||||
v |= USB_EP0R_EP_TYPE & type;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_SetEPAddress(volatile uint16_t *EPR, uint16_t address)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX;
|
||||
v |= USB_EP0R_EA & address;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_SetEPKind(volatile uint16_t *EPR)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_CTR_TX | USB_EP0R_EA;
|
||||
v |= USB_EP0R_EP_KIND;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_ClearEPKind(volatile uint16_t *EPR)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_CTR_TX | USB_EP0R_EA;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_ClearEPCTRX(volatile uint16_t *EPR)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_ClearEPCTTX(volatile uint16_t *EPR)
|
||||
{
|
||||
uint16_t v = *EPR;
|
||||
v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA;
|
||||
*EPR = v;
|
||||
}
|
||||
|
||||
static inline void USB_Delay(unsigned int delay)
|
||||
{
|
||||
SysTick->LOAD = delay;
|
||||
SysTick->VAL = 0;
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||
while(!((SysTick->CTRL) & SysTick_CTRL_COUNTFLAG_Msk));
|
||||
SysTick->CTRL = 0;
|
||||
}
|
||||
|
||||
void USB_Init(void)
|
||||
{
|
||||
// GPIOA clock
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||
|
||||
// for(int i = 0; i < 8; i++)
|
||||
// {
|
||||
// USB_BTABLE_ENTRIES[i].ADDR_RX = 0;
|
||||
// USB_BTABLE_ENTRIES[i].ADDR_TX = 0;
|
||||
// USB_BTABLE_ENTRIES[i].COUNT_RX = 0;
|
||||
// USB_BTABLE_ENTRIES[i].COUNT_TX = 0;
|
||||
// }
|
||||
|
||||
GPIOA->CRH &= ~(GPIO_CRH_CNF11 | GPIO_CRH_MODE11 |\
|
||||
GPIO_CRH_CNF12 | GPIO_CRH_MODE12);
|
||||
GPIOA->CRH |= GPIO_CRH_MODE11 | GPIO_CRH_MODE12;
|
||||
GPIOA->ODR &= ~(GPIO_CRH_MODE11 | GPIO_CRH_MODE12);
|
||||
USB_Delay(100000);
|
||||
|
||||
// Enable reset and correct transfer interrupts
|
||||
NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
|
||||
// Analog power up
|
||||
USB->CNTR = (uint16_t)USB_CNTR_FRES;
|
||||
// Minimum delay: 1 µs
|
||||
USB_Delay(3000);
|
||||
|
||||
USB->CNTR = (uint16_t)0;
|
||||
USB->ISTR = (uint16_t)0;
|
||||
USB->CNTR = (uint16_t)(USB_CNTR_RESETM | USB_CNTR_CTRM);
|
||||
|
||||
// Configure USB pins (PA11 and PA12 in AF mode, 50 MHz push-pull)
|
||||
GPIOA->CRH |= GPIO_CRH_CNF11_1 | GPIO_CRH_MODE11 |\
|
||||
GPIO_CRH_CNF12_1 | GPIO_CRH_MODE12;
|
||||
}
|
||||
|
||||
static inline void USB_HandleReset(void)
|
||||
{
|
||||
// Remove reset flag
|
||||
USB->ISTR = (uint16_t)~(USB_ISTR_RESET);
|
||||
USB_ResetCount++;
|
||||
|
||||
// Set buffer table origin
|
||||
USB->BTABLE = USB_BTABLE_OFFSET;
|
||||
|
||||
// Set buffer table contents for control endpoint 0
|
||||
USB_BTABLE_ENTRIES[0].COUNT_RX = USB_EP_RXCOUNT_BL_SIZE | (1 << 10);
|
||||
// USB_BTABLE_ENTRIES[0].COUNT_RX = (4 << 10);
|
||||
USB_BTABLE_ENTRIES[0].ADDR_RX = 0x40;
|
||||
USB_BTABLE_ENTRIES[0].COUNT_TX = 0;
|
||||
USB_BTABLE_ENTRIES[0].ADDR_TX = 0x80;
|
||||
|
||||
// Set buffer table contents for control endpoint 1
|
||||
USB_BTABLE_ENTRIES[1].COUNT_RX_0 = USB_EP_RXCOUNT_BL_SIZE | (1 << 10);
|
||||
USB_BTABLE_ENTRIES[1].ADDR_RX_0 = 0x100;
|
||||
USB_BTABLE_ENTRIES[1].COUNT_RX_1 = USB_EP_RXCOUNT_BL_SIZE | (1 << 10);
|
||||
USB_BTABLE_ENTRIES[1].ADDR_RX_1 = 0x140;
|
||||
|
||||
// Configure endpoint 0
|
||||
USB_SetEPR(&(USB->EP0R), USB_EPR_EP_TYPE_CONTROL |\
|
||||
USB_EPR_STAT_TX_NAK | USB_EPR_STAT_RX_VALID);
|
||||
|
||||
|
||||
// Configure endpoint 1
|
||||
USB_SetEPR(&(USB->EP1R), USB_EPR_EP_TYPE_ISO |\
|
||||
USB_EPR_STAT_TX_DISABLED | USB_EPR_STAT_RX_VALID |\
|
||||
(1 << USB_EP0R_EA_Pos));
|
||||
|
||||
// Enable
|
||||
USB->DADDR = USB_DADDR_EF;
|
||||
}
|
||||
|
||||
static inline void USB_PMAToMemory(uint8_t *mem, uint16_t offset, size_t length)
|
||||
{
|
||||
uint8_t *pma = (uint8_t*)(USB_PMA_ADDR + 2 * offset);
|
||||
for(unsigned int i = 0; i < length / 2; i++)
|
||||
{
|
||||
mem[2 * i] = *pma++;
|
||||
mem[2 * i + 1] = *pma++;
|
||||
pma += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void USB_MemoryToPMA(uint16_t offset, const uint8_t *mem, size_t length)
|
||||
{
|
||||
uint16_t *pma = (uint16_t*)(USB_PMA_ADDR + 2 * offset);
|
||||
for(unsigned int i = 0; i < length / 2; i++)
|
||||
{
|
||||
uint16_t tmp = mem[2 * i] | (mem[2 * i + 1] << 8);
|
||||
*pma++ = tmp;
|
||||
pma++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void USB_HandleIn(void)
|
||||
{
|
||||
if((USB->DADDR & USB_DADDR_ADD) != USB_Address)
|
||||
{
|
||||
USB->DADDR = USB_Address | USB_DADDR_EF;
|
||||
}
|
||||
// Ready for next packet
|
||||
USB_SetEPRXStatus(&USB->EP0R, USB_EP_RX_VALID);
|
||||
}
|
||||
|
||||
static inline void USB_HandleOut(void)
|
||||
{
|
||||
// Ready for next packet
|
||||
USB_SetEPRXStatus(&USB->EP0R, USB_EP_RX_VALID);
|
||||
}
|
||||
|
||||
static inline void USB_HandleSetup(void)
|
||||
{
|
||||
USB_SetupPacket_t sp;
|
||||
//memcpy(&sp, (const void*)(USB_PMA_ADDR + USB_BTABLE_ENTRIES[0].ADDR_RX), sizeof(USB_SetupPacket_t));
|
||||
USB_PMAToMemory((uint8_t*)&sp, USB_BTABLE_ENTRIES[0].ADDR_RX, sizeof(USB_SetupPacket_t));
|
||||
|
||||
const uint8_t *reply_data = NULL;
|
||||
int reply_length = 0;
|
||||
uint8_t reply_response = USB_TOKEN_ACK;
|
||||
|
||||
if((sp.bmRequestType & (USB_REQUEST_TYPE | USB_REQUEST_RECIPIENT)) \
|
||||
== (USB_REQUEST_TYPE_STANDARD | USB_REQUEST_RECIPIENT_DEVICE))
|
||||
{
|
||||
switch(sp.bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:;
|
||||
if(sp.wValue == 0 && sp.wIndex == 0 && sp.wLength == 2)
|
||||
{
|
||||
reply_length = 2;
|
||||
reply_data = USB_DeviceStatus;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQUEST_GET_DESCRIPTOR:;
|
||||
USB_DescriptorType_t descriptor_type = sp.wValue >> 8;
|
||||
int descriptor_index = sp.wValue & 0xff;
|
||||
switch(descriptor_type)
|
||||
{
|
||||
case USB_DEVICE_DESCRIPTOR:;
|
||||
reply_data = USB_DeviceDescriptor.raw;
|
||||
reply_length = USB_DeviceDescriptor.bLength;
|
||||
break;
|
||||
|
||||
case USB_CONFIGURATION_DESCRIPTOR:;
|
||||
reply_data = USB_ConfigurationInterfaceDescriptor.raw;
|
||||
if(sp.wLength < USB_ConfigurationInterfaceDescriptor.configuration.wTotalLength)
|
||||
{
|
||||
reply_length = USB_ConfigurationInterfaceDescriptor.configuration.bLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_length = USB_ConfigurationInterfaceDescriptor.configuration.wTotalLength;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_STRING_DESCRIPTOR:;
|
||||
switch(descriptor_index)
|
||||
{
|
||||
case 0:;
|
||||
reply_data = (uint8_t*)USB_StringDescriptor_LangID;
|
||||
reply_length = (uint8_t)*USB_StringDescriptor_LangID;
|
||||
break;
|
||||
case 1:;
|
||||
reply_data = (uint8_t*)USB_StringDescriptor_Vendor;
|
||||
reply_length = (uint8_t)*USB_StringDescriptor_Vendor;
|
||||
break;
|
||||
case 2:;
|
||||
reply_data = (uint8_t*)USB_StringDescriptor_Product;
|
||||
reply_length = (uint8_t)*USB_StringDescriptor_Product;
|
||||
break;
|
||||
case 3:;
|
||||
reply_data = (uint8_t*)USB_StringDescriptor_Serial;
|
||||
reply_length = (uint8_t)*USB_StringDescriptor_Serial;
|
||||
break;
|
||||
default:;
|
||||
__asm__ volatile("bkpt");
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_INTERFACE_DESCRIPTOR:;
|
||||
reply_data = USB_ConfigurationInterfaceDescriptor.interface0.raw;
|
||||
reply_length = USB_ConfigurationInterfaceDescriptor.interface0.bLength;
|
||||
break;
|
||||
|
||||
case USB_ENDPOINT_DESCRIPTOR:;
|
||||
// Does not exist yet
|
||||
__asm__ volatile("bkpt");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_ADDRESS:
|
||||
USB_Address = sp.wValue & USB_DADDR_ADD;
|
||||
reply_response = USB_EP_TX_VALID;
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_CONFIGURATION:
|
||||
reply_response = USB_EP_TX_VALID;
|
||||
break;
|
||||
|
||||
default:;
|
||||
reply_response = USB_EP_TX_STALL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_length = USBCOM_HandleSetupPacket(&sp, &reply_data);
|
||||
}
|
||||
|
||||
if(reply_data)
|
||||
{
|
||||
// Reply with data
|
||||
//memcpy((void*)(USB_PMA_ADDR + USB_BTABLE_ENTRIES[0].ADDR_TX), reply_data, reply_length);
|
||||
USB_MemoryToPMA(USB_BTABLE_ENTRIES[0].ADDR_TX, reply_data, reply_length);
|
||||
USB_BTABLE_ENTRIES[0].COUNT_TX = reply_length;
|
||||
USB_SetEPTXStatus(&(USB->EP0R), USB_EP_TX_VALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send response
|
||||
USB_BTABLE_ENTRIES[0].COUNT_TX = 0;
|
||||
USB_SetEPTXStatus(&(USB->EP0R), reply_response);
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt service routine
|
||||
void USB_LP_IRQHandler(void)
|
||||
{
|
||||
if(USB->ISTR & USB_ISTR_RESET)
|
||||
{
|
||||
// Reset happened
|
||||
USB_HandleReset();
|
||||
return;
|
||||
}
|
||||
uint16_t istr;
|
||||
while((istr = USB->ISTR) & (USB_ISTR_CTR))
|
||||
{
|
||||
if(istr & USB_ISTR_CTR)
|
||||
{
|
||||
// USB->ISTR = (uint16_t)~USB_ISTR_CTR;
|
||||
// Correct transfer
|
||||
int ep = istr & USB_ISTR_EP_ID;
|
||||
if(ep == 0)
|
||||
{
|
||||
if(istr & USB_ISTR_DIR)
|
||||
{
|
||||
// OUT transfer
|
||||
if(USB->EP0R & USB_EP0R_SETUP)
|
||||
{
|
||||
// Clear CTR_RX
|
||||
USB->EP0R = USB->EP0R & (USB_EP0R_SETUP | USB_EP0R_EP_TYPE |\
|
||||
USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA);
|
||||
|
||||
// Setup packed received
|
||||
USB_HandleSetup();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear CTR_RX
|
||||
USB->EP0R = USB->EP0R & (USB_EP0R_SETUP | USB_EP0R_EP_TYPE |\
|
||||
USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA);
|
||||
|
||||
USB_HandleOut();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear CTR_TX
|
||||
USB->EP0R = USB->EP0R & (USB_EP0R_CTR_RX | USB_EP0R_SETUP |\
|
||||
USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA);
|
||||
|
||||
// IN transfer
|
||||
USB_HandleIn();
|
||||
}
|
||||
}
|
||||
else if(ep == 1)
|
||||
{
|
||||
USBCOM_HandleISO0OUT();
|
||||
// Ready for next packet
|
||||
// USB_SetEPRXStatus(&USB->EP1R, USB_EP_RX_VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
113
src/usb.h
113
src/usb.h
|
@ -1,113 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
#include "pinning.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define USB_TOKEN_OUT 0b0001
|
||||
#define USB_TOKEN_IN 0x1001
|
||||
#define USB_TOKEN_SOF 0b0101
|
||||
#define USB_TOKEN_SETUP 0b1101
|
||||
#define USB_TOKEN_DATA0 0b0011
|
||||
#define USB_TOKEN_DATA1 0b1011
|
||||
#define USB_TOKEN_DATA2 0b0111
|
||||
#define USB_TOKEN_ACK 0b0010
|
||||
#define USB_TOKEN_NAK 0b1010
|
||||
#define USB_TOKEN_STALL 0b1110
|
||||
#define USB_TOKEN_NYET 0b0110
|
||||
#define USB_TOKEN_PRE 0b1100
|
||||
#define USB_TOKEN_ERR 0b1100
|
||||
#define USB_TOKEN_SPLIT 0b1000
|
||||
#define USB_TOKEN_PING 0b0100
|
||||
|
||||
#define USB_REQUEST_DIRECTION (1 << 7)
|
||||
#define USB_REQUEST_DIRECTION_OUT 0
|
||||
#define USB_REQUEST_DIRECTION_IN (1 << 7)
|
||||
#define USB_REQUEST_TYPE (0x3 << 5)
|
||||
#define USB_REQUEST_TYPE_STANDARD 0
|
||||
#define USB_REQUEST_TYPE_CLASS (1 << 5)
|
||||
#define UBS_REQUEST_TYPE_VENDOR (2 << 5)
|
||||
#define UBS_REQUEST_TYPE_RESERVED (3 << 5)
|
||||
#define USB_REQUEST_RECIPIENT 0x1f
|
||||
#define USB_REQUEST_RECIPIENT_DEVICE 0
|
||||
#define USB_REQUEST_RECIPIENT_INTERFACE 1
|
||||
#define USB_REQUEST_RECIPIENT_ENDPOINT 2
|
||||
#define USB_REQUEST_RECIPIENT_OTHER 3
|
||||
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1 // wValue = <feature>, wIndex = 0|<interface>|<endpoint>, wLength = 0
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8 // wValue = 0, wIndex = 0, wLength = 1
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6 // wValue = <descriptor type>:<descriptor index>, wIndex = 0|<language>, wLength = <descriptor length>
|
||||
#define USB_REQUEST_GET_INTERFACE 10 // wValue = 0, wIndex = <interface>, wLength = 1
|
||||
#define USB_REQUEST_GET_STATUS 0 // wValue = 0, wIndex = 0|<interface>|<endpoint>, wLength = 2
|
||||
#define USB_REQUEST_SET_ADDRESS 5 // wValue = <address>, wIndex = 0, wLength = 0
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9 // wValue = <configuration value>, wIndex = 0, wLength = 0
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7 // wValue = <descriptor type>:<descriptor index>, wIndex = 0|<language>, wLength = <descriptor length>
|
||||
#define USB_REQUEST_SET_FEATURE 3 // wValue = <feature selector>, wIndex = 0|<interface>|<endpoint>, wLength = 0
|
||||
#define USB_REQUEST_SET_INTERFACE 11 // wValue = <alternate setting>, wIndex = <interface>, wLength = 0
|
||||
#define USB_REQUEST_SYNCH_FRAME 12 // wValue = 0, wIndex = <endpoint>, wLength = 2
|
||||
|
||||
#define USB_EPR_STAT_TX_DISABLED 0x00
|
||||
#define USB_EPR_STAT_TX_STALL USB_EP0R_STAT_TX_0
|
||||
#define USB_EPR_STAT_TX_NAK USB_EP0R_STAT_TX_1
|
||||
#define USB_EPR_STAT_TX_VALID (USB_EP0R_STAT_TX_0 | USB_EP0R_STAT_TX_1)
|
||||
|
||||
#define USB_EPR_STAT_RX_DISABLED 0x00
|
||||
#define USB_EPR_STAT_RX_STALL USB_EP0R_STAT_RX_0
|
||||
#define USB_EPR_STAT_RX_NAK USB_EP0R_STAT_RX_1
|
||||
#define USB_EPR_STAT_RX_VALID (USB_EP0R_STAT_RX_0 | USB_EP0R_STAT_RX_1)
|
||||
|
||||
#define USB_EPR_EP_TYPE_BULK 0x00
|
||||
#define USB_EPR_EP_TYPE_CONTROL USB_EP0R_EP_TYPE_0
|
||||
#define USB_EPR_EP_TYPE_ISO USB_EP0R_EP_TYPE_1
|
||||
#define USB_EPR_EP_TYPE_INTERRUPT (USB_EP0R_EP_TYPE_0 | USB_EP0R_EP_TYPE_1)
|
||||
|
||||
#define USB_PMA_ADDR 0x40006000UL
|
||||
#define USB_BTABLE_OFFSET 0x00
|
||||
#define USB_EP_RXCOUNT_BL_SIZE (1 << 15)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile union
|
||||
{
|
||||
volatile uint16_t ADDR_TX;
|
||||
volatile uint16_t ADDR_RX_0;
|
||||
volatile uint16_t ADDR_TX_0;
|
||||
};
|
||||
volatile uint16_t rsvd1;
|
||||
volatile union
|
||||
{
|
||||
volatile uint16_t COUNT_TX;
|
||||
volatile uint16_t COUNT_RX_0;
|
||||
volatile uint16_t COUNT_TX_0;
|
||||
};
|
||||
volatile uint16_t rsvd2;
|
||||
volatile union
|
||||
{
|
||||
volatile uint16_t ADDR_RX;
|
||||
volatile uint16_t ADDR_RX_1;
|
||||
volatile uint16_t ADDR_TX_1;
|
||||
};
|
||||
volatile uint16_t rsvd3;
|
||||
volatile union
|
||||
{
|
||||
volatile uint16_t COUNT_RX;
|
||||
volatile uint16_t COUNT_RX_1;
|
||||
volatile uint16_t COUNT_TX_1;
|
||||
};
|
||||
volatile uint16_t rsvd4;
|
||||
} __attribute__((packed, aligned(4))) USB_BufferTableEntry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__((packed, aligned(2))) USB_SetupPacket_t;
|
||||
|
||||
#define USB_BTABLE_ENTRIES ((USB_BufferTableEntry_t*)(USB_PMA_ADDR + USB_BTABLE_OFFSET))
|
||||
|
||||
void USB_Init(void);
|
|
@ -1,33 +0,0 @@
|
|||
#include "usb_com.h"
|
||||
|
||||
unsigned USBCOM_Registers[USBCOM_N_REGISTERS];
|
||||
|
||||
uint8_t USBCOM_HandleSetupPacket(USB_SetupPacket_t *sp, const uint8_t **reply_data)
|
||||
{
|
||||
uint8_t reply_length = 0;
|
||||
|
||||
if(sp->bmRequestType & USB_REQUEST_DIRECTION_IN)
|
||||
{
|
||||
// Read register
|
||||
if(sp->bRequest < USBCOM_N_REGISTERS)
|
||||
{
|
||||
*reply_data = (uint8_t*)&USBCOM_Registers[sp->bRequest];
|
||||
reply_length = sp->wLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write register
|
||||
if(sp->bRequest < USBCOM_N_REGISTERS)
|
||||
{
|
||||
USBCOM_Registers[sp->bRequest] = ((uint32_t)(sp->wIndex) << 16) | sp->wValue;
|
||||
}
|
||||
}
|
||||
|
||||
return reply_length;
|
||||
}
|
||||
|
||||
void USBCOM_HandleISO0OUT(void)
|
||||
{
|
||||
__asm__("bkpt");
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
typedef enum {
|
||||
USBCOM_REG_LEDCOUNT,
|
||||
|
||||
USBCOM_N_REGISTERS
|
||||
} USBCOM_Register_t;
|
||||
|
||||
extern unsigned USBCOM_Registers[USBCOM_N_REGISTERS];
|
||||
|
||||
uint8_t USBCOM_HandleSetupPacket(USB_SetupPacket_t *sp, const uint8_t **reply_data);
|
||||
void USBCOM_HandleISO0OUT(void);
|
|
@ -1,75 +0,0 @@
|
|||
#include "usb_descriptors.h"
|
||||
|
||||
const USB_DeviceDescriptor_t USB_DeviceDescriptor =
|
||||
{
|
||||
.bLength = 18,
|
||||
.bDescriptorType = USB_DEVICE_DESCRIPTOR,
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = 0xff,
|
||||
.bDeviceSubClass = 0xff,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = 64,
|
||||
.idVendor = 0x16c0,
|
||||
.idProduct = 0x05dc,
|
||||
.bcdDevice = 0x0200,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigurations = 1
|
||||
};
|
||||
|
||||
const USB_WholeDescriptor_t USB_ConfigurationInterfaceDescriptor =
|
||||
{
|
||||
.configuration = (USB_ConfigurationDescriptor_t)
|
||||
{
|
||||
.bLength = 9,
|
||||
.bDescriptorType = USB_CONFIGURATION_DESCRIPTOR,
|
||||
.wTotalLength = sizeof(USB_WholeDescriptor_t),
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = 0x80,
|
||||
.bMaxPower = 100
|
||||
},
|
||||
.interface0 = (USB_InterfaceDescriptor_t)
|
||||
{
|
||||
.bLength = 9,
|
||||
.bDescriptorType = USB_INTERFACE_DESCRIPTOR,
|
||||
.bInterfaceNumber = 0,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = 0,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = 0
|
||||
},
|
||||
.endpoint0out = (USB_EndpointDescriptor_t)
|
||||
{
|
||||
.bLength = sizeof(USB_EndpointDescriptor_t),
|
||||
.bDescriptorType = USB_ENDPOINT_DESCRIPTOR,
|
||||
.bEndpointAddress = 1,
|
||||
.bmAttributes = 1,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 1
|
||||
}
|
||||
};
|
||||
|
||||
#define USB_STRING_LANGID 0x0409
|
||||
#define USB_STRING_VENDOR 'F', 'r', 'u', 'c', 'h', 't', \
|
||||
'i', '\'', 's', 0
|
||||
#define USB_STRING_PRODUCT 'e', 'x', 't', 'r', 'e', 'm', \
|
||||
'e', 'l', 'y', ' ', \
|
||||
'd', 'u', 'm', 'b', ' ', \
|
||||
't', 'h', 'e', 'r', 'm', 'a', \
|
||||
'l', ' ', 'p', 'r', 'i', 'n', \
|
||||
't', 'e', 'r', 0
|
||||
#define USB_STRING_SERIAL 'v', '0', '.', '0', '0', '1', 0
|
||||
|
||||
const uint16_t USB_StringDescriptor_LangID[] =
|
||||
USB_BUILD_STRING_DESCRIPTOR(USB_STRING_LANGID);
|
||||
const uint16_t USB_StringDescriptor_Vendor[] =
|
||||
USB_BUILD_STRING_DESCRIPTOR(USB_STRING_VENDOR);
|
||||
const uint16_t USB_StringDescriptor_Product[] =
|
||||
USB_BUILD_STRING_DESCRIPTOR(USB_STRING_PRODUCT);
|
||||
const uint16_t USB_StringDescriptor_Serial[] =
|
||||
USB_BUILD_STRING_DESCRIPTOR(USB_STRING_SERIAL);
|
|
@ -1,106 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
};
|
||||
uint8_t raw[18];
|
||||
} __attribute__((packed)) USB_DeviceDescriptor_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
uint8_t raw[9];
|
||||
} __attribute__((packed, aligned(1))) USB_ConfigurationDescriptor_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
uint8_t raw[9];
|
||||
} __attribute__((packed, aligned(1))) USB_InterfaceDescriptor_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
};
|
||||
uint8_t raw[7];
|
||||
} __attribute__((packed)) USB_EndpointDescriptor_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_ConfigurationDescriptor_t configuration;
|
||||
USB_InterfaceDescriptor_t interface0;
|
||||
USB_EndpointDescriptor_t endpoint0out;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
uint8_t raw[18];
|
||||
} __attribute__((packed, aligned(1))) USB_WholeDescriptor_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USB_DEVICE_DESCRIPTOR = 1,
|
||||
USB_CONFIGURATION_DESCRIPTOR,
|
||||
USB_STRING_DESCRIPTOR,
|
||||
USB_INTERFACE_DESCRIPTOR,
|
||||
USB_ENDPOINT_DESCRIPTOR
|
||||
} __attribute__((packed)) USB_DescriptorType_t;
|
||||
|
||||
#define USB_STRING_DESCRIPTOR_LENGTH(...) (sizeof((uint16_t[]){__VA_ARGS__}) + 2)
|
||||
#define USB_BUILD_STRING_DESCRIPTOR(...) {USB_STRING_DESCRIPTOR_LENGTH(__VA_ARGS__) | (USB_STRING_DESCRIPTOR << 8), __VA_ARGS__}
|
||||
|
||||
extern const uint16_t USB_StringDescriptor_LangID[];
|
||||
extern const uint16_t USB_StringDescriptor_Vendor[];
|
||||
extern const uint16_t USB_StringDescriptor_Product[];
|
||||
extern const uint16_t USB_StringDescriptor_Serial[];
|
||||
|
||||
extern const USB_DeviceDescriptor_t USB_DeviceDescriptor;
|
||||
// extern const USB_ConfigurationDescriptor_t USB_ConfigurationDescriptor;
|
||||
// extern const USB_InterfaceDescriptor_t USB_InterfaceDescriptor;
|
||||
extern const USB_WholeDescriptor_t USB_ConfigurationInterfaceDescriptor;
|
Loading…
Reference in a new issue