Mercurial > ecos
changeset 2660:b3f68c7d3671
* cdl/cl_cs8900a_eth_drivers.cdl: Added
CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT option to manage chip in 8-bit
mode.
* include/cs8900.h
* src/if_cs8900a.c: Added a support for the 8-bit access for CS8900A.
All access to CS8900A registers wrapped via CS_IN, CS_OUT macros (the
macros were defined in past, but, still not used). In common way the
macros use the eCos macros: HAL_READ_UINT16, HAL_WRITE_UINT16 , but,
in other (rare) conditions they can use 8-bit access too.
| author | asl |
|---|---|
| date | Sun, 23 Nov 2008 12:36:23 +0000 |
| parents | a8a5496dc26a |
| children | 20ca46d1ed4b |
| files | packages/devs/eth/cl/cs8900a/current/ChangeLog packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl packages/devs/eth/cl/cs8900a/current/include/cs8900.h packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c |
| diffstat | 4 files changed, 73 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/eth/cl/cs8900a/current/ChangeLog +++ b/packages/devs/eth/cl/cs8900a/current/ChangeLog @@ -1,3 +1,15 @@ +2008-11-07 Sergei Gavrikov <sergei.gavrikov@gmail.com> + + * cdl/cl_cs8900a_eth_drivers.cdl: Added + CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT option to manage chip in 8-bit + mode. + * include/cs8900.h + * src/if_cs8900a.c: Added a support for the 8-bit access for CS8900A. + All access to CS8900A registers wrapped via CS_IN, CS_OUT macros (the + macros were defined in past, but, still not used). In common way the + macros use the eCos macros: HAL_READ_UINT16, HAL_WRITE_UINT16 , but, + in other (rare) conditions they can use 8-bit access too. + 2007-09-04 Stephen Finney <shf@pfinc.com> * add timeout to potential infinite loop in cs8900a_send per
--- a/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl +++ b/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl @@ -80,6 +80,22 @@ cdl_package CYGPKG_DEVS_ETH_CL_CS8900A { carefully chosen decision, hence this option." } + cdl_option CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT { + display "8-bit data bus" + flavor bool + requires !CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM + requires CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS + default_value 0 + description " + The CS8900A can been use in 8-bit mode. From AN181 from + Cirrus Logic... Unsupported functions in 8-bit mode: + Interrupts are not supported. Polled mode must be used; + The DMA engine only uses 16 bit memory access and does not + support 8 bit transfers; The packet page pointer has an + auto increment feature that cannot be used in 8-bit mode; + An EEPROM is not supported." + } + cdl_option CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED { display "Byte swapped data bus" flavor bool
--- a/packages/devs/eth/cl/cs8900a/current/include/cs8900.h +++ b/packages/devs/eth/cl/cs8900a/current/include/cs8900.h @@ -80,7 +80,9 @@ // 2 for added data IO output: get_reg, put_reg // 4 for packet allocation/free output // 8 for only startup status, so we can tell we're installed OK -#define DEBUG 0x0 +#ifndef DEBUG +# define DEBUG 0x0 +#endif #if DEBUG & 1 #define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0) @@ -440,10 +442,10 @@ static __inline__ cyg_uint16 get_reg(cyg_addrword_t base, int regno) { cyg_uint16 val; - HAL_WRITE_UINT16(base+CS8900A_PPTR, regno); - HAL_READ_UINT16(base+CS8900A_PDATA, val); + CS_OUT(base, CS8900A_PPTR, regno); + CS_IN(base, CS8900A_PDATA, val); #if DEBUG & 2 - diag_printf("get_reg(%p, %d) => 0x%04x\n", base, regno, val); + diag_printf("get_reg(%p, %d) => 0x%04x\n", (void *)base, regno, val); #endif return val; } @@ -452,10 +454,10 @@ static __inline__ void put_reg(cyg_addrword_t base, int regno, cyg_uint16 val) { #if DEBUG & 2 - diag_printf("put_reg(%p, %d, 0x%04x)\n", base, regno, val); + diag_printf("put_reg(%p, %d, 0x%04x)\n", (void *)base, regno, val); #endif - HAL_WRITE_UINT16(base+CS8900A_PPTR, regno); - HAL_WRITE_UINT16(base+CS8900A_PDATA, val); + CS_OUT(base, CS8900A_PPTR, regno); + CS_OUT(base, CS8900A_PDATA, val); } #endif // _CYGONCE_ETH_CL_CS8900_H_
--- a/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c +++ b/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c @@ -212,7 +212,7 @@ cs8900a_init(struct cyg_netdevtab_entry chip_type = get_reg(base, PP_ChipID); chip_rev = get_reg(base, PP_ChipRev); #if DEBUG & 8 - diag_printf("CS8900A[%p] - type: 0x%04x, rev: 0x%04x\n", base, chip_type, chip_rev); + diag_printf("CS8900A[%p] - type: 0x%04x, rev: 0x%04x\n", (void *)base, chip_type, chip_rev); #endif if (chip_type != PP_ChipID_CL) { #if DEBUG & 8 @@ -353,10 +353,12 @@ cs8900a_start(struct eth_drv_sc *sc, cyg put_reg(base, PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx); // Clear Interrupt Status Queue before enabling interrupts do { - HAL_READ_UINT16(cpd->base+CS8900A_ISQ, stat); + CS_IN(cpd->base, CS8900A_ISQ, stat); } while (stat != 0) ; cpd->txbusy = false; +#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT put_reg(base, PP_BusCtl, PP_BusCtl_EnableIRQ); +#endif } // This routine is called to perform special "control" opertions @@ -473,6 +475,7 @@ cs8900a_send(struct eth_drv_sc *sc, stru cyg_uint8 *data; cyg_uint16 saved_data = 0, *sdata; cyg_uint16 stat; + bool force_coping_by_byte; bool odd_byte = false; // Mark xmitter busy @@ -487,6 +490,12 @@ cs8900a_send(struct eth_drv_sc *sc, stru total_len = CYG_SWAP16(total_len); #endif +#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT + force_coping_by_byte = true; +#else + force_coping_by_byte = false; +#endif + // The hardware indicates that there are options as to when the actual // packet transmission will start wrt moving of data into the transmit // buffer. However, impirical results seem to indicate that if the @@ -498,12 +507,12 @@ cs8900a_send(struct eth_drv_sc *sc, stru // not all of the data was provided before the transmission should // have completed (i.e. buffer underrun). // For now, the solution is to not allow this overlap. - //HAL_WRITE_UINT16(cpd->base+CS8900A_TxCMD, PP_TxCmd_TxStart_5) + //CS_OUT(cpd->base, CS8900A_TxCMD, PP_TxCmd_TxStart_5) // Start only when all data sent to chip - HAL_WRITE_UINT16(cpd->base+CS8900A_TxCMD, PP_TxCmd_TxStart_Full); + CS_OUT(cpd->base, CS8900A_TxCMD, PP_TxCmd_TxStart_Full); - HAL_WRITE_UINT16(cpd->base+CS8900A_TxLEN, total_len); + CS_OUT(cpd->base, CS8900A_TxLEN, total_len); // Wait for controller ready signal { // add timeout per cs8900a bugzilla report 1000281 */ @@ -539,20 +548,20 @@ cs8900a_send(struct eth_drv_sc *sc, stru #else saved_data |= ((cyg_uint16)*data++) << 8; #endif - HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); + CS_OUT(cpd->base, CS8900A_RTDATA, saved_data); len--; odd_byte = false; } - if (((CYG_ADDRESS)data & 0x1) == 0) { + if (!force_coping_by_byte && ((CYG_ADDRESS)data & 0x1) == 0) { /* Aligned on 16-bit boundary, so output contiguous words. */ sdata = (cyg_uint16 *)data; while (len > 1) { // Make sure data get on the bus in Big Endian format #if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \ (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED )) - HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, *sdata++); + CS_OUT(cpd->base, CS8900A_RTDATA, *sdata++); #else - HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, CYG_SWAP16(*sdata++)); + CS_OUT(cpd->base, CS8900A_RTDATA, CYG_SWAP16(*sdata++)); #endif len -= sizeof(cyg_uint16); } @@ -568,7 +577,7 @@ cs8900a_send(struct eth_drv_sc *sc, stru #else saved_data |= ((cyg_uint16)*data++) << 8; #endif - HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); + CS_OUT(cpd->base, CS8900A_RTDATA, saved_data); len -= sizeof(cyg_uint16); } } @@ -585,7 +594,7 @@ cs8900a_send(struct eth_drv_sc *sc, stru } } if (odd_byte) { - HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data); + CS_OUT(cpd->base, CS8900A_RTDATA, saved_data); } } @@ -603,8 +612,18 @@ cs8900a_RxEvent(struct eth_drv_sc *sc, i if(stat & PP_RxCFG_RxOK) { // Only start reading a message if one has been received - HAL_READ_UINT16(base+CS8900A_RTDATA, stat); - HAL_READ_UINT16(base+CS8900A_RTDATA, len); +#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT + CS_IN(base, CS8900A_RTDATA, stat); + CS_IN(base, CS8900A_RTDATA, len); +#else + // From AN181 Using the Crystal CS8900A in 8-bit mode. + // Note: it is very important to read the RxStatus and RxLength high + // order byte first. + stat = *(volatile CYG_BYTE *)(base + CS8900A_RTDATA + 1) << 8; + stat |= *(volatile CYG_BYTE *)(base + CS8900A_RTDATA); + len = *(volatile CYG_BYTE *)(base + CS8900A_RTDATA + 1) << 8; + len |= *(volatile CYG_BYTE *)(base + CS8900A_RTDATA); +#endif #ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED len = CYG_SWAP16(len); @@ -639,7 +658,7 @@ cs8900a_recv(struct eth_drv_sc *sc, stru data = (cyg_uint16 *)sg_list[i].buf; mlen = sg_list[i].len; while (mlen >= sizeof(*data)) { - HAL_READ_UINT16(base+CS8900A_RTDATA, val); + CS_IN(base, CS8900A_RTDATA, val); if (data) { #if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \ (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED )) @@ -651,7 +670,7 @@ cs8900a_recv(struct eth_drv_sc *sc, stru mlen -= sizeof(*data); } if (mlen) { - HAL_READ_UINT16(base+CS8900A_RTDATA, val); + CS_IN(base, CS8900A_RTDATA, val); #ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED // last odd byte will be in the LSB cval = (cyg_uint8)(val); @@ -699,7 +718,7 @@ cs8900a_poll(struct eth_drv_sc *sc) cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private; cyg_addrword_t base = cpd->base; - HAL_READ_UINT16(base+CS8900A_ISQ, event); + CS_IN(base, CS8900A_ISQ, event); while (event != 0) { switch (event & ISQ_EventMask) { case ISQ_RxEvent: @@ -723,7 +742,7 @@ cs8900a_poll(struct eth_drv_sc *sc) #endif break; } - HAL_READ_UINT16(base+CS8900A_ISQ, event); + CS_IN(base, CS8900A_ISQ, event); } CYGHWR_CL_CS8900A_PLF_INT_CLEAR(cpd);
