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.
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 |
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); |
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:
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.
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.
This option specifies the size of the internal transmit buffers used for the Ethernet device.
This option specifies the size of the internal receive buffers used for the Ethernet device.
This option specifies the number of output buffer packets to be used for the Ethernet device.
This option specifies the number of input buffer packets to be used for the Ethernet device.
Selecting this option will cause the Ethernet driver to accumulate statistics provided from the MAC layer.
The Actel A2Fxxx uses the 16x5x generic serial device driver. The driver is instantiaced through the CYGPKG_IO_SERIAL_CORTEXM_A2FXXX serial package.
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. |