From 9a3655a43358c43128f6e62c8d74ff3aa81960c7 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 25 Jan 2019 01:46:07 +0200 Subject: [PATCH 1/1] forgotten files --- install | 5 +++ src/asm.h | 13 ++++++++ src/gpio.h | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/serial.c | 54 ++++++++++++++++++++++++++++++++ src/serial.h | 11 +++++++ src/uart.h | 69 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 251 insertions(+) create mode 100755 install create mode 100644 src/asm.h create mode 100644 src/gpio.h create mode 100644 src/serial.c create mode 100644 src/serial.h create mode 100644 src/uart.h diff --git a/install b/install new file mode 100755 index 0000000..837479c --- /dev/null +++ b/install @@ -0,0 +1,5 @@ +#!/bin/sh + +mount /media/usbmass && \ + cp rpikern.bin /media/usbmass/kernel7.img && \ + umount /media/usbmass && sync diff --git a/src/asm.h b/src/asm.h new file mode 100644 index 0000000..61d29ac --- /dev/null +++ b/src/asm.h @@ -0,0 +1,13 @@ +#ifndef ASM_H_ +#define ASM_H_ + +#define enable_intr() asm volatile ("cpsie i") +#define disable_intr() asm volatile ("cpsid i") +#define mem_barrier() asm volatile ("dmb" ::: "memory") + +#define delay(x) asm volatile ( \ + "0: subs %0, %0, #1\n\t" \ + "bne 0b\n\t" \ + :: "r"(x) : "cc") + +#endif /* ASM_H_ */ diff --git a/src/gpio.h b/src/gpio.h new file mode 100644 index 0000000..19ca6c3 --- /dev/null +++ b/src/gpio.h @@ -0,0 +1,99 @@ +#ifndef GPIO_H_ +#define GPIO_H_ + +#include "asm.h" + +#define GPIO_BASE 0x3f200000 +#define GPIO_REG(x) (*(volatile uint32_t*)(GPIO_BASE | (x))) + +/* function select */ +#define REG_GPFSEL(x) GPIO_REG((x) << 2) +#define REG_GPFSEL0 GPIO_REG(0x00) +#define REG_GPFSEL1 GPIO_REG(0x04) +#define REG_GPFSEL2 GPIO_REG(0x08) +#define REG_GPFSEL3 GPIO_REG(0x0c) +#define REG_GPFSEL4 GPIO_REG(0x10) +#define REG_GPFSEL5 GPIO_REG(0x14) +/* pin output set */ +#define REG_GPSET0 GPIO_REG(0x1c) +#define REG_GPSET1 GPIO_REG(0x20) +/* pin output clear */ +#define REG_GPCLR0 GPIO_REG(0x28) +#define REG_GPCLR1 GPIO_REG(0x2c) +/* pin level */ +#define REG_GPLEV0 GPIO_REG(0x34) +#define REG_GPLEV1 GPIO_REG(0x38) +/* pin event detect status */ +#define REG_GPEDS0 GPIO_REG(0x40) +#define REG_GPEDS1 GPIO_REG(0x44) +/* pin rising edge detect enable */ +#define REG_GPREN0 GPIO_REG(0x4c) +#define REG_GPREN1 GPIO_REG(0x50) +/* pin falling edge detect enable */ +#define REG_GPFEN0 GPIO_REG(0x58) +#define REG_GPFEN1 GPIO_REG(0x5c) +/* pin high detect enable */ +#define REG_GPHEN0 GPIO_REG(0x64) +#define REG_GPHEN1 GPIO_REG(0x68) +/* pin low detect enable */ +#define REG_GPLEN0 GPIO_REG(0x70) +#define REG_GPLEN1 GPIO_REG(0x74) +/* pin async rising edge detect */ +#define REG_GPAREN0 GPIO_REG(0x7c) +#define REG_GPAREN1 GPIO_REG(0x80) +/* pin async falling edge detect */ +#define REG_GPAFEN0 GPIO_REG(0x88) +#define REG_GPAFEN1 GPIO_REG(0x8c) +/* pin pull-up/down enable */ +#define REG_GPPUD GPIO_REG(0x94) +/* pin pull-up/down enable clock */ +#define REG_GPPUDCLK0 GPIO_REG(0x98) +#define REG_GPPUDCLK1 GPIO_REG(0x9c) + +/* function select bits */ +#define FSEL_IN 0 +#define FSEL_OUT 1 +#define FSEL_ALT0 4 +#define FSEL_ALT1 5 +#define FSEL_ALT2 6 +#define FSEL_ALT3 7 +#define FSEL_ALT4 3 +#define FSEL_ALT5 2 + +/* pull-up/down bits */ +#define PUD_DISABLE 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +static inline void gpio_fsel(int x, int f) +{ + static const unsigned int fseltab[54][2] = { + {0, 0}, {0, 3}, {0, 6}, {0, 9}, {0, 12}, {0, 15}, {0, 18}, {0, 21}, {0, 24}, {0, 27}, + {4, 0}, {4, 3}, {4, 6}, {4, 9}, {4, 12}, {4, 15}, {4, 18}, {4, 21}, {4, 24}, {4, 27}, + {8, 0}, {8, 3}, {8, 6}, {8, 9}, {8, 12}, {8, 15}, {8, 18}, {8, 21}, {8, 24}, {8, 27}, + {12, 0}, {12, 3}, {12, 6}, {12, 9}, {12, 12}, {12, 15}, {12, 18}, {12, 21}, {12, 24}, {12, 27}, + {16, 0}, {16, 3}, {16, 6}, {16, 9}, {16, 12}, {16, 15}, {16, 18}, {16, 21}, {16, 24}, {16, 27}, + {20, 0}, {20, 3}, {20, 6}, {20, 9} + }; + uint32_t val; + + if(x <= 53) { + val = f << fseltab[x][1]; + *(volatile uint32_t*)(GPIO_BASE | fseltab[x][0]) = val; + } +} + +static inline void gpio_pullups(uint32_t mask0, uint32_t mask1, int state) +{ + REG_GPPUD = state; + delay(150); + + if(mask0) REG_GPPUDCLK0 = mask0; + if(mask1) REG_GPPUDCLK1 = mask1; + delay(150); + + if(mask0) REG_GPPUDCLK0 = 0; + if(mask1) REG_GPPUDCLK1 = 0; +} + +#endif /* GPIO_H_ */ diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..ddd5923 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,54 @@ +#include +#include "serial.h" +#include "uart.h" +#include "gpio.h" + +/* baud rate: BAUDDIV = (UART_CLK / (16 * baud)) */ +#define UART_CLK 3000000 + +void init_serial(int baud) +{ + uint32_t bdiv_fp6; + + REG_CR = 0; /* disable UART */ + + /* disable pullups for GPIO 14 & 15 */ + gpio_pullups(0xc000, 0, PUD_DISABLE); + + REG_ICR = 0; /* clear pending interrupts */ + + /* calculate baud rate divisor */ + bdiv_fp6 = (UART_CLK << 6) / (16 * baud); + REG_IBRD = (bdiv_fp6 >> 6) & 0xffff; /* 16 bits integer part */ + REG_FBRD = bdiv_fp6 & 0x3f; /* 6 bits fractional precision */ + + /* line control: fifo enable, 8n1 */ + REG_LCRH = LCRH_FIFOEN | LCRH_8BITS; + /* mask all interrupts */ + REG_IMSC = I_CTS | I_RX | I_TX | I_RTIME | I_FRM | I_PAR | I_BRK | I_OVR; + + /* enable UART RX&TX */ + REG_CR = CR_UARTEN | CR_TXEN | CR_RXEN; +} + +void ser_putchar(int c) +{ + while(REG_FR & FR_TXFF); + REG_DR = c & 0xff; +} + +int ser_getchar(void) +{ + while(REG_FR & FR_RXFE); + return REG_DR & 0xff; +} + +void ser_printstr(const char *s) +{ + while(*s) { + if(*s == '\n') { + ser_putchar('\r'); + } + ser_putchar(*s++); + } +} diff --git a/src/serial.h b/src/serial.h new file mode 100644 index 0000000..785457e --- /dev/null +++ b/src/serial.h @@ -0,0 +1,11 @@ +#ifndef SERIAL_H_ +#define SERIAL_H_ + +void init_serial(int baud); + +void ser_putchar(int c); +int ser_getchar(void); + +void ser_printstr(const char *s); + +#endif /* SERIAL_H_ */ diff --git a/src/uart.h b/src/uart.h new file mode 100644 index 0000000..ade162e --- /dev/null +++ b/src/uart.h @@ -0,0 +1,69 @@ +#ifndef UART_PL011_H_ +#define UART_PL011_H_ + +#define UART0_BASE 0x3f201000 +#define UART0_REG(x) *(volatile uint32_t*)(UART0_BASE | (x)) + +#define REG_DR UART0_REG(0x00) /* data register */ +#define REG_RSRECR UART0_REG(0x04) /* receive status & error clear */ +#define REG_FR UART0_REG(0x18) /* flag register */ +#define REG_IBRD UART0_REG(0x24) /* integer baud rate divisor (low 16 bits) */ +#define REG_FBRD UART0_REG(0x28) /* fractional baud rate divisor (low 6 (six) bits) */ +#define REG_LCRH UART0_REG(0x2c) /* line control */ +#define REG_CR UART0_REG(0x30) /* control register */ +#define REG_IFLS UART0_REG(0x34) /* interrupt FIFO level select */ +#define REG_IMSC UART0_REG(0x38) /* interrupt mask set clear */ +#define REG_RIS UART0_REG(0x3c) /* raw interrupt status */ +#define REG_MIS UART0_REG(0x40) /* masked interrupt status */ +#define REG_ICR UART0_REG(0x44) /* interrupt clear */ + +/* error bits in REG_DR */ +#define DR_FRM 0x0100 +#define DR_PAR 0x0200 +#define DR_BRK 0x0400 +#define DR_OVR 0x0800 + +/* receive status error bits */ +#define RCR_FRM 0x01 +#define RCR_PAR 0x02 +#define RCR_BRK 0x04 +#define RCR_OVR 0x08 + +/* flag register bits */ +#define FR_CTS 0x01 +#define FR_BUSY 0x08 +#define FR_RXFE 0x10 /* receive FIFO empty */ +#define FR_TXFF 0x20 /* transmit FIFO full */ +#define FR_RXFF 0x40 /* receive FIFO full */ +#define FR_TXFE 0x80 /* transmit FIFO empty */ + +/* line control register bits */ +#define LCRH_BRK 0x01 /* send break */ +#define LCRH_PAREN 0x02 +#define LCRH_PAREVEN 0x04 +#define LCRH_STOP2 0x08 +#define LCRH_FIFOEN 0x10 +#define LCRH_8BITS 0x60 +#define LCRH_7BITS 0x40 +#define LCRH_STICKPAR 0x80 /* ? */ + +/* control register bits */ +#define CR_UARTEN 0x0001 +#define CR_LOOPEN 0x0080 +#define CR_TXEN 0x0100 +#define CR_RXEN 0x0200 +#define CR_RTS 0x0800 +#define CR_RTSEN 0x4000 +#define CR_CTSEN 0x8000 + +/* interrupt bits for IMSC, RIS, ICR */ +#define I_CTS 0x0002 +#define I_RX 0x0010 +#define I_TX 0x0020 +#define I_RTIME 0x0040 +#define I_FRM 0x0080 +#define I_PAR 0x0100 +#define I_BRK 0x0200 +#define I_OVR 0x0400 + +#endif /* UART_PL011_H_ */ -- 1.7.10.4