1 /*********************************************************/
2 /*** Module : PDIUSB D11,H11,H11A,D12 - implement. ***/
3 /*** Author : Roman Bartosinski (C) 03.10.2002 ***/
4 /*** Description : Integrate common functions for ***/
5 /*** PDIUSBD11,PDIUSBD12,PDIUSBH11(old) ***/
6 /*** PDIUSBH11A in Single/Multiple mode ***/
7 /*** to one common file. ***/
8 /*** Modify : 10.10.2002 - add H11 ***/
9 /*** 13.10.2002 - add spec.fnc for 'using' ***/
10 /*********************************************************/
12 #include <system_def.h>
14 #if __BYTE_ORDER == __BIG_ENDIAN
17 #include <usb/pdiusb.h>
18 #include <usb/usb_spec.h>
20 #ifdef PDI_CMD_RWD_INTERNAL
22 #include <periph/i2c.h>
31 /*********************************************************/
32 // Function for read and write from/into chip
34 #if defined(PDI_CMD_RWD_INTERNAL)
35 #if defined(PDIUSBD12) // parallel interface
37 void pdiSendCommand( unsigned char byCmd) {
38 *((volatile xdata unsigned char *) PDIUSB_COMMAND_ADDR) = byCmd;
40 unsigned char pdiReadData( unsigned char byCount, void *pbyData) {
41 unsigned char out = byCount;
44 *(unsigned char*)pbyData++ = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
48 void pdiWriteData( unsigned char byCount, const void *pbyData) {
51 *((volatile xdata unsigned char *) PDIUSB_WRITE_DATA_ADDR) = *(unsigned char*)pbyData++;
55 #if defined(PDI_USE_USING)
56 unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING {
58 *((volatile xdata unsigned char *) PDIUSB_COMMAND_ADDR) = byCmd;
59 i[0] = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
64 i[1] = *((volatile xdata unsigned char *) PDIUSB_READ_DATA_ADDR);
65 return (((unsigned short) i[1]) << 8) + i[0];
69 #else // serial interface iic
71 #define D11_REG_CMD PDIUSB_COMMAND_ADDR
73 #ifndef D11_REG_DATA_WRITE
74 #define D11_REG_DATA_WRITE PDIUSB_WRITE_DATA_ADDR
76 #ifndef D11_REG_DATA_READ
77 #define D11_REG_DATA_READ PDIUSB_READ_DATA_ADDR
80 void pdiSendCommand( unsigned char byCmd) {
81 I2C_Write( D11_REG_CMD, &byCmd, 1);
83 unsigned char pdiReadData( unsigned char byCount, void *pbyData) {
84 I2C_Read( D11_REG_DATA_READ, pbyData, byCount);
87 void pdiWriteData( unsigned char byCount, const void *pbyData) {
88 I2C_Write( D11_REG_DATA_WRITE, pbyData, byCount);
90 #if defined(PDI_USE_USING)
91 unsigned short pdiIntCmdReadData( unsigned char byCmd, unsigned char byShort) _PDI_USING {
99 /*********************************************************/
100 /*********************************************************/
101 // PDIUSB common commands
103 #if defined(PDIUSBH11) || defined(PDIUSBH11A) || defined(PDIUSBD11)
105 /*********************************************************/
106 // pdiSetHUBAddressEnable
107 // enable HUB function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
108 void pdiSetHUBAddressEnable( unsigned char byAddress, unsigned char byEnable) {
109 // usb_debug_print( DEBUG_LEVEL_HIGH, ("H "));
110 byAddress = (byAddress & 0x7F) | (byEnable << 7);
111 pdiSendCommand( PDI_CMD_HUB_ENB_ADDR);
112 pdiWriteData( 1, &byAddress);
116 #if !defined(PDIUSBH11A_MULTPLE) // D11,D12,H11,H11A_S(emb.fnc)
118 /*********************************************************/
119 // pdiSetAddressEnable
120 // Enable function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
121 void pdiSetAddressEnable( unsigned char byAddr_Enb) {
122 // usb_debug_print( DEBUG_LEVEL_HIGH, ("A "));
123 pdiSendCommand( PDI_CMD_FNC_ENB_ADDR);
124 pdiWriteData( 1, &byAddr_Enb);
129 /*********************************************************/
130 // pdiSetEmbFncAddressEnable
131 // Enable Embedded function and set address (byAddress is 0-0x7F, byEnable is 0 or 1)
132 // byFnc - function index (zero based) 0-3
133 void pdiSetEmbFncAddressEnable( unsigned char byFnc, unsigned char byAddress, unsigned char byEnable) {
134 byAddress = (byAddress & 0x7F) | (byEnable << 7);
135 pdiSendCommand( PDI_CMD_FNC1_ENB_ADDR + byFnc);
136 pdiWriteData( 1, &byAddress);
143 /*********************************************************/
144 // pdiSetEndpointEnable
145 // enable/disable endpoints (PDI_EPEN_xxx)
146 void pdiSetEndpointEnable( unsigned char byEnable) {
147 // usb_debug_print( DEBUG_LEVEL_HIGH, ("E "));
148 pdiSendCommand( PDI_CMD_EPEN);
149 pdiWriteData( 1, &byEnable);
153 #if !defined(PDIUSBH11) // H11 has not it
155 /*********************************************************/
157 // set chip mode (PDI_MODE_xxx) and clock division factor (PDI_CLOCK_xxx)
158 void pdiSetMode( unsigned short wMode_Clock) {
160 // usb_debug_print( DEBUG_LEVEL_HIGH, ("M%04X ",wMode_Clock));
161 sm[0] = (unsigned char) (wMode_Clock & 0xff);
162 sm[1] = (unsigned char) (wMode_Clock >> 8);
163 pdiSendCommand( PDI_CMD_SET_MODE);
164 pdiWriteData( 2, sm);
169 #if defined(PDIUSBD12)
171 /*********************************************************/
173 // set DMA mode (PDI_DMA_xxx)
174 void pdiSetDMA( unsigned char byDma) {
175 pdiSendCommand( PDI_CMD_SET_DMA);
176 pdiWriteData( 1, &byDma);
179 /*********************************************************/
181 // get current DMA mode
182 unsigned char pdiGetDMA( void) {
184 pdiSendCommand( PDI_CMD_GET_DMA);
185 pdiReadData( 1, &dma);
192 #if defined(PDIUSBH11)
194 /*********************************************************/
196 // pdiGetInterrupt - H11 return only one byte
197 // get interrupt register (PDI_INT_xxx)
198 unsigned char pdiGetInterrupt( void) _PDI_USING {
200 #if defined(PDI_USE_USING)
201 return pdiIntCmdReadData( PDI_CMD_GET_INT_REG, 0);
203 pdiSendCommand( PDI_CMD_GET_INT_REG);
204 pdiReadData( 1, &gin);
211 /*********************************************************/
213 // get interrupt register (PDI_INT_xxx)
214 unsigned short pdiGetInterrupt( void) _PDI_USING {
216 #if defined(PDI_USE_USING)
217 return pdiIntCmdReadData( PDI_CMD_GET_INT_REG, 1);
219 pdiSendCommand( PDI_CMD_GET_INT_REG);
220 pdiReadData( 2, &gin);
221 #if __BYTE_ORDER == __BIG_ENDIAN
224 return gin; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
230 /*********************************************************/
232 // set internal buffer pointer to selected endpoint (zero based) (PDI_SELEP_xxx)
233 unsigned char pdiSelectEp( unsigned char byEpIdx) {
235 // usb_debug_print( DEBUG_LEVEL_HIGH, ("e%1d ",byEpIdx));
236 pdiSendCommand( PDI_CMD_SELECT_EP + byEpIdx);
237 pdiReadData( 1, &sep);
241 /*********************************************************/
242 // pdiGetLastTransStatus
243 // get Last transaction status (PDI_LTSTAT_xxx and PDI_ERR_xxx)
244 unsigned char pdiGetLastTransStatus( unsigned char byEpIdx) _PDI_USING {
246 // usb_debug_print( DEBUG_LEVEL_HIGH, ("L "));
247 #if defined(PDI_USE_USING)
248 return pdiIntCmdReadData( PDI_CMD_GET_LAST_STAT + byEpIdx, 0);
250 pdiSendCommand( PDI_CMD_GET_LAST_STAT + byEpIdx);
251 pdiReadData( 1, <s);
257 #if defined(PDIUSBD11) || defined(PDIUSBH11) || defined(PDIUSBH11A)
259 /*********************************************************/
261 // get Endpoint Status (PDI_EPSTAT_xxx)
262 unsigned char pdiGetEpStatus( unsigned char byEpIdx) {
264 // usb_debug_print( DEBUG_LEVEL_HIGH, ("G "));
265 pdiSendCommand( PDI_CMD_GET_EP_STAT + byEpIdx);
266 pdiReadData( 1, &ges);
272 /*********************************************************/
273 // pdiReadFromEpBuffer - raw reading
274 // read data from selected internal chip buffer
275 // if byLength < length of buffer data, so we read only byLength data)
276 unsigned char pdiReadFromEpBuffer( unsigned char byLength, unsigned char *pToBuff) {
277 unsigned char rdep[2];
278 // usb_debug_print( DEBUG_LEVEL_HIGH, ("R "));
279 pdiSendCommand( PDI_CMD_READ_BUFFER);
280 pdiReadData( 2, rdep);
281 if ( rdep[1]) { // there is some data
282 if ( byLength < rdep[1]) // we need less data then is received
284 pdiReadData( rdep[1], pToBuff);
289 /*********************************************************/
290 // pdiWriteToEpBuffer - raw writing
291 // write data to selected internal chip buffer
292 void pdiWriteToEpBuffer( unsigned char byLength, const unsigned char *pFromBuff) {
294 // usb_debug_print( DEBUG_LEVEL_HIGH, ("W "));
295 pdiSendCommand( PDI_CMD_WRITE_BUFFER);
296 hd[0] = 0; hd[1] = byLength;
297 pdiWriteData( 2, hd);
299 pdiWriteData( byLength, pFromBuff);
303 /*********************************************************/
305 // set endpoint stall flag
306 void pdiSetEpStatus( unsigned char byEpIdx, unsigned char byStatus) {
307 // usb_debug_print( DEBUG_LEVEL_HIGH, ("T "));
308 pdiSendCommand( PDI_CMD_SET_EP_STAT + byEpIdx);
309 pdiWriteData( 1, &byStatus);
312 /*********************************************************/
313 // pdiAcknowledgeSetup
314 // chip disable fncs Validate and Clear after SETUP packet,
315 // this cmd re-enable these fncs
316 void pdiAcknowledgeSetup( void) {
317 // usb_debug_print( DEBUG_LEVEL_HIGH, ("C "));
318 pdiSendCommand( PDI_CMD_ACK_SETUP);
321 /*********************************************************/
323 // set endpoint flag 'empty' and next data can be receive
324 void pdiClearBuffer( void) {
325 // usb_debug_print( DEBUG_LEVEL_HIGH, ("B "));
326 pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
330 /*********************************************************/
332 // set endpoint flag 'full' and data can be send
333 void pdiValidateBuffer( void) {
334 // usb_debug_print( DEBUG_LEVEL_HIGH, ("V "));
335 pdiSendCommand( PDI_CMD_VALID_BUFFER);
338 /*********************************************************/
340 // send an upstream resume signal for 10ms
341 void pdiSendResume( void) {
342 // usb_debug_print( DEBUG_LEVEL_HIGH, ("M "));
343 pdiSendCommand( PDI_CMD_SEND_RESUME);
346 /*********************************************************/
348 // return frame number of last successfully received SOF
349 unsigned short pdiGetFrameNumber( void) {
351 pdiSendCommand( PDI_CMD_GET_FRAME);
352 pdiReadData( 2, &gfn);
353 #if __BYTE_ORDER == __BIG_ENDIAN
356 return gfn; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
359 /*********************************************************/
360 // pdiGetChipID - this function is undocumented
361 // read chip ID (not documented function) ( LSB is maybe type of chip in hex (0x12,0x11))
362 unsigned short pdiGetChipID( void) {
364 pdiSendCommand( PDI_CMD_GET_CHIP_ID);
365 pdiReadData( 2, &gid);
366 #if __BYTE_ORDER == __BIG_ENDIAN
369 return gid; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
373 /*********************************************************/
374 /*********************************************************/
376 #if defined(PDIUSBH11) || defined(PDIUSBH11A)
377 /*********************************************************/
378 // pdiClearPortFeature
379 // clear feature 'byFeature' in downstream port 2-5 'byEpIdx' (zero based)
380 void pdiClearPortFeature( unsigned char byEpIdx, unsigned char byFeature) {
381 pdiSendCommand( PDI_CMD_P2_CLR_FEATURE + byEpIdx);
382 pdiWriteData( 1, &byFeature);
385 /*********************************************************/
387 // set feature 'byFeature' in downstream port 2-5 'byEpIdx' (zero based)
388 void pdiSetPortFeature( unsigned char byEpIdx, unsigned char byFeature) {
389 pdiSendCommand( PDI_CMD_P2_SET_FEATURE + byEpIdx);
390 pdiWriteData( 1, &byFeature);
393 /*********************************************************/
395 // get port status (port status byte and port status change byte)
396 unsigned short pdiGetPortFeature( unsigned char byEpIdx) {
398 pdiSendCommand( PDI_CMD_P2_GET_STATUS + byEpIdx);
399 pdiReadData( 2, &gpf);
400 #if __BYTE_ORDER == __BIG_ENDIAN
403 return gpf; //pdiData[0] + (((unsigned short)pdiData[1])<<8);
406 /*********************************************************/
407 // pdiSetStatusChangeBits
408 // set local power change bits status
409 void pdiSetStatusChangeBits( unsigned char byBits) {
410 pdiSendCommand( PDI_CMD_SET_CHNG_BITS);
411 pdiWriteData( 1, &byBits);
418 /*********************************************************/
419 /*********************************************************/
420 // PDIUSB other commands
422 // complex function for select endpoint, write data and validate data in endpoint buffer
423 void pdiWriteEndpoint( unsigned char byEpIdx, unsigned char byLength, const unsigned char *pbyData) {
424 pdiSelectEp( byEpIdx);
425 pdiWriteToEpBuffer( byLength, pbyData);
429 // complex function for select endpoint, read data and clear endpoint buffer
430 // byMaxLength means how many bytes will be maximally read.
431 unsigned char pdiReadEndpoint( unsigned char byEpIdx, unsigned char byMaxLength, unsigned char *pbyData) {
432 unsigned char cnt = 0, sep;
433 sep = pdiSelectEp( byEpIdx);
434 if ( sep & PDI_SELEP_FULL) {
435 cnt = pdiReadFromEpBuffer( byMaxLength, pbyData);
441 // complex universal function for select command and read/write data to/from PDIUSB
442 unsigned char pdiCmdData( unsigned char byCmd, unsigned char *pbyData,
443 unsigned char byCount, unsigned char byRead) {
444 pdiSendCommand( byCmd);
446 if( byRead) byCount = pdiReadData( byCount, pbyData); // Read Data
447 else pdiWriteData( byCount, pbyData); // Write Data
452 #if !defined(PDIUSBH11A_MULTIPLE)
453 // complex function for acknowledge control endpoint
454 void pdiAckSetupControl( void) {
455 pdiSendCommand( PDI_CMD_SELECT_EP + PDI_EP0_RX);
456 pdiSendCommand( PDI_CMD_ACK_SETUP);
457 pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
458 pdiSendCommand( PDI_CMD_SELECT_EP + PDI_EP0_TX);
459 pdiSendCommand( PDI_CMD_ACK_SETUP);
462 // complex function for acknowledge control endpoint ( for one emb.fnc. 1,6,7) (zero-based 0,1,2)
463 void pdiAckSetupFncControl( unsigned char Fnc) {
464 unsigned char FncTab[3] = { PDI_F1_EP0_RX, PDI_F6_EP0_RX, PDI_F7_EP0_RX};
465 pdiSendCommand( PDI_CMD_SELECT_EP + FncTab[Fnc]);
466 pdiSendCommand( PDI_CMD_ACK_SETUP);
467 pdiSendCommand( PDI_CMD_CLEAR_BUFFER);
468 pdiSendCommand( PDI_CMD_SELECT_EP + FncTab[Fnc] + 1);
469 pdiSendCommand( PDI_CMD_ACK_SETUP);
473 #if defined(PDIUSBD12) // parallel interface
474 void pdiInit( void) {
475 pdiSetAddressEnable( PDI_ENAD_ENABLE);
476 pdiSetEndpointEnable( PDI_EPEN_ENABLE);
477 pdiSetDMA( PDI_DMA_EP4_INT | PDI_DMA_EP5_INT);
478 pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING |
479 PDI_MODE_SOFT_CONNECT | PDI_CLOCK_12M);
483 #if defined(PDIUSBH11A_SINGLE) // serial interface
484 void pdiInit( void) {
485 pdiSetHUBAddressEnable( 0, 0); // disable HUB
486 pdiSetAddressEnable( PDI_ENAD_ENABLE); // enable emb.function
487 pdiSetEndpointEnable( PDI_EPEN_FNC_ENB);
488 pdiSetMode( PDI_MODE_REMOTE_WAKEUP | PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING |
489 PDI_MODE_SOFT_CONNECT | PDI_MODE_SINGLE_FNC | PDI_CLOCK_12M);
493 /*********************************************************/
495 static const unsigned char epin2idx[]={
506 static const unsigned char epout2idx[]={
518 // convert endpoint number to pdi index number
519 unsigned char pdiEp2Idx(unsigned char ep) {
520 if(ep & USB_ENDPOINT_DIRECTION_MASK)
521 return epin2idx[ep & 0xf];
523 return epout2idx[ep & 0xf];
526 /*********************************************************/
527 /*********************************************************/