[Armadeus-commitlog] armadeus branch, master, updated. armadeus-6.0-89-gff5c0ef
Brought to you by:
sszy
|
From: Julien B a. A. <ar...@us...> - 2016-06-01 16:40:55
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via ff5c0ef882bad0015d34e1bce2abc52afab63108 (commit)
from 0901cbe64e727eeed08c3977300cc9b5e82ed837 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ff5c0ef882bad0015d34e1bce2abc52afab63108
Author: Julien BOIBESSOT <jul...@ar...>
Date: Wed Jun 1 18:36:16 2016 +0200
[TARGET] Add some examples to do bare-metal programming on APF6
-----------------------------------------------------------------------
Summary of changes:
target/baremetal/Makefile | 30 +++++++++++
target/baremetal/README | 11 ++++
target/baremetal/apf6dev_led.c | 36 +++++++++++++
target/baremetal/apf6dev_led.h | 3 +
target/baremetal/imx6.ld | 21 ++++++++
target/baremetal/imx6_epit.c | 86 +++++++++++++++++++++++++++++++
target/baremetal/imx6_epit.h | 4 ++
target/baremetal/imx6_led_blink.c | 49 +++++++++++++++++
target/baremetal/imx6_uart.c | 103 +++++++++++++++++++++++++++++++++++++
target/baremetal/imx6_uart.h | 4 ++
target/baremetal/start.s | 15 +++++
11 files changed, 362 insertions(+), 0 deletions(-)
create mode 100644 target/baremetal/Makefile
create mode 100644 target/baremetal/README
create mode 100644 target/baremetal/apf6dev_led.c
create mode 100644 target/baremetal/apf6dev_led.h
create mode 100644 target/baremetal/imx6.ld
create mode 100644 target/baremetal/imx6_epit.c
create mode 100644 target/baremetal/imx6_epit.h
create mode 100644 target/baremetal/imx6_led_blink.c
create mode 100644 target/baremetal/imx6_uart.c
create mode 100644 target/baremetal/imx6_uart.h
create mode 100644 target/baremetal/start.s
diff --git a/target/baremetal/Makefile b/target/baremetal/Makefile
new file mode 100644
index 0000000..bb5c34c
--- /dev/null
+++ b/target/baremetal/Makefile
@@ -0,0 +1,30 @@
+CROSS = arm-none-eabi
+CFLAGS = -g3 -Wall -Os
+CFLAGS += -DIMX6Q -mcpu=cortex-a9
+
+Q=@
+EXEC=led_blink
+
+default: all
+
+# start.s should be first !
+$(EXEC).elf: start.s imx6_led_blink.c imx6_uart.c imx6_epit.c apf6dev_led.c
+ @echo " CC/LD $@"
+ $(Q)$(CROSS)-gcc $(CFLAGS) -l gcc -ffreestanding -nostartfiles -o $@ $^ -T imx6.ld
+
+$(EXEC): $(EXEC).elf
+ @echo " BIN $@"
+ $(Q)$(CROSS)-objcopy -O binary $^ $@
+
+# Readable assembly code:
+$(EXEC).txt: $(EXEC).elf
+ @echo " TXT $@"
+ $(Q)$(CROSS)-objdump -D $^ > $@
+
+all: $(EXEC) $(EXEC).txt
+ cp $(EXEC) /tftpboot/
+
+clean:
+ rm -f *.elf
+ rm -f $(EXEC).txt
+ rm -f $(EXEC)
diff --git a/target/baremetal/README b/target/baremetal/README
new file mode 100644
index 0000000..49035ad
--- /dev/null
+++ b/target/baremetal/README
@@ -0,0 +1,11 @@
+Bare-metal examples inspired from http://atose.org/?p=141
+
+Initial purpose is to create small bare-metal programs to test AMP on i.MX6
+but these examples can also be used as a start base for the ones who don't want
+to run an OS on their APF6 modules...
+
+imx6.ld linker script is configured to build a program launchable from i.MX6
+internal SRAM (0x910080).
+
+For more infos:
+http://www.armadeus.com/wiki/index.php?title=APF6_Bare-metal_programming
diff --git a/target/baremetal/apf6dev_led.c b/target/baremetal/apf6dev_led.c
new file mode 100644
index 0000000..5a845f5
--- /dev/null
+++ b/target/baremetal/apf6dev_led.c
@@ -0,0 +1,36 @@
+#include <stdint.h>
+
+#ifdef DEBUG
+#include "imx6_uart.h"
+#endif
+
+#define GPIO7_DR (*(volatile uint32_t *)0x020b4000)
+#define GPIO7_GDIR (*(volatile uint32_t *)0x020b4004)
+#define GPIO_PIN12 (1 << 12)
+
+void apf6dev_userled_init(void)
+{
+ uint32_t reg;
+
+#ifdef DEBUG
+ debug_puts("led init\r\n");
+#endif
+ reg = GPIO7_GDIR;
+ reg |= GPIO_PIN12;
+ GPIO7_GDIR = reg;
+}
+
+void apf6dev_userled_set(int state)
+{
+ uint32_t reg;
+
+ if (state) {
+ reg = GPIO7_DR;
+ reg |= GPIO_PIN12;
+ GPIO7_DR = reg;
+ } else {
+ reg = GPIO7_DR;
+ reg &= ~GPIO_PIN12;
+ GPIO7_DR = reg;
+ }
+}
diff --git a/target/baremetal/apf6dev_led.h b/target/baremetal/apf6dev_led.h
new file mode 100644
index 0000000..8171ef7
--- /dev/null
+++ b/target/baremetal/apf6dev_led.h
@@ -0,0 +1,3 @@
+
+void apf6dev_userled_init(void);
+void apf6dev_userled_set(int state);
diff --git a/target/baremetal/imx6.ld b/target/baremetal/imx6.ld
new file mode 100644
index 0000000..b82eff0
--- /dev/null
+++ b/target/baremetal/imx6.ld
@@ -0,0 +1,21 @@
+/*
+ Inspired from imx6q.ld (http://atose.org/?p=141), which is:
+ Copyright (c) 2013 Andrew Trotman
+ Open Source under the BSD License.
+*/
+
+ENTRY(_Reset)
+
+SECTIONS
+{
+ . = 0x910080;
+ . = ALIGN(4);
+
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+
+ . = ALIGN(4);
+ . = . + 0x1000; /* 4kB of stack memory */
+ stack_top = .;
+}
diff --git a/target/baremetal/imx6_epit.c b/target/baremetal/imx6_epit.c
new file mode 100644
index 0000000..3b204f0
--- /dev/null
+++ b/target/baremetal/imx6_epit.c
@@ -0,0 +1,86 @@
+/*
+ Inspired from imx6q_uart.c (http://atose.org/?p=141), which is:
+ Copyright (c) 2012-2013 Andrew Trotman
+ Licensed BSD
+*/
+
+#include <stdint.h>
+
+#ifdef DEBUG
+#include "imx6_uart.h"
+#endif
+
+#define CCM_CCGR1 (*(volatile uint32_t *)0x020c406c)
+#define CCGR1_CG6 (0x03 << 12)
+#define PRE_PERIPH_CLK_SEL (0x03 << 18)
+#define CCM_CBCDR (*(volatile uint32_t *)0x020c4014)
+#define AHB_PODF (0x7 << 10)
+#define IPG_PODF (0x3 << 8)
+#define CCM_CBCMR (*(volatile uint32_t *)0x020c4018)
+
+#define EPIT1_BASE (0x020d0000)
+#define EPIT1(REG) (*(volatile uint32_t *)(EPIT1_BASE + REG))
+#define EPIT1_WR(REG, VAL) (*(volatile uint32_t *)(EPIT1_BASE + REG) = VAL)
+#define CR (0x00)
+#define CR_SWR (1 << 16)
+#define CR_CLKSRC(x) (((x) & 0x3) << 24)
+#define CR_PRESCALAR(x) (((x) & 0xfff) << 4)
+#define CR_IOVW (1 << 17)
+#define CR_RLD (1 << 3)
+#define CR_ENMOD (1 << 1)
+#define CR_EN (1 << 0)
+#define SR (0x04)
+#define SR_OCIF (1 << 0)
+#define LR (0x08)
+
+void epit_init(void)
+{
+ uint32_t speed_in_Hz[] = {528000000, 396000000, 307000000 /*352000000*/, 198000000, 594000000};
+ uint32_t frequency;
+
+#ifdef DEBUG
+ debug_puts("epit_init \r\n");
+#endif
+ //CCM_CCGR1 = (CCM_CCGR1 | CCGR1_CG6); // turn on the clock
+
+ /* Software reset the subsystem */
+ EPIT1_WR(CR, CR_SWR);
+ while ((EPIT1(CR) & CR_SWR) != 0)
+ ; /* Wait end of reset */
+
+ /*
+ Configure the timer:
+ Use the peripheral clock
+ Set and forget mode
+ Immediate load starting with the value in the load register
+ */
+ /*frequency = 528000000 */
+ frequency = speed_in_Hz[((CCM_CBCMR & PRE_PERIPH_CLK_SEL) >> 18) & 0x3] /
+ (((CCM_CBCDR & AHB_PODF) >> 10) + 1) / (((CCM_CBCDR & IPG_PODF) >> 8) + 1);
+ EPIT1_WR(CR, CR_CLKSRC(1) | CR_PRESCALAR((frequency / 1000000) - 1) | CR_RLD | CR_IOVW | CR_ENMOD);
+}
+
+static void epit_start(uint32_t time_in_us)
+{
+ /* Store the count value in the load register (which then gets immediately loaded into the timer */
+ EPIT1_WR(LR, time_in_us);
+
+ /* Clear the status register so that we can watch it clock over */
+ EPIT1_WR(SR, /*EPIT1(SR) &*/ SR_OCIF);
+
+ /* Start the timer */
+ EPIT1_WR(CR, 0x0102041b /*EPIT1(CR) & CR_EN*/); // SET macro ?
+}
+
+static void epit_stop(void)
+{
+ EPIT1_WR(CR, 0x0102041a /*EPIT1(CR) | ~CR_EN*/); // CLR macro ?
+}
+
+void epit_delay_us(uint32_t usecs)
+{
+ epit_start(usecs);
+ while (EPIT1(SR) == 0)
+ ;
+ epit_stop();
+}
diff --git a/target/baremetal/imx6_epit.h b/target/baremetal/imx6_epit.h
new file mode 100644
index 0000000..38e3c9a
--- /dev/null
+++ b/target/baremetal/imx6_epit.h
@@ -0,0 +1,4 @@
+
+void epit_init(void);
+void epit_delay_us(uint32_t usecs);
+
diff --git a/target/baremetal/imx6_led_blink.c b/target/baremetal/imx6_led_blink.c
new file mode 100644
index 0000000..0ee8e1b
--- /dev/null
+++ b/target/baremetal/imx6_led_blink.c
@@ -0,0 +1,49 @@
+/*
+ Inspired from imx6q_uart.c (http://atose.org/?p=141) which is:
+ Copyright (c) 2012-2013 Andrew Trotman
+ Licensed BSD
+*/
+
+#include <stdint.h>
+
+#include "imx6_uart.h"
+#include "imx6_epit.h"
+#include "apf6dev_led.h"
+
+void enable_pins(void)
+{
+ /* If not launched from U-Boot, here should be defined the IOMUX
+ configuration for used GPIOs and UART */
+}
+
+void enable_clocks(void)
+{
+ /* If not launched from U-Boot, here should be defined the clock
+ configuration for UART and EPIT */
+}
+
+#define DELAY_US 500000 /* 0.5 secs */
+
+int main(void)
+{
+ int i = 20;
+
+ enable_clocks();
+ enable_pins();
+ serial_init();
+ epit_init();
+ apf6dev_userled_init();
+
+ epit_delay_us(DELAY_US);
+ debug_puts("\r\nExample led_blink compiled on " __DATE__ " at " __TIME__ "\r\n");
+
+ /* Infinite loop */
+ while (i != 0) {
+ apf6dev_userled_set(1);
+ epit_delay_us(DELAY_US);
+ apf6dev_userled_set(0);
+ epit_delay_us(DELAY_US);
+ }
+
+ return 0;
+}
diff --git a/target/baremetal/imx6_uart.c b/target/baremetal/imx6_uart.c
new file mode 100644
index 0000000..d5a478f
--- /dev/null
+++ b/target/baremetal/imx6_uart.c
@@ -0,0 +1,103 @@
+/*
+ Inspired from imx6q_uart.c (http://atose.org/?p=141), which is:
+ Copyright (c) 2012-2013 Andrew Trotman
+ Licensed BSD
+*/
+
+#include <stdint.h>
+
+#define BAUD_RATE 115200
+#define DEFAULT_UART 4 /* Console on APF6Dev */
+
+static volatile unsigned long *uart4_utxd = (unsigned long *)0x021f0040;
+static volatile unsigned long *uart4_usr2 = (unsigned long *)0x021f0098;
+#define B_USR2_TXFE (1 << 14)
+
+void debug_putc(char value)
+{
+ /* Write to the serial port */
+ *uart4_utxd = value;
+
+ /* Make sure it was sent */
+ while ((*uart4_usr2 & B_USR2_TXFE) == 0)
+ ; /* do nothing */
+}
+
+void debug_puts(char *string)
+{
+ while (*string != 0)
+ debug_putc(*string++);
+}
+
+#if 0
+char debug_getc(void)
+{
+/*
+ Wait for a character to arrive
+*/
+ while ((HW_UART_USR2(DEFAULT_UART).B.RDR) == 0)
+ ; // do nothing
+
+/*
+ Get it and put it into the array
+*/
+ return HW_UART_URXD_RD(DEFAULT_UART) & 0xFF;
+}
+#endif
+
+#define PLL3_FREQUENCY 80000000
+
+void serial_init(void)
+{
+#if 0
+TBDL !!!
+/*
+ Disable and soft reset the UART then wait for it to come up
+*/
+HW_UART_UCR1(DEFAULT_UART).U = 0; // disable the UART
+HW_UART_UCR2(DEFAULT_UART).U = 0; // software reset (SRST)
+while (HW_UART_UCR2(DEFAULT_UART).B.SRST == 0)
+ ; // nothing
+
+/*
+ Enable the UART
+ Enable RXDMUXSEL (must be on)
+*/
+HW_UART_UCR1(DEFAULT_UART).B.UARTEN = 1;
+HW_UART_UCR3(DEFAULT_UART).B.RXDMUXSEL = 1;
+
+/*
+ 8 bits, 1 stop bit, no parity,software flow control
+*/
+/* 8-bits ignore RTS enable RX enable TX don't reset */
+HW_UART_UCR2_WR(DEFAULT_UART, BM_UART_UCR2_WS | BM_UART_UCR2_IRTS | BM_UART_UCR2_RXEN | BM_UART_UCR2_TXEN | BM_UART_UCR2_SRST);
+
+/*
+ Set the board rate
+
+ The "Module Clock" is the UART_CLK which comes from CCM.
+ The "Peripheral Clock" is the IPG_CLK which comes from CCM.
+
+ PLL3 runs at 80MHz by default
+ PLL3 -> CDCDR1:uart_clk_podf (6 bit divider) -> UART_CLK_ROOT
+*/
+
+/*
+ Divide the clock by 2
+*/
+HW_UART_UFCR(DEFAULT_UART).B.RFDIV = 0x04; /* divide input clock by 2 */
+HW_UART_UFCR(DEFAULT_UART).B.DCEDTE = 0; /* DCE mode */
+
+
+/*
+ Binary Rate Multiplier Numerator = 0x0F
+*/
+HW_UART_UBIR(DEFAULT_UART).U = 0x0F;
+
+/*
+ Binary Rate Multipier Denominator set based on the baud rate
+*/
+HW_UART_UBMR(DEFAULT_UART).U = (PLL3_FREQUENCY / (HW_CCM_CSCDR1.B.UART_CLK_PODF + 1)) / (2 * BAUD_RATE); // UBMR should be 0x015B once set
+#endif
+}
+
diff --git a/target/baremetal/imx6_uart.h b/target/baremetal/imx6_uart.h
new file mode 100644
index 0000000..bb320f5
--- /dev/null
+++ b/target/baremetal/imx6_uart.h
@@ -0,0 +1,4 @@
+void debug_putc(char value);
+void debug_puts(char *string);
+char debug_getc(void);
+void serial_init(void);
diff --git a/target/baremetal/start.s b/target/baremetal/start.s
new file mode 100644
index 0000000..3947578
--- /dev/null
+++ b/target/baremetal/start.s
@@ -0,0 +1,15 @@
+/*
+ Inspired from imx6q.s (http://atose.org/?p=141), which is:
+ Copyright (c) 2013 Andrew Trotman
+ Open Source under the BSD License.
+*/
+
+.global _Reset
+
+/*
+ RESET_HANDLER
+ -------------
+*/
+_Reset:
+ ldr sp, =stack_top
+ b main
hooks/post-receive
--
armadeus
|