Update Atsam BSP Support

Alexander Krutwig alexander.krutwig at embedded-brains.de
Tue Oct 4 11:39:46 UTC 2016


over the last months, lots of work and effort has been put into the 
of the BSP support for ATSAMV7 microcontrollers by Atmel.
Thus, I updated the README of the BSP with the work already done in the 
process and
attached it to this email in order to keep you updated about the progress.

In addition to the work described in the document, we currently work on 
USB and SD-card
support. Support for NOR flashes is already finished, however, not yet 

Best regards,
Alexander Krutwig

embedded brains GmbH
Alexander Krutwig
Dornierstr. 4
D-82178 Puchheim
email: alexander.krutwig at embedded-brains.de
Phone: +49-89-18 94 741 - 17
Fax:   +49-89-18 94 741 - 09
PGP: Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

-------------- next part --------------
= Board support package for the Atmel SAM V71/V70/E70/S70 chip platform.

== General Information

The BSP is customized to a particular board/chip variant by means of configure
command line options.

Use --enable-chip=XYZ to select the chip variant where XYZ is one of same70j19,
same70j20, same70j21, same70n19, same70n20, same70n21, same70q19, same70q20,
same70q21, sams70j19, sams70j20, sams70j21, sams70n19, sams70n20, sams70n21,
sams70q19, sams70q20, sams70q21, samv71j19, samv71j20, samv71j21, samv71n19,
samv71n20, samv71n21, samv71q19, samv71q20 and samv71q21.  By default the BSP
uses the ATSAMV71Q21 chip.  Not all variants are tested.

Use --enable-sdram=XYZ to select the SDRAM variant where XYZ is one of
is42s16100e-7bli and is42s16320f-7bl. Not all variants are tested with all
controller and speed combinations.

Use BOARD_MAINOSC=XYZ to set the main oscillator frequency in Hz (default

Use BOARD_MCK=XYZ to set the Master Clock (MCK) frequency in Hz (default
123MHz).  The default value enables operation of an external SDRAM, e.g. 150MHz
would be too fast.

Use ATSAM_CONSOLE_BAUD=XYZ to set the initial baud for console devices (default

Use ATSAM_CONSOLE_DEVICE_TYPE=XYZ to set the device type for /dev/console, use
0 for USART and 1 for UART (default USART).

Use ATSAM_CONSOLE_DEVICE_INDEX=XYZ to set the device index for /dev/console
(default 1, e.g. USART1).

Use ATSAM_CONSOLE_USE_INTERRUPTS=XYZ to set the use interrupt driven mode for
console devices (used by default).

Use ATSAM_MEMORY_TCM_SIZE=XYZ to set the size of tightly coupled memories (TCM)
in bytes (default 0x00000000).

Use ATSAM_MEMORY_INTFLASH_SIZE=XYZ to set the size of internal flash in bytes
(default is derived from chip variant).

Use ATSAM_MEMORY_INTSRAM_SIZE=XYZ to set the size of internal SRAM in bytes
(default is derived from chip variant).

Use ATSAM_MEMORY_SDRAM_SIZE=XYZ to set the size of external SDRAM in bytes
(default 0x00200000).

Use ATSAM_MEMORY_QSPIFLASH_SIZE=XYZ to set the size of QSPI flash in bytes
(default 0x00200000).

The pins may be configured by the application at link-time.
See link:include/pin-config.h[]

The clock driver uses the ARMv7-M Systick.

The console driver supports the USART and UART devices.

The default linker command file places the code into the internal flash.  Use
"LDFLAGS += -qnolinkcmds -T linkcmds.sdram" to place the code into the external
SDRAM.  Use "LDFLAGS += -qnolinkcmds -T linkcmds.intsram" to place the code
into the internal SRAM.

The fast text section uses the ITCM.  The fast data section uses the DTCM.

Data and instruction cache are enabled during system start.  The RTEMS cache
manager is supported with exception of the freeze functions.

== I2C driver ==

The I2C driver has been realized using the RTEMS I2C framework as a basis.
In order to start communication via I2C, the following steps have to be


Now, the device can be opened via the open command.

 int fd_in;
 int fd_out;
 fd_in = open(&eeprom_path[0], O_RDWR);
 fd_out = open(&eeprom_path[0], O_RDWR);

From now on, normal read and writes can be executed using the I2C device.

 ssize_t read_bytes;
 uint8_t data_in[EEPROM_SIZE];
 n = read(fd_in, &data_in[0], EEPROM_SIZE);

After completion, the bus and EEPROM shall be unlinked.


== Low-Power Support ==

With the low-power-support, module peripherals can be switched on or off.
Additionally, a timer can be set to wake up from low power mode.
Therefore, a structure called atsam_power_control shall be set. This structure
contains a function pointer where a specific handler can be inserted as well as
a function argument.

As function pointer, the following defines can be used:

 ATSAM_POWER_PERIPHERAL(switch on or off certain peripheral)
 ATSAM_POWER_CLOCK_DRIVER(switches off clock interrupts)
 ATSAM_POWER_SLEEP_MODE(enters processor sleep mode)
 ATSAM_POWER_RTC_DRIVER(a)(sets a wakeup timer which shall be set in argument a)

The argument a shall be a type atsam_power_data_rtc_driver which incorporates
an element called interval which is the amount of time in seconds that will
be spent in the low power mode.
As an application example, this excerpt demonstrates how the processor would be
set into low power mode for five seconds and then wakes up again.

 static atsam_power_data_rtc_driver rtc_data = {.interval = 5};
 static const atsam_power_control power_controls[] = {

 rtems_task lp_tasks(){
      RTEMS_ARRAY_SIZE(power_controls), ATSAM_POWER_OFF);
      RTEMS_ARRAY_SIZE(power_controls), ATSAM_POWER_ON);

 rtems_task Init(rtems_task_argument arg){
  atsam_power_control c = ATSAM_POWER_RTC_DRIVER(&rtc_data);
  // create rtems_task "lp_tasks" & open shell for input

See link:include/power.h[]

=== RTC driver ===

This driver is able to set and retrieve the time information from the real time
module (RTC) as well as set alarms and timers. This driver is mainly used in the
low power support in order to set the clock after waking up from the low power

== Ethernet driver ==

This driver sets up a network connection for the given microcontroller families.
As usual, with regard to network drivers a rtems_bsdnet_config shall be given to
setup up the connection.

 struct rtems_bsdnet_ifconfig atsam_ifconfig = {
  .next = NULL,
  .ip_address = NULL,
  .ip_netmask = NULL,
  .hardware_address = NULL,
  .ignore_broadcast = 0,
  .mtu = 0,
  .rbuf_count = 8,
  .xbuf_count = 64,
  .port = 0,
  .irno = 0,
  .bpar = 0

 struct rtems_bsdnet_config rtems_bsdnet_config = {
  .ifconfig = &atsam_ifconfig,
  .bootp = NULL,
  .network_task_priority = 10,
  .mbuf_bytecount = 8192,
  .mbuf_cluster_bytecount = (65536 - 8192),
  .hostname = NULL,
  .domainname = NULL,
  .gateway = NULL,
  .log_host = NULL,
  .name_server = { NULL, NULL, NULL },
  .ntp_server = { NULL, NULL, NULL },
  .sb_efficiency = 0,
  .udp_tx_buf_size = 0,
  .udp_rx_buf_size = 0,
  .tcp_tx_buf_size = 0,
  .tcp_rx_buf_size = 0

 static void Init(rtems_task_argument arg){
  rtems_status_code rv;
  static const char mac_address[6] = {0x0e, 0xb4, 0xba, 0x5e, 0xba, 0x11};
  static const char *ip_self = "";
  static const char *ip_gateway = "";
  static const char *ip_netmask = "";
  /* Setup Network */
  rtems_bsdnet_config.network_task_priority = 10;
  rtems_bsdnet_config.gateway = ip_gateway;
  rtems_bsdnet_config.log_host = ip_gateway;
  rtems_bsdnet_config.name_server [0] = ip_gateway;
  rtems_bsdnet_config.ntp_server [0] = ip_gateway;
  rtems_bsdnet_config.ifconfig->hardware_address = mac_address;
  rtems_bsdnet_config.ifconfig->ip_address = ip_self;
  rtems_bsdnet_config.ifconfig->ip_netmask = ip_netmask;
  rv = rtems_bsdnet_initialize_network();
  assert(rv == RTEMS_SUCCESSFUL);

== SPI driver ==

The SPI driver has been realized using the RTEMS SPI framework as a basis.
In order to start communication via SPI, the following steps have to be

 rv = atsam_register_spi_0();

After registration of the bus, the SPI device can be opened by an usual "open"

 int fd;
 fd = open(ATSAM_SPI_0_BUS_PATH, O_RDWR);

SPI messages are sent using the message type spi_ioc_transfer. In order to
trigger message transfers, the ioctl shall be used using the following command.

 spi_ioc_transfer msg;
 ioctl(fd, SPI_IOC_MESSAGE(1), &msg);

After completion, the bus shall be unlinked and the file descriptor closed.


== QSPI driver ==

The QSPI controller has the option to have the communication work in Single Bit,
Dual SPI and Quad SPI operation. Furthermore, it supports the function of
"Execute in Place (XIP)" which executes code directly from Serial Flash
By calling


the peripheral clock of the QSPI module is enabled, the QSPI Quad Mode is enabled
and the according cfi_attach and cfi_probe functions are called.

== TCM support ==

The microcontroller has the option use tightly coupled memory (TCM) that can be
set via the system control block. Those memories are controlled by the System
Control Block (SCB) and can be set to the sizes 0 KB, 32 KB, 64 KB, 128 KB for
both the Instruction TCM and Data TCM. Those sizes are currently set during the

See link:startup/bspstarthooks.c[]

== SPI bridge support for BSP independent UARTs ==

For the communication with the Dual UART with I2C-bus/SPI interface SC16IS752,
the aforementioned SPI framework was developed which can be found in the cpukit.
In the process, a UART based on Termios was developed to ensure the read, write,
open and close operations needed to communicate with the bridge device.
The communication can be achieved by two different modes, the polled mode and
the interrupt-based mode in which a wakeup interrupt is needed.
During initialization, parameters like input frequency as well as operation
using the RS232 or RS485 transmission mode has to be defined.

See link:../../../../../../cpukit/dev/serial/nxp-sc16is752.c[]

More information about the devel mailing list