-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Raspberry Pi3 Uart #496
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,23 +18,209 @@ | |
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA | ||
*/ | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
#include <target.h> | ||
#include "image.h" | ||
#include "printf.h" | ||
#ifndef ARCH_AARCH64 | ||
# error "wolfBoot raspi3 HAL: wrong architecture selected. Please compile with ARCH=AARCH64." | ||
#endif | ||
|
||
#define TEST_ENCRYPT | ||
|
||
#if defined(DEBUG_UART) | ||
#define PRINTF_ENABLED | ||
#endif | ||
|
||
|
||
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014 | ||
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999 | ||
|
||
#define MMIO_BASE 0x3F000000 | ||
|
||
#define GPIO_BASE MMIO_BASE + 0x200000 | ||
|
||
#define GPFSEL1 ((volatile unsigned int*)(GPIO_BASE+0x04)) | ||
#define GPPUD ((volatile unsigned int*)(GPIO_BASE+0x94)) | ||
#define GPPUDCLK0 ((volatile unsigned int*)(GPIO_BASE+0x98)) | ||
|
||
/* PL011 UART registers */ | ||
#define UART0_BASE GPIO_BASE + 0x1000 | ||
#define UART0_DR ((volatile unsigned int*)(UART0_BASE+0x00)) | ||
#define UART0_FR ((volatile unsigned int*)(UART0_BASE+0x18)) | ||
#define UART0_IBRD ((volatile unsigned int*)(UART0_BASE+0x24)) | ||
#define UART0_FBRD ((volatile unsigned int*)(UART0_BASE+0x28)) | ||
#define UART0_LCRH ((volatile unsigned int*)(UART0_BASE+0x2C)) | ||
#define UART0_CR ((volatile unsigned int*)(UART0_BASE+0x30)) | ||
#define UART0_IMSC ((volatile unsigned int*)(UART0_BASE+0x38)) | ||
#define UART0_ICR ((volatile unsigned int*)(UART0_BASE+0x44)) | ||
|
||
/* mail box message buffer */ | ||
volatile unsigned int __attribute__((aligned(16))) mbox[36]; | ||
|
||
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880) | ||
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0)) | ||
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) | ||
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14)) | ||
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18)) | ||
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C)) | ||
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20)) | ||
#define MBOX_RESPONSE 0x80000000 | ||
#define MBOX_FULL 0x80000000 | ||
#define MBOX_EMPTY 0x40000000 | ||
|
||
#define MBOX_REQUEST 0 | ||
|
||
/* channels */ | ||
#define MBOX_CH_POWER 0 | ||
#define MBOX_CH_FB 1 | ||
#define MBOX_CH_VUART 2 | ||
#define MBOX_CH_VCHIQ 3 | ||
#define MBOX_CH_LEDS 4 | ||
#define MBOX_CH_BTNS 5 | ||
#define MBOX_CH_TOUCH 6 | ||
#define MBOX_CH_COUNT 7 | ||
#define MBOX_CH_PROP 8 | ||
|
||
/* tags */ | ||
#define MBOX_TAG_GETBRDVERSION 0x10002 | ||
#define MBOX_TAG_GETSERIAL 0x10004 | ||
#define MBOX_TAG_GET_CLOCK_RATE 0x30002 | ||
#define MBOX_TAG_SETCLKRATE 0x38002 | ||
#define MBOX_TAG_LAST 0 | ||
|
||
/* Fixed addresses */ | ||
extern void *kernel_addr, *update_addr, *dts_addr; | ||
/* Loop <delay> times */ | ||
static inline void delay(int32_t count) | ||
{ | ||
register unsigned int c; | ||
c = count; | ||
while (c--) { | ||
asm volatile("nop"); | ||
} | ||
} | ||
/** | ||
* write message to mailbox | ||
*/ | ||
static void mailbox_write(uint8_t chan) | ||
{ | ||
uint32_t ch = (((uint32_t)((unsigned long)&mbox) & ~0xf) | ||
| (chan & 0xf)); | ||
|
||
/* wait until mail box becomes ready to write */ | ||
while ((*MBOX_STATUS & MBOX_FULL) != 0) { } | ||
|
||
/* write the address of the message to mail-box channel */ | ||
*MBOX_WRITE = ch; | ||
} | ||
/** | ||
* read message from mailbox | ||
*/ | ||
static int mailbox_read(uint8_t chan) | ||
{ | ||
uint32_t ch = (((uint32_t)((unsigned long)&mbox) & ~0xf) | ||
| (chan & 0xf)); | ||
/* now wait for the response */ | ||
while(1) { | ||
while ((*MBOX_STATUS & MBOX_EMPTY) != 0) { } | ||
if(ch == *MBOX_READ) | ||
/* is it a valid successful response */ | ||
return mbox[1] == MBOX_RESPONSE; | ||
} | ||
return 0; | ||
} | ||
|
||
/* UART functions for Raspberry Pi 3 UART */ | ||
void uart_tx(char c) | ||
{ | ||
/* wait until uart channel is ready to send */ | ||
do{ | ||
asm volatile("nop"); | ||
} while(*UART0_FR & 0x20); | ||
*UART0_DR = c; | ||
} | ||
|
||
char uart_read(void) | ||
{ | ||
char c; | ||
/* wait until data is comming */ | ||
do{ | ||
asm volatile("nop"); | ||
} while(*UART0_FR & 0x10); | ||
/* read it and return */ | ||
c = (char)(*UART0_DR); | ||
/* convert carrige return to newline */ | ||
if (c == '\r') | ||
c = '\n'; | ||
|
||
return c; | ||
} | ||
|
||
/** | ||
* Send string to UART | ||
*/ | ||
void uart_write(const char* buf, uint32_t sz) { | ||
uint32_t len = sz; | ||
|
||
while (len > 0 && *buf) { | ||
/* convert newline to carrige return + newline */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spelling, plus conversion from CR to CR+LF, that should be handled by the caller, or left as is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Agree. Carriage return code should be handled by the caller. |
||
if (*buf == '\n') | ||
uart_tx('\r'); | ||
|
||
uart_tx(*buf++); | ||
len--; | ||
} | ||
} | ||
|
||
void uart_init() | ||
{ | ||
register unsigned int c; | ||
|
||
/* initialize UART. turn off UART 0*/ | ||
*UART0_CR = 0; | ||
|
||
/* set up clock for consistent divisor values */ | ||
mbox[0] = 9 * 4; | ||
mbox[1] = MBOX_REQUEST; | ||
/* tag for setting clock rate */ | ||
mbox[2] = MBOX_TAG_SETCLKRATE; | ||
mbox[3] = 12; | ||
mbox[4] = 8; | ||
/* specify UART clock channel */ | ||
mbox[5] = 2; | ||
/* UART clock rate in hz(4Mhz)*/ | ||
mbox[6] = 4000000; | ||
/* not use turbo */ | ||
mbox[7] = 0; | ||
mbox[8] = MBOX_TAG_LAST; | ||
|
||
mailbox_write(MBOX_CH_PROP); | ||
mailbox_read(MBOX_CH_PROP); | ||
|
||
/* disable pull up/down for all GPIO pins */ | ||
*GPPUD = 0; | ||
delay(150); | ||
/* Disable pull up/down for pin 14 and 15 */ | ||
*GPPUDCLK0 = (1<<14)|(1<<15); | ||
delay(150); | ||
/* flush GPIO setting to make it take effect */ | ||
*GPPUDCLK0 = 0; | ||
|
||
/* clear pending interrupts */ | ||
*UART0_ICR = 0x7FF; | ||
/* select 115200 baud rate */ | ||
/* divider = 4000000 / (16 * 115200) = 2.17 = ~2 */ | ||
*UART0_IBRD = 2; | ||
/* Fractional part register = (.17013 * 64) + 0.5 = 11.38 = ~11 */ | ||
*UART0_FBRD = 0xB; | ||
/* Enable fifo, 8bit data transmission ( 1stop bit, no parity) */ | ||
*UART0_LCRH = (1 << 4) | (1 << 5) | (1 << 6); | ||
/* enable UART0 transfer & receive*/ | ||
*UART0_CR = (1 << 0) | (1 << 8) | (1 << 9); | ||
} | ||
|
||
void* hal_get_primary_address(void) | ||
{ | ||
|
@@ -91,22 +277,88 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq) | |
{ | ||
} | ||
|
||
|
||
void zynq_init(uint32_t cpu_clock) | ||
{ | ||
} | ||
|
||
#if defined(DISPLAY_CLOCKS) | ||
static uint32_t getclocks(uint8_t cid) | ||
{ | ||
/* Retrive clock rate */ | ||
/* length of the message */ | ||
mbox[0] = 8 * 4; | ||
mbox[1] = MBOX_REQUEST; | ||
/* tag for get board version */ | ||
mbox[2] = MBOX_TAG_GET_CLOCK_RATE; | ||
/* buffer size */ | ||
mbox[3] = 8; | ||
mbox[4] = 8; | ||
/* clock id CORE*/ | ||
mbox[5] = cid; | ||
/* clock frequency */ | ||
mbox[6] = 0; | ||
mbox[7] = MBOX_TAG_LAST; | ||
mailbox_write(MBOX_CH_PROP); | ||
|
||
if (mailbox_read(MBOX_CH_PROP)) { | ||
return mbox[6]; | ||
} | ||
else { | ||
return 0; | ||
} | ||
} | ||
#endif /* DISPLAY clocks */ | ||
|
||
/* public HAL functions */ | ||
void hal_init(void) | ||
{ | ||
#if defined(TEST_ENCRYPT) && defined (EXT_ENCRYPTED) | ||
char enc_key[] = "0123456789abcdef0123456789abcdef" | ||
"0123456789abcdef"; | ||
"0123456789abcdef"; | ||
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32)); | ||
#endif | ||
|
||
uart_init(); | ||
|
||
/* length of the message */ | ||
mbox[0] = 7 * 4; | ||
mbox[1] = MBOX_REQUEST; | ||
/* tag for get board version */ | ||
mbox[2] = MBOX_TAG_GETBRDVERSION; | ||
/* buffer size */ | ||
mbox[3] = 4; | ||
mbox[4] = 0; | ||
mbox[5] = 0; | ||
mbox[6] = MBOX_TAG_LAST; | ||
|
||
/* send the message to the GPU */ | ||
mailbox_write(MBOX_CH_PROP); | ||
|
||
if (mailbox_read(MBOX_CH_PROP)) { | ||
wolfBoot_printf("My board version is: 0x%08x", mbox[5]); | ||
wolfBoot_printf("\n"); | ||
} else { | ||
wolfBoot_printf("Unable to query board version!\n"); | ||
} | ||
|
||
#if defined(DISPLAY_CLOCKS) && defined(PRINTF_ENABLED) | ||
/* Get clocks */ | ||
wolfBoot_printf("\n EMMC clock : %d Hz", getclocks(1)); | ||
wolfBoot_printf("\n UART clock : %d Hz", getclocks(2)); | ||
wolfBoot_printf("\n ARM clock : %d Hz", getclocks(3)); | ||
wolfBoot_printf("\n CORE clock : %d Hz", getclocks(4)); | ||
wolfBoot_printf("\n V3D clock : %d Hz", getclocks(5)); | ||
wolfBoot_printf("\n H264 clock : %d Hz", getclocks(6)); | ||
wolfBoot_printf("\n ISP clock : %d Hz", getclocks(7)); | ||
wolfBoot_printf("\n SDRAM clock : %d Hz", getclocks(8)); | ||
wolfBoot_printf("\n PIXEL clock : %d Hz", getclocks(9)); | ||
wolfBoot_printf("\n PWM clock : %d Hz", getclocks(10)); | ||
wolfBoot_printf("\n HEVC clock : %d Hz", getclocks(11)); | ||
wolfBoot_printf("\n EMMC2 clock : %d Hz", getclocks(12)); | ||
wolfBoot_printf("\n M2MC clock : %d Hz", getclocks(13)); | ||
wolfBoot_printf("\n PIXEL_BVB clock : %d Hz\n", getclocks(14)); | ||
#endif | ||
|
||
} | ||
|
||
void hal_prepare_boot(void) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spelling: carriage. Is this conversion really required?