Skip to content

Commit 410ad4d

Browse files
author
Hubert Denkmair
committed
add basic STM32G0 support
1 parent be66f5f commit 410ad4d

File tree

2 files changed

+198
-68
lines changed

2 files changed

+198
-68
lines changed

src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ TU_ATTR_ALWAYS_INLINE static inline void reg16_clear_bits(__IO uint16_t *reg, ui
216216
}
217217

218218
// Bits in ISTR are cleared upon writing 0
219-
TU_ATTR_ALWAYS_INLINE static inline void clear_istr_bits(uint16_t mask) {
219+
TU_ATTR_ALWAYS_INLINE static inline void clear_istr_bits(uint32_t mask) {
220220
USB->ISTR = ~mask;
221221
}
222222

@@ -242,16 +242,23 @@ void dcd_init (uint8_t rhport)
242242
{
243243
asm("NOP");
244244
}
245+
246+
#ifdef PMA_32BIT_ACCESS // CNTR register is 32bits on STM32G0, 16bit on older versions
247+
USB->CNTR &= ~USB_CNTR_PDWN;
248+
#else
245249
reg16_clear_bits(&USB->CNTR, USB_CNTR_PDWN);// Remove powerdown
250+
#endif
251+
246252
// Wait startup time, for F042 and F070, this is <= 1 us.
247253
for(uint32_t i = 0; i<200; i++) // should be a few us
248254
{
249255
asm("NOP");
250256
}
251257
USB->CNTR = 0; // Enable USB
252-
253-
USB->BTABLE = DCD_STM32_BTABLE_BASE;
254258

259+
#ifndef STM32G0 // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address
260+
USB->BTABLE = DCD_STM32_BTABLE_BASE;
261+
#endif
255262
USB->ISTR = 0; // Clear pending interrupts
256263

257264
// Reset endpoints to disabled
@@ -312,7 +319,7 @@ void dcd_sof_enable(uint8_t rhport, bool en)
312319
}
313320
else
314321
{
315-
USB->CNTR &= (uint16_t) ~USB_CNTR_SOFM;
322+
USB->CNTR &= ~USB_CNTR_SOFM;
316323
}
317324
}
318325

@@ -358,6 +365,9 @@ void dcd_int_enable (uint8_t rhport)
358365
NVIC_EnableIRQ(USB_LP_IRQn);
359366
NVIC_EnableIRQ(USBWakeUp_IRQn);
360367

368+
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
369+
NVIC_EnableIRQ(USB_UCPD1_2_IRQn);
370+
361371
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
362372
NVIC_EnableIRQ(USB_HP_IRQn);
363373
NVIC_EnableIRQ(USB_LP_IRQn);
@@ -405,6 +415,9 @@ void dcd_int_disable(uint8_t rhport)
405415
NVIC_DisableIRQ(USB_LP_IRQn);
406416
NVIC_DisableIRQ(USBWakeUp_IRQn);
407417

418+
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
419+
NVIC_DisableIRQ(USB_UCPD1_2_IRQn);
420+
408421
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
409422
NVIC_DisableIRQ(USB_HP_IRQn);
410423
NVIC_DisableIRQ(USB_LP_IRQn);
@@ -433,7 +446,7 @@ void dcd_remote_wakeup(uint8_t rhport)
433446
{
434447
(void) rhport;
435448

436-
USB->CNTR |= (uint16_t) USB_CNTR_RESUME;
449+
USB->CNTR |= USB_CNTR_RESUME;
437450
remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms.
438451
}
439452

@@ -534,18 +547,22 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
534547

535548
if((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */
536549
{
537-
// The setup_received function uses memcpy, so this must first copy the setup data into
538-
// user memory, to allow for the 32-bit access that memcpy performs.
539-
uint8_t userMemBuf[8];
540550
uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex);
541551
/* Get SETUP Packet*/
542552
if(count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again.
543553
{
544554
// Must reset EP to NAK (in case it had been stalling) (though, maybe too late here)
545555
pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK);
546556
pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK);
547-
dcd_read_packet_memory(userMemBuf, *pcd_ep_rx_address_ptr(USB,EPindex), 8);
557+
#ifdef PMA_32BIT_ACCESS
558+
dcd_event_setup_received(0, (uint8_t*)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true);
559+
#else
560+
// The setup_received function uses memcpy, so this must first copy the setup data into
561+
// user memory, to allow for the 32-bit access that memcpy performs.
562+
uint8_t userMemBuf[8];
563+
dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB,EPindex), 8);
548564
dcd_event_setup_received(0, (uint8_t*)userMemBuf, true);
565+
#endif
549566
}
550567
}
551568
else
@@ -568,7 +585,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
568585

569586
if (count != 0U)
570587
{
571-
uint16_t addr = *pcd_ep_rx_address_ptr(USB, EPindex);
588+
uint16_t addr = pcd_get_ep_rx_address(USB, EPindex);
572589

573590
if (xfer->ff)
574591
{
@@ -672,8 +689,13 @@ void dcd_int_handler(uint8_t rhport) {
672689

673690
if (int_status & USB_ISTR_WKUP)
674691
{
692+
#ifdef PMA_32BIT_ACCESS // CNTR register is 32bits on STM32G0, 16bit on older versions
693+
USB->CNTR &= ~USB_CNTR_LPMODE;
694+
USB->CNTR &= ~USB_CNTR_FSUSP;
695+
#else
675696
reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE);
676697
reg16_clear_bits(&USB->CNTR, USB_CNTR_FSUSP);
698+
#endif
677699
clear_istr_bits(USB_ISTR_WKUP);
678700
dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
679701
}
@@ -695,7 +717,7 @@ void dcd_int_handler(uint8_t rhport) {
695717
if(int_status & USB_ISTR_ESOF) {
696718
if(remoteWakeCountdown == 1u)
697719
{
698-
USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
720+
USB->CNTR &= ~USB_CNTR_RESUME;
699721
}
700722
if(remoteWakeCountdown > 0u)
701723
{
@@ -722,8 +744,13 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re
722744
uint8_t const dev_addr = (uint8_t) request->wValue;
723745

724746
// Setting new address after the whole request is complete
747+
#ifdef PMA_32BIT_ACCESS
748+
USB->DADDR &= ~USB_DADDR_ADD;
749+
USB->DADDR = (USB->DADDR & ~USB_DADDR_ADD_Msk) | dev_addr; // leave the enable bit set
750+
#else
725751
reg16_clear_bits(&USB->DADDR, USB_DADDR_ADD);
726752
USB->DADDR = (uint16_t)(USB->DADDR | dev_addr); // leave the enable bit set
753+
#endif
727754
}
728755
}
729756

@@ -925,14 +952,14 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc
925952

926953
if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) )
927954
{
928-
*pcd_ep_tx_address_ptr(USB, ep_idx) = pma_addr;
955+
pcd_set_ep_tx_address(USB, ep_idx, pma_addr);
929956
pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size);
930957
pcd_clear_tx_dtog(USB, ep_idx);
931958
}
932959

933960
if( (dir == TUSB_DIR_OUT) || (wType == USB_EP_ISOCHRONOUS) )
934961
{
935-
*pcd_ep_rx_address_ptr(USB, ep_idx) = pma_addr;
962+
pcd_set_ep_rx_address(USB, ep_idx, pma_addr);
936963
pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size);
937964
pcd_clear_rx_dtog(USB, ep_idx);
938965
}
@@ -1011,10 +1038,10 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
10111038
xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx;
10121039

10131040
pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS);
1014-
1015-
*pcd_ep_tx_address_ptr(USB, ep_idx) = pma_addr;
1016-
*pcd_ep_rx_address_ptr(USB, ep_idx) = pma_addr;
1017-
1041+
1042+
pcd_set_ep_tx_address(USB, ep_idx, pma_addr);
1043+
pcd_set_ep_rx_address(USB, ep_idx, pma_addr);
1044+
10181045
return true;
10191046
}
10201047

@@ -1063,7 +1090,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix)
10631090
}
10641091

10651092
uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix);
1066-
uint16_t addr_ptr = *pcd_ep_tx_address_ptr(USB,ep_ix);
1093+
uint16_t addr_ptr = pcd_get_ep_tx_address(USB, ep_ix);
10671094

10681095
if (xfer->ff)
10691096
{
@@ -1197,6 +1224,19 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
11971224
}
11981225
}
11991226

1227+
#ifdef PMA_32BIT_ACCESS
1228+
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes)
1229+
{
1230+
// FIXME original function uses byte-access to source memory (to support non-aligned buffers)
1231+
const uint32_t* src32 = (uint32_t*)(src);
1232+
uint32_t* dst32 = (uint32_t*)(USB_PMAADDR + dst);
1233+
for (unsigned n=wNBytes/4; n>0; --n) {
1234+
*dst32++ = *src32++;
1235+
}
1236+
*dst32 = (*src32) & ((1<<8*(wNBytes % 4)) - 1);
1237+
return true;
1238+
}
1239+
#else
12001240
// Packet buffer access can only be 8- or 16-bit.
12011241
/**
12021242
* @brief Copy a buffer from user memory area to packet memory area (PMA).
@@ -1239,6 +1279,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si
12391279

12401280
return true;
12411281
}
1282+
#endif
12421283

12431284
/**
12441285
* @brief Copy from FIFO to packet memory area (PMA).
@@ -1290,6 +1331,14 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN
12901331
return true;
12911332
}
12921333

1334+
#ifdef PMA_32BIT_ACCESS
1335+
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes)
1336+
{
1337+
// FIXME this should probably be modified for possible unaligned access?
1338+
memcpy(dst, (void*)(USB_PMAADDR+src), wNBytes);
1339+
return true;
1340+
}
1341+
#else
12931342
/**
12941343
* @brief Copy a buffer from packet memory area (PMA) to user memory area.
12951344
* Uses byte-access of system memory and 16-bit access of packet memory
@@ -1323,6 +1372,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
13231372
}
13241373
return true;
13251374
}
1375+
#endif
13261376

13271377
/**
13281378
* @brief Copy a buffer from user packet memory area (PMA) to FIFO.

0 commit comments

Comments
 (0)