Remove USB, remap a lot of pins

This commit is contained in:
fruchti 2018-08-04 15:20:55 +02:00
parent 22b6ee1136
commit 04bbaf8e14
11 changed files with 53 additions and 754 deletions

View file

@ -1 +1 @@
191
205

View file

@ -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)

View file

@ -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(;;)
{

View file

@ -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"

View file

@ -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
View file

@ -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
View file

@ -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);

View file

@ -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");
}

View file

@ -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);

View file

@ -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);

View file

@ -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;