Skip to content

Commit 8096afc

Browse files
committed
Microchip PIC24/dsPIC33 device mode support
1 parent c5992ed commit 8096afc

File tree

2 files changed

+112
-32
lines changed

2 files changed

+112
-32
lines changed

src/common/tusb_mcu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@
111111
#define TUP_DCD_ENDPOINT_MAX 8
112112
#define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER
113113

114+
#elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || \
115+
TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33)
116+
#define TUP_DCD_ENDPOINT_MAX 16
117+
#define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER
118+
114119
//------------- ST -------------//
115120
#elif TU_CHECK_MCU(OPT_MCU_STM32F0)
116121
#define TUP_DCD_ENDPOINT_MAX 8

src/portable/microchip/pic/dcd_pic.c

Lines changed: 107 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,10 @@
3939

4040
#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK)
4141

42-
#define TU_PIC_HAS_MMU 1
43-
#define TU_PIC_HAS_HW_RMW 1
4442
#define TU_PIC_INT_SIZE 4
4543

4644
#elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33)
4745

48-
#define TU_PIC_HAS_MMU 0
49-
#define TU_PIC_HAS_HW_RMW 0
5046
#define TU_PIC_INT_SIZE 2
5147

5248
#else
@@ -56,7 +52,7 @@
5652
#endif
5753

5854

59-
#if TU_PIC_HAS_MMU
55+
#if TU_PIC_INT_SIZE == 4
6056

6157
#ifndef KVA_TO_PA
6258
#define KVA_TO_PA(kva) ((uint32_t)(kva) & 0x1fffffff)
@@ -89,6 +85,8 @@ enum {
8985
TOK_PID_SETUP = 0xDu,
9086
};
9187

88+
// The BDT is 8 bytes on 32bit PICs and 4 bytes on 8/16bit PICs
89+
#if TU_PIC_INT_SIZE == 4
9290
typedef struct TU_ATTR_PACKED
9391
{
9492
union {
@@ -119,6 +117,37 @@ typedef struct TU_ATTR_PACKED
119117
} buffer_descriptor_t;
120118

121119
TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" );
120+
#else
121+
typedef struct TU_ATTR_PACKED
122+
{
123+
union {
124+
uint16_t head;
125+
126+
struct {
127+
uint16_t : 10;
128+
uint16_t tok_pid : 4;
129+
uint16_t data : 1;
130+
uint16_t own : 1;
131+
};
132+
struct {
133+
uint16_t : 10;
134+
uint16_t bdt_stall : 1;
135+
uint16_t dts : 1;
136+
uint16_t ninc : 1;
137+
uint16_t keep : 1;
138+
};
139+
140+
struct {
141+
uint16_t bc : 10;
142+
uint16_t : 6;
143+
};
144+
};
145+
uint8_t *addr;
146+
} buffer_descriptor_t;
147+
148+
TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 4, "size is not correct" );
149+
#endif
150+
122151

123152
typedef struct TU_ATTR_PACKED
124153
{
@@ -142,7 +171,11 @@ typedef struct
142171
union {
143172
/* [#EP][OUT,IN][EVEN,ODD] */
144173
buffer_descriptor_t bdt[16][2][2];
145-
uint16_t bda[512];
174+
#if TU_PIC_INT_SIZE == 4
175+
uint16_t bda[256];
176+
#else
177+
uint8_t bda[256];
178+
#endif
146179
};
147180
TU_ATTR_ALIGNED(4) union {
148181
endpoint_state_t endpoint[16][2];
@@ -158,7 +191,11 @@ typedef struct
158191
// BDT(Buffer Descriptor Table) must be 256-byte aligned
159192
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
160193

194+
#if TU_PIC_INT_SIZE == 4
161195
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
196+
#else
197+
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 256, "size is not correct" );
198+
#endif
162199

163200
#if TU_PIC_INT_SIZE == 4
164201
typedef uint32_t ep_reg_t;
@@ -172,7 +209,12 @@ static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) {
172209
#else
173210
volatile void *ep_reg_base = &U1EP0;
174211
#endif
175-
return ep_reg_base + 0x10 * ep_num;
212+
#if TU_PIC_INT_SIZE == 4
213+
const size_t offset = 0x10;
214+
#else
215+
const size_t offset = 0x2;
216+
#endif
217+
return ep_reg_base + offset * ep_num;
176218
}
177219

178220
static inline ep_reg_t ep_read(uint8_t rhport, uint8_t ep_num) {
@@ -186,7 +228,7 @@ static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
186228
}
187229

188230
static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
189-
#if TU_PIC_HAS_HW_RMW
231+
#if TU_PIC_INT_SIZE == 4
190232
volatile ep_reg_t *ep_clr = (ep_addr(rhport, ep_num) + 0x4);
191233
*ep_clr = val;
192234
#else
@@ -197,7 +239,7 @@ static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
197239
}
198240

199241
static inline void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
200-
#if TU_PIC_HAS_HW_RMW
242+
#if TU_PIC_INT_SIZE == 4
201243
volatile ep_reg_t *ep_s = (ep_addr(rhport, ep_num) + 0x8);
202244
*ep_s = val;
203245
#else
@@ -278,7 +320,7 @@ static void prepare_next_setup_packet(uint8_t rhport)
278320
_dcd.bdt[0][1][in_odd].data = 1;
279321
_dcd.bdt[0][1][in_odd ^ 1].data = 0;
280322
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
281-
_dcd.setup_packet, sizeof(_dcd.setup_packet));
323+
_dcd.setup_packet, sizeof(_dcd.setup_packet));
282324
}
283325

284326
static void process_stall(uint8_t rhport)
@@ -298,7 +340,7 @@ static void process_stall(uint8_t rhport)
298340

299341
static void process_tokdne(uint8_t rhport)
300342
{
301-
uint32_t s = U1STAT;
343+
ep_reg_t s = U1STAT;
302344

303345
U1IR = _U1IR_TRNIF_MASK;
304346

@@ -321,7 +363,11 @@ static void process_tokdne(uint8_t rhport)
321363
ep->odd = odd ^ 1;
322364
if (pid == TOK_PID_SETUP) {
323365
dcd_event_setup_received(rhport, (uint8_t *)PA_TO_KVA1(bd->addr), true);
366+
#if TU_PIC_INT_SIZE == 4
324367
U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK;
368+
#else
369+
U1CONbits.PKTDIS = 0;
370+
#endif
325371
return;
326372
}
327373

@@ -341,8 +387,8 @@ static void process_tokdne(uint8_t rhport)
341387
}
342388
const unsigned length = ep->length;
343389
dcd_event_xfer_complete(rhport,
344-
tu_edpt_addr(epnum, dir),
345-
length - remaining, XFER_RESULT_SUCCESS, true);
390+
tu_edpt_addr(epnum, dir),
391+
length - remaining, XFER_RESULT_SUCCESS, true);
346392
if (0 == epnum && 0 == length) {
347393
/* After completion a ZLP of control transfer,
348394
* it prepares for the next steup transfer. */
@@ -358,11 +404,16 @@ static void process_tokdne(uint8_t rhport)
358404

359405
static void process_bus_reset(uint8_t rhport)
360406
{
407+
#if TU_PIC_INT_SIZE == 4
361408
U1PWRCCLR = _U1PWRC_USUSPEND_MASK;
362409
U1CONSET = _U1CON_PPBRST_MASK;
410+
#else
411+
U1PWRCbits.USUSPND = 0;
412+
U1CONbits.PPBRST = 1;
413+
#endif
363414
U1ADDR = 0;
364415

365-
U1IE = _U1IE_URSTIE_DETACHIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK |
416+
U1IE = _U1IE_URSTIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK |
366417
_U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK;
367418

368419
U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK;
@@ -386,7 +437,11 @@ static void process_bus_reset(uint8_t rhport)
386437
tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0]));
387438
_dcd.addr = 0;
388439
prepare_next_setup_packet(rhport);
440+
#if TU_PIC_INT_SIZE == 4
389441
U1CONCLR = _U1CON_PPBRST_MASK;
442+
#else
443+
U1CONbits.PPBRST = 0;
444+
#endif
390445
dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
391446
}
392447

@@ -399,9 +454,15 @@ static void process_bus_sleep(uint8_t rhport)
399454
static void process_bus_resume(uint8_t rhport)
400455
{
401456
// Enable suspend & disable resume interrupt
457+
#if TU_PIC_INT_SIZE == 4
402458
U1PWRCCLR = _U1PWRC_USUSPEND_MASK;
403459
U1IECLR = _U1IE_RESUMEIE_MASK;
404460
U1IESET = _U1IE_IDLEIE_MASK;
461+
#else
462+
U1PWRCbits.USUSPND = 0;
463+
U1IEbits.RESUMEIE = 0;
464+
U1IEbits.IDLEIE = 1;
465+
#endif
405466

406467
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
407468
}
@@ -418,26 +479,29 @@ void dcd_init(uint8_t rhport)
418479
TRISBbits.TRISB6 = 1;
419480
#endif
420481

421-
#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX) || (CFG_TUSB_MCU == OPT_MCU_PIC32MM)
482+
tu_memclr(&_dcd, sizeof(_dcd));
483+
484+
#if TU_PIC_INT_SIZE == 4
422485
U1PWRCSET = _U1PWRC_USBPWR_MASK;
423-
#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
424-
// TODO
425-
#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33)
486+
#else
426487
U1PWRCbits.USBPWR = 1;
427488
#endif
428-
429-
tu_memclr(&_dcd, sizeof(_dcd));
430-
489+
490+
#if TU_PIC_INT_SIZE == 4
431491
uint32_t bdt_phys = KVA_TO_PA((uintptr_t)_dcd.bdt);
432492

433493
U1BDTP1 = (uint8_t)(bdt_phys >> 8);
434494
U1BDTP2 = (uint8_t)(bdt_phys >> 16);
435495
U1BDTP3 = (uint8_t)(bdt_phys >> 24);
496+
#else
497+
U1BDTP1 = (uint8_t)((uint16_t)(void *)_dcd.bdt >> 8);
436498

437-
U1IE = _U1IE_URSTIE_DETACHIE_MASK;
499+
U1CNFG1bits.PPB = 2;
500+
#endif
438501

439-
dcd_connect(rhport);
502+
U1IE = _U1IE_URSTIE_MASK;
440503

504+
dcd_connect(rhport);
441505
}
442506

443507
void dcd_int_enable(uint8_t rhport)
@@ -459,18 +523,30 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
459523

460524
void dcd_remote_wakeup(uint8_t rhport)
461525
{
526+
#if TU_PIC_INT_SIZE == 4
462527
U1CONSET = _U1CON_RESUME_MASK;
463-
528+
#else
529+
U1CONbits.RESUME = 1;
530+
#endif
464531
unsigned cnt = 25000000 / 1000;
465532
while (cnt--) asm volatile("nop");
466533

534+
#if TU_PIC_INT_SIZE == 4
467535
U1CONCLR = _U1CON_RESUME_MASK;
536+
#else
537+
U1CONbits.RESUME = 0;
538+
#endif
468539
}
469540

470541
void dcd_connect(uint8_t rhport)
471542
{
472-
while (!U1CONbits.USBEN)
543+
while (!U1CONbits.USBEN) {
544+
#if TU_PIC_INT_SIZE == 4
473545
U1CONSET = _U1CON_USBEN_SOFEN_MASK;
546+
#else
547+
U1CONbits.USBEN = 1;
548+
#endif
549+
}
474550
}
475551

476552
void dcd_disconnect(uint8_t rhport)
@@ -502,14 +578,14 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
502578

503579
ep->max_packet_size = tu_edpt_packet_size(ep_desc);
504580

581+
505582
unsigned val = _U1EP0_EPCONDIS_MASK;
506583
val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? _U1EP0_EPHSHK_MASK : 0;
507584
val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK;
508585

509-
volatile void *ep_reg_base = &U1EP0;
510-
volatile uint32_t *reg_ep = (ep_reg_base + 0x10 * epn);
511-
512-
*reg_ep |= val;
586+
ep_reg_t tmp = ep_read(rhport, epn);
587+
tmp |= val;
588+
ep_write(rhport, epn, tmp);
513589

514590
if (xfer != TUSB_XFER_ISOCHRONOUS) {
515591
bd[odd].dts = 1;
@@ -569,6 +645,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
569645

570646
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
571647
{
648+
572649
const unsigned epn = tu_edpt_number(ep_addr);
573650
const unsigned dir = tu_edpt_dir(ep_addr);
574651
endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
@@ -593,7 +670,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
593670
}
594671
bd->bc = total_bytes >= mps ? mps: total_bytes;
595672
bd->addr = (uint8_t *)KVA_TO_PA(buffer);
596-
// __DSB();
597673
bd->own = 1; /* This bit must be set last */
598674

599675
if (ie) intr_enable(rhport);
@@ -673,7 +749,7 @@ void dcd_int_handler(uint8_t rhport)
673749
U1IR = is; /* discard any pending events */
674750
}
675751

676-
if (is & _U1IR_URSTIF_DETACHIF_MASK) {
752+
if (is & _U1IR_URSTIF_MASK) {
677753
U1IR = is; /* discard any pending events */
678754
process_bus_reset(rhport);
679755
}
@@ -705,7 +781,6 @@ void dcd_int_handler(uint8_t rhport)
705781
}
706782

707783
intr_clear(rhport);
708-
709784
}
710785

711786
#endif

0 commit comments

Comments
 (0)