Code Confidencebuild 3.0.0.201402161939

HAL and Device Drivers

Name

HAL -- Actel HAL and Device Drivers

Clocking

The internal clock network of the Smarfusion devices includes a large amount of possible configuration combination. The network has 3 different input clocks (CLKA, CLKB and CLKC), each of them can be connected to a different clock source such as the main oscillator, the RC oscillator, the FPGA fabric or the dedicated single-ended or differential IO. The clock network has an internal PLL and 3 global output clocks (CLKGA, CLKGB and CLKGC). The cortex-M3, digital and analog peripherals clocks are derived either from CLKGA or CLKGC through the NGMUX. Due to the large amount of configuration parameters, it is recommended to use the Actel MSS configuration tool to setup the clock network and let the system boot handle the configuration. However, the eCos HAL includes all the required options to setup the clock network. Note that only a limited subset of combinations have been tested.

SPI bus

The Actel AF2xxx microcontroller family has 2 SPI buses available. Each SPI bus has a certain number of slave select line (called SPI_x_SSx) that are directly driven by the SPI controller. The first SPI bus has 4 slave select lines available (SPI_0_SS0 to SPI_0_SS3) while the second bus has 8 of them (SPI_1_SS0 to SPI_1_SS7). In addition, the eCos SPI driver allows using the GPIO of the microcontroller as slave select lines which is in some cases required. In the rest of this chapter, the former case is called SPI controlled slave select while the later is called GPIO controlled slave select

NOTE: The SPI_x_SSx microcontroller dedicated pins can be used as GPIO, thus, it is possible to use SPI_0_SS0 as slave select either in SPI or GPIO controlled mode. This is true for all SPI_x_SSx pins.

New SPI devices are instantiated using the following macro:

        #include <cyg/io/spi.h>
        #include <cyg/io/spi_a2fxxx.h>

        #define CYG_DEVS_SPI_CORTEXM_A2FXXX_DEVICE(                    \
                _name_, _bus_, _csnum_, _csgpio_, _proto_, _clpol_,    \
                _clpha_, _brate_, _csup_dly_, _csdw_dly_, _trbt_dly_)


        _name_     is the name of the SPI device. This will be used to 
                   reference a data structure of type cyg_spi_device 
                   which can be passed to the SPI driver API without 
                   needing a cast.
        _bus_      is the bus number to which this device is attached 
                   (1 or 2).
        _csgpio_   when set to false:
                    - the device slave select line is controlled by the 
                      SPI controller.
                   when set to true:
                    - the device slave select line is a GPIO of the 
                      processor controlled by the SPI driver.
        _csnum_    when _csgpio_ is set to false : 
                    - is the slave select line used for this device, 
                      numbered from 0.
                   when _csgpio_ is set to true : 
                    - is the GPIO number used to drive the device slave 
                      select line.
        _proto_    is the SPI bus protocol:
                    0 -> Motorola SPI Mode (_clpol_ and _clpha_ are 
                         valid in this mode)
                    1 -> National Semiconductor MICROWIRE Mode
                    2 -> Texas Instruments (TI) Synchronous Serial Mode
        _clpol_    is the SPI bus clock polarity used by the device 
                   (valid only for Motorola SPI Protocol).
        _clpha_    is the SPI bus clock phase used by the device 
                   (valid only for Motorola SPI Protocol).
        _brate_    is the SPI bus clock baud rate used by the device, 
                   measured in Hz.
        _csup_dly_ is the minimum delay between slave select assert and 
                   transfer start, measured in microseconds.
        _csdw_dly_ is the minimum delay between transfer end and slave 
                   select deassert, measured in microseconds.
        _trbt_dly_ is the minimum delay between consecutive transfers.
     

NOTE: _csup_dly_ and _csdw_dly_ are only valid when GPIOs are configured to drive the slave select line. When the SPI controller drives the slave select line itself, the user has no control over the exact timing.

The Actel Smartfusion board features a SPI serial flash (AT25DF641) attached to the first SPI bus. The SPI flash is connected to the SPI_0_SS0 line, however, to suit eCos SPI transaction, the line is configured as a general purpose IO and controlled by the SPI driver.

The following section describes how the SPI serial flash is declared. The code is located in devs/fash/cortexm/a2fxxx/a2f200_eval/flash_a2f200_eval.c. The required includes are:

        #include <cyg/io/spi.h>
        #include <cyg/io/at25dfxxx.h>
        #include <cyg/io/spi_a2fxxx.h>
     

The device is defined to be connected on SPI bus 1, using GPIO 19 for slave select. The Motorola protocol (mode 0) is selected with a bus clock speed of 25MHz.

         CYG_DEVS_SPI_CORTEXM_A2FXXX_DEVICE (
            at25dfxxx_spi_device, 1, 19, true, A2FXXX_SPI_MOTOROLA, 0, 0, 25000000, 1, 1, 1
         );
        
         _bus_      = 1 
         _csgpio_   = true -> use GPIO
         _csgpio_   = 19   -> GPIO19 also SPI_0_SS0
         _proto_    = Motorola Protocol
         _clpol_    = 0
         _clpha_    = 0
         _brate_    = 25MHz
         _csup_dly  = 1us
         _csdw_dly_ = 1us
         _trbt_dly_ = 1us
     

From the default CDL, SPI bus 1 uses the DMA channel 0 for outbound and channel 1 for inbound transfer. SPI bus 2 uses DMA channel 2 and 3 respectively. The DMA channel number are selected with:

        CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_TX_DMA
        CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_RX_DMA 
        and
        CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_TX_DMA
        CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_RX_DMA 
     

I2C bus

The Actel microcontroller family has 2 I2C buses available and the Smartfusion evaluation kit feature an OLED display connected to the first I2C bus with address 0x3C. The I2C driver is tested using the OLED display, however, the OLED driver is not part of the eCos HAL. A new I2C bus is instantiated using the following macro:

        #define CYG_A2FXXX_I2C_BUS(                             \
                _name_,                                         \
                _init_fn_,                                      \
                _base_,                                         \
                _base_bb_,                                      \
                _periph_,                                       \
                _isr_vec_,                                      \
                _isr_pri_)                                      \

        _name_      is the name of the SPI device.
        _init_fn_   is the I2C initialization function to be called by the C constructor.
        _base_      is the base address of the I2C peripheral.
        _base_bb_   is the Bit-Band base address of the I2C peripheral.
        _periph_    is the peripheral bit identifier for reset/release operation.
        _isr_vec_   is the peripheral interrupt vector number.
        _isr_pri_   is the interrupt priority.
     

The following section describes how the I2C bus 0 is declared. The code is located in hal/cortexm/a2fxxx/a2f200_eval/current/src/platform_i2c.c. The required includes are:

        #include <cyg/io/i2c.h>
        #include <cyg/io/i2c_a2fxxx.h>
     

The first part declares the I2C bus 0 and the second part attached a I2C device with address 0x3C to the bus.

         CYG_A2FXXX_I2C_BUS(hal_a2fxxx_i2c0_bus,
                 a2fxxx_i2c0_init,
                 CYGHWR_HAL_A2FXXX_I2C0,
                 CYGHWR_HAL_A2FXXX_I2C0_BB,
                 CYGHWR_HAL_A2FXXX_SC_CLR_SOFTRST_CR_I2C0,
                 CYGNUM_HAL_INTERRUPT_I2C0_0,
                 0x60);

         _name_     = hal_a2fxxx_i2c0_bus
         _init_fn_  = a2fxxx_i2c0_init
         _base_     = CYGHWR_HAL_A2FXXX_I2C0                    // Base address
         _base_bb_  = CYGHWR_HAL_A2FXXX_I2C0_BB                 // for bit-band access
         _periph_   = CYGHWR_HAL_A2FXXX_SC_CLR_SOFTRST_CR_I2C0
         _isr_vec_  = CYGNUM_HAL_INTERRUPT_I2C0_0
         _isr_pri_  = 0x60

         CYG_I2C_DEVICE(i2c_a2fxxx_oled,
                 &hal_a2fxxx_i2c0_bus,
                 0x3c,
                 0,
                 CYG_I2C_DEFAULT_DELAY);
     

Ethernet Controller

The Ethernet MAC layer of the Actel device is compliant with the RMII 10/100Mbps specification. The development kit interface the DP83848 PHY from National Semiconductor.

NOTE: To use the Ethernet interface of the evaluation kit, the FPGA fabric must be programmed. The Ethernet PHY input clock (50MHz) is connected to an IO only accessible from the fabric. It is therefore required to route the MAC_CLK from the clock network to the IO (T6).

Some of the driver configuration parameters accessible from the CDL file are:

CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_CHATTER

Selecting this option will cause the Ethernet driver to print status messages as various Ethernet operations are undertaken. This is option is designed to help debugging the Ethernet driver.

CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_PROMISCUOUS

Selecting this option will set the Ethernet MAC in promiscuous mode, all Ethernet packets will be delivered to the application layer whether or not destinated to the device.

CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_TX

This option specifies the size of the internal transmit buffers used for the Ethernet device.

CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_RX

This option specifies the size of the internal receive buffers used for the Ethernet device.

CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM

This option specifies the number of output buffer packets to be used for the Ethernet device.

CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM

This option specifies the number of input buffer packets to be used for the Ethernet device.

CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS

Selecting this option will cause the Ethernet driver to accumulate statistics provided from the MAC layer.

Serial

The Actel A2Fxxx uses the 16x5x generic serial device driver. The driver is instantiaced through the CYGPKG_IO_SERIAL_CORTEXM_A2FXXX serial package.

DMA

The eCos HAL offers some basics routines to configure and use the 8 DMA channels available in the Smartfusion chips. It must be noted that all channels are sharing the same interrupt. The current implementation limits the transfer size to byte tranfer ( field TRANSFER_SIZE from the CHANNEL_x_CONTROL register ). Currently only the SPI driver makes use of the DMA interface.

DMA channels are registered / released with a2fxxx_dma_ch_attach and a2fxxx_dma_ch_detach respectively:

     cyg_uint32
     a2fxxx_dma_ch_attach(cyg_uint8 ch, cyg_ISR_t *isr, cyg_DSR_t *dsr, cyg_addrword_t data)

     ch         specify the DMA channel numbered from 0.
     isr        specify the interrupt ISR to call for this channel.
     dsr        specify the interrupt DSR to call for this channel.
     data       data argument passed to the ISR and DSR routine.
     
     void
     a2fxxx_dma_ch_detach (cyg_uint8 ch)

     ch         specify the DMA channel number from 0 to 7
     

DMA channels are configured with a2fxxx_dma_ch_setup :

     cyg_uint32
     a2fxxx_dma_ch_setup(cyg_uint8 ch, cyg_uint8 type, cyg_bool outbound, 
           cyg_uint8 src_incr, cyg_uint8 dst_incr, cyg_bool pri, cyg_uint8 wr_adj)

     ch         is the DMA channel numbered from 0.
     type       is the transfer type to be performed. For valid
                values, check CYGHWR_HAL_A2FXXX_DMA_XFER(_x) in var_io.h.
     outbound   set to true for transfer out of memory, false for transfer 
                to memory
     src_incr   is the memory address increment step for the source. Valid
                values are 0, 1, 2 and 4 byte(s). 0 can be used for DMA
                transfer from peripheral FIFO for instance.
     dst_incr   is the memory address increment step for the destination.
                Valid values are 0, 1, 2 and 4 byte(s). 0 can be used for 
                DMA transfer to peripheral FIFO for instance.
     pri        is the DMA channel priority (true = high , false = low)
     wr_adj     indicates the number of FCLK periods which the PDMA must wait 
                after completion of a read or write access to a peripheral
                before evaluating the out-of-band status signals from that 
                peripheral for another transfer.
     

DMA transfer are initiated using a2fxxx_dma_xfer :

     cyg_uint32
     a2fxxx_dma_xfer (cyg_uint8 ch, cyg_bool polled, cyg_uint32 len, cyg_uint8 *src, 
                          cyg_uint8 *dst)

     ch         is the DMA channel numbered from 0.
     polled     set to true to use the DMA channel in polling mode ( no
                end of tranfer interrupt are raised ).
     len        select the length of the transfer ( in number of byte
                transfered ).
     src        is the start address from which data is to be read during 
                the next DMA transfer cycle.
     dst        is the start address from which data is to be written during 
                the next DMA transfer cycle.
     

DMA interrupts are cleared with a2fxxx_dma_clear_interrupt and status of the transaction is retreived with a2fxxx_dma_get_comp_flag :

     void
     a2fxxx_dma_clear_interrupt (cyg_uint8 ch)

     cyg_uint8 
     a2fxxx_dma_get_comp_flag (cyg_uint8 ch)

     ch         is the DMA channel numbered from 0.