Triss 8 months ago
commit
e9f3dda982
  1. 5
      .gitignore
  2. 30
      Makefile
  3. 40
      README.md
  4. 58
      arm926ejs_fx3.cfg
  5. 33
      bsp/cache.c
  6. 54
      bsp/cache.h
  7. 210
      bsp/dma.c
  8. 73
      bsp/dma.h
  9. 77
      bsp/fx3.ld
  10. 69
      bsp/gctl.c
  11. 54
      bsp/gctl.h
  12. 220
      bsp/gpif.c
  13. 237
      bsp/gpif.h
  14. 104
      bsp/gpio.c
  15. 89
      bsp/gpio.h
  16. 40
      bsp/irq.c
  17. 64
      bsp/irq.h
  18. 34
      bsp/regaccess.h
  19. 82
      bsp/uart.c
  20. 49
      bsp/uart.h
  21. 699
      bsp/usb.c
  22. 100
      bsp/usb.h
  23. 58
      bsp/util.c
  24. 29
      bsp/util.h
  25. 94
      bsp/vectors.S
  26. 144
      elf2img.py
  27. 146
      main.c
  28. 354
      rdb/dma.h
  29. 357
      rdb/gctl.h
  30. 341
      rdb/generator/convert.py
  31. 19
      rdb/generator/convert.sh
  32. 436
      rdb/gpif.h
  33. 93
      rdb/gpio.h
  34. 147
      rdb/i2c.h
  35. 103
      rdb/i2s.h
  36. 38
      rdb/lpp.h
  37. 119
      rdb/pib.h
  38. 147
      rdb/pport.h
  39. 2
      rdb/readme.txt
  40. 108
      rdb/spi.h
  41. 122
      rdb/uart.h
  42. 1339
      rdb/uib.h
  43. 38
      rdb/uibin.h
  44. 44
      rdb/vic.h

5
.gitignore

@ -0,0 +1,5 @@
*.o
*.d
*.img
*.elf
*.map

30
Makefile

@ -0,0 +1,30 @@
CC = arm-none-eabi-gcc
CGENFLAGS = -mcpu=arm926ej-s -mthumb-interwork -fno-pie
WARN = -Wall -Wextra -Werror
OPTIMIZE = -g -Og
INCLUDE = -I.
GENDEP = -MMD -MP
DEFS = -DPLL_FBDIV=20
CFLAGS = -std=gnu17 $(CGENFLAGS) $(WARN) $(OPTIMIZE) $(INCLUDE) $(GENDEP) $(DEFS)
LDFLAGS = -static -nostartfiles -T bsp/fx3.ld -Wl,-z,max-page-size=4096,-Map,$(basename $@).map
VPATH = bsp
OBJS = main.o usb.o gpif.o gctl.o gpio.o uart.o util.o dma.o irq.o cache.o vectors.o
all : jazelle.img
jazelle.img: jazelle.elf
python3 elf2img.py $< $@
clean :
rm -f jazelle.img jazelle.elf jazelle.map $(OBJS) $(OBJS:.o=.d)
jazelle.elf : $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
-include $(OBJS:.o=.d)

40
README.md

@ -0,0 +1,40 @@
# Jacking (Jazelle hacking (Jean gazelle hacking))
**Jazelle reverse engineering effort**
not the first one, but hopefully one that properly documents some stuff
## Workflow
Currently targetting the Cypress FX3.
### Compiling
```
$ make
```
Needs an `arm-none-eabi` toolchain.
### Running/debugging
#### Setup
```
$ openocd -f ./arm926ejs_fx3.cfg -c "transport select jtag" -c "adapter speed 1000" -c "init"
```
#### Running code
```
$ printf 'reset halt\nload_image jazelle.elf\nexit\n' | nc localhost 4444
gdb -ex 'target extended-remote localhost:3333' -ex 'set $pc=_start' -ex 'b jazelle_exec' -ex c jazelle.elf
```
## Credits
FX3 base code: gratuitously stolen from https://github.com/zeldin/fx3lafw/
Jazelle info this project is based on:
* https://hackspire.org/index.php/Jazelle
* https://github.com/SonoSooS/libjz

58
arm926ejs_fx3.cfg

@ -0,0 +1,58 @@
#
# OpenOCD configuration file for Cypress FX3 (ARM926EJ-S).
#
# FX3 has a standard ARM JTAG TAP and can work with a standard ARM926EJ-S configuration.
#
# The interface selected below is the CY7C65215 based JTAG debug probe. If another
# debug probe is being used, just replace the "interface cy7c65215" line with the
# appropriate interface name.
#
gdb_port 3333
adapter driver openjtag
openjtag_variant cy7c65215
######################################
# Target: CYPRESS FX3 ARM926EJ-S
######################################
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME fx3
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x07926069
}
#delays on reset lines
adapter srst delay 200
jtag_ntrst_delay 200
adapter speed 1000
reset_config trst_and_srst srst_pulls_trst
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
jtag_rclk 3
######################
# Target configuration
######################
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME
#-variant arm926ejs
#adapter speed 1000

33
bsp/cache.c

@ -0,0 +1,33 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/cache.h>
void Fx3CacheEnableCaches(void)
{
Fx3CacheInvalidateICacheAndDCache();
/* Set I and C bit in Control register */
uint32_t creg;
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(creg));
creg |= (1UL << 12) | (1UL << 2);
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" : : "r"(creg));
}

54
bsp/cache.h

@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_CACHE_H_
#define BSP_CACHE_H_
#include <stdint.h>
static inline void Fx3CacheInvalidateICacheAndDCache(void)
{
__asm__ __volatile__("mcr p15, 0, %0, c7, c7, 0" : : "r"(0));
}
static inline void Fx3CacheInvalidateICache(void)
{
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : : "r"(0));
}
static inline void Fx3CacheCleanDCache(void)
{
__asm__ __volatile__("1: mrc p15, 0, r15, c7, c10, 3; bne 1b" ::: "cc");
}
static inline void Fx3CacheCleanDCacheEntry(volatile void *ptr)
{
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 1" : : "r"(((uint32_t)ptr) & ~0x1FUL));
}
static inline void Fx3CacheInvalidateDCacheEntry(volatile void *ptr)
{
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r"(((uint32_t)ptr) & ~0x1FUL));
}
extern void Fx3CacheEnableCaches(void);
#endif /* BSP_CACHE_H_ */

210
bsp/dma.c

@ -0,0 +1,210 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/dma.h>
#include <bsp/regaccess.h>
#include <bsp/cache.h>
#include <bsp/uart.h>
#include <rdb/dma.h>
#define FX3_SCK_STATUS_DEFAULT \
( FX3_SCK_STATUS_SUSP_TRANS | \
FX3_SCK_STATUS_EN_CONS_EVENTS | \
FX3_SCK_STATUS_EN_PROD_EVENTS | \
FX3_SCK_STATUS_TRUNCATE )
static uint16_t Fx3DmaDescriptorFirstUnallocated = 1;
static uint16_t Fx3DmaDescriptorFreeListHead = 0;
uint16_t Fx3DmaAllocateDescriptor(void)
{
uint16_t r;
if ((r = Fx3DmaDescriptorFreeListHead)) {
/* Pick first off free list */
volatile struct Fx3DmaDescriptor *desc = FX3_DMA_DESCRIPTOR(r);
Fx3DmaDescriptorFreeListHead = desc->dscr_chain;
} else if(Fx3DmaDescriptorFirstUnallocated < 768) {
/* Allocate a fresh one */
r = Fx3DmaDescriptorFirstUnallocated++;
}
return r;
}
void Fx3DmaFreeDescriptor(uint16_t d)
{
if (d) {
/* Put on head of free list */
volatile struct Fx3DmaDescriptor *desc = FX3_DMA_DESCRIPTOR(d);
desc->dscr_chain = Fx3DmaDescriptorFreeListHead;
Fx3DmaDescriptorFreeListHead = d;
}
}
void Fx3DmaAbortSocket(uint32_t socket)
{
Fx3ClearReg32(socket + FX3_SCK_STATUS,
FX3_SCK_STATUS_GO_ENABLE |
FX3_SCK_STATUS_WRAPUP);
Fx3WriteReg32(socket + FX3_SCK_INTR, ~0);
while((Fx3ReadReg32(socket + FX3_SCK_STATUS) & FX3_SCK_STATUS_ENABLED))
;
}
static void Fx3DmaFillDescriptor(uint16_t descriptor, uint32_t buffer,
uint32_t sync, uint32_t size,
uint16_t wrchain, uint16_t rdchain)
{
volatile struct Fx3DmaDescriptor *desc = FX3_DMA_DESCRIPTOR(descriptor);
if (!(size & FX3_DSCR_SIZE_BUFFER_SIZE_MASK))
size |= 1UL << FX3_DSCR_SIZE_BUFFER_SIZE_SHIFT;
desc->dscr_buffer = buffer;
desc->dscr_sync = sync;
desc->dscr_size = size;
desc->dscr_chain =
(wrchain << FX3_DSCR_CHAIN_WR_NEXT_DSCR_SHIFT) |
(rdchain << FX3_DSCR_CHAIN_RD_NEXT_DSCR_SHIFT);
Fx3CacheCleanDCacheEntry(desc);
}
static void Fx3DmaTransferStart(uint32_t socket, uint16_t descriptor,
uint32_t status, uint32_t size, uint32_t count)
{
Fx3WriteReg32(socket + FX3_SCK_STATUS, FX3_SCK_STATUS_DEFAULT);
while((Fx3ReadReg32(socket + FX3_SCK_STATUS) & FX3_SCK_STATUS_ENABLED))
;
Fx3WriteReg32(socket + FX3_SCK_STATUS, status);
Fx3WriteReg32(socket + FX3_SCK_INTR, ~0UL);
Fx3WriteReg32(socket + FX3_SCK_DSCR,
(0UL << FX3_SCK_DSCR_DSCR_LOW_SHIFT) |
(0UL << FX3_SCK_DSCR_DSCR_COUNT_SHIFT) |
(descriptor << FX3_SCK_DSCR_DSCR_NUMBER_SHIFT));
Fx3WriteReg32(socket + FX3_SCK_SIZE, size);
Fx3WriteReg32(socket + FX3_SCK_COUNT, count);
Fx3SetReg32(socket + FX3_SCK_STATUS,
FX3_SCK_STATUS_GO_ENABLE);
}
static void Fx3DmaWaitForEvent(uint32_t socket, uint32_t event)
{
for(;;) {
uint32_t status = Fx3ReadReg32(socket + FX3_SCK_INTR);
if (status & FX3_SCK_INTR_ERROR) {
Fx3UartTxString("DMA error\n");
return;
}
if (status & event)
return;
/* timeout? */
}
}
void Fx3DmaFillDescriptorThrough(uint32_t prod_socket, uint32_t cons_socket,
uint16_t descriptor, volatile void *buffer,
uint16_t length, uint16_t wrchain, uint16_t rdchain)
{
Fx3DmaFillDescriptor(descriptor, (uint32_t)buffer,
FX3_DSCR_SYNC_EN_PROD_INT |
FX3_DSCR_SYNC_EN_PROD_EVENT |
(FX3_DMA_SOCKET_IP(prod_socket) << FX3_DSCR_SYNC_PROD_IP_SHIFT) |
(FX3_DMA_SOCKET_SCK(prod_socket) << FX3_DSCR_SYNC_PROD_SCK_SHIFT) |
FX3_DSCR_SYNC_EN_CONS_INT |
FX3_DSCR_SYNC_EN_CONS_EVENT |
(FX3_DMA_SOCKET_IP(cons_socket) << FX3_DSCR_SYNC_CONS_IP_SHIFT) |
(FX3_DMA_SOCKET_SCK(cons_socket) << FX3_DSCR_SYNC_CONS_SCK_SHIFT),
(length + 15) & FX3_DSCR_SIZE_BUFFER_SIZE_MASK,
wrchain, rdchain);
}
void Fx3DmaFillDescriptorRead(uint32_t socket, uint16_t descriptor,
const volatile void *buffer, uint16_t length,
uint16_t chain)
{
Fx3DmaFillDescriptor(descriptor, (uint32_t)buffer,
FX3_DSCR_SYNC_EN_PROD_INT |
FX3_DSCR_SYNC_EN_PROD_EVENT |
(0x3FUL << FX3_DSCR_SYNC_PROD_IP_SHIFT) |
FX3_DSCR_SYNC_EN_CONS_INT |
FX3_DSCR_SYNC_EN_CONS_EVENT |
(FX3_DMA_SOCKET_IP(socket) << FX3_DSCR_SYNC_CONS_IP_SHIFT) |
(FX3_DMA_SOCKET_SCK(socket) << FX3_DSCR_SYNC_CONS_SCK_SHIFT),
(length << FX3_DSCR_SIZE_BYTE_COUNT_SHIFT) |
((length + 15) & FX3_DSCR_SIZE_BUFFER_SIZE_MASK) |
FX3_DSCR_SIZE_BUFFER_OCCUPIED, chain, chain);
}
void Fx3DmaFillDescriptorWrite(uint32_t socket, uint16_t descriptor,
volatile void *buffer, uint16_t length,
uint16_t chain)
{
Fx3DmaFillDescriptor(descriptor, (uint32_t)buffer,
FX3_DSCR_SYNC_EN_PROD_INT |
FX3_DSCR_SYNC_EN_PROD_EVENT |
(FX3_DMA_SOCKET_IP(socket) << FX3_DSCR_SYNC_PROD_IP_SHIFT) |
(FX3_DMA_SOCKET_SCK(socket) << FX3_DSCR_SYNC_PROD_SCK_SHIFT) |
FX3_DSCR_SYNC_EN_CONS_INT |
FX3_DSCR_SYNC_EN_CONS_EVENT |
(0x3FUL << FX3_DSCR_SYNC_CONS_IP_SHIFT),
(length + 15) & FX3_DSCR_SIZE_BUFFER_SIZE_MASK, chain, chain);
}
void Fx3DmaSimpleTransferRead(uint32_t socket, uint16_t descriptor,
const volatile void *buffer, uint16_t length)
{
Fx3DmaFillDescriptorRead(socket, descriptor, buffer, length, 0xFFFFU);
Fx3DmaTransferStart(socket, descriptor,
FX3_SCK_STATUS_DEFAULT | FX3_SCK_STATUS_UNIT, 1, 0);
Fx3DmaWaitForEvent(socket, FX3_SCK_INTR_CONSUME_EVENT);
}
void Fx3DmaSimpleTransferWrite(uint32_t socket, uint16_t descriptor,
volatile void *buffer, uint16_t length)
{
Fx3DmaFillDescriptorWrite(socket, descriptor, buffer, length, 0xFFFFU);
Fx3DmaTransferStart(socket, descriptor,
FX3_SCK_STATUS_DEFAULT | FX3_SCK_STATUS_UNIT, 1, 0);
Fx3DmaWaitForEvent(socket, FX3_SCK_INTR_PRODUCE_EVENT);
}
void Fx3DmaStartProducer(uint32_t socket, uint16_t descriptor,
uint32_t size, uint32_t count)
{
Fx3DmaTransferStart(socket, descriptor,
FX3_SCK_STATUS_SUSP_TRANS |
FX3_SCK_STATUS_EN_PROD_EVENTS |
FX3_SCK_STATUS_TRUNCATE,
size, count);
}
void Fx3DmaStartConsumer(uint32_t socket, uint16_t descriptor,
uint32_t size, uint32_t count)
{
Fx3DmaTransferStart(socket, descriptor,
FX3_SCK_STATUS_SUSP_TRANS |
FX3_SCK_STATUS_EN_CONS_EVENTS |
FX3_SCK_STATUS_TRUNCATE,
size, count);
}

73
bsp/dma.h

@ -0,0 +1,73 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_DMA_H_
#define BSP_DMA_H_
#include <stdint.h>
#define FX3_LPP_DMA_SCK(n) (0xE0008000+((n)<<7))
#define FX3_PIB_DMA_SCK(n) (0xE0018000+((n)<<7))
#define FX3_UIB_DMA_SCK(n) (0xE0038000+((n)<<7))
#define FX3_UIBIN_DMA_SCK(n) (0xE0048000+((n)<<7))
#define FX3_DMA_SOCKET_IP(s) (((s) >> 16) & 0x3FUL)
#define FX3_DMA_SOCKET_SCK(s) (((s) >> 7) & 0xFFUL)
#define FX3_DMA_DESCRIPTOR(n) /* 1 <= n < 768 */ \
((volatile struct Fx3DmaDescriptor *)(void *)(0x40000000 + ((n) << 4)))
#define FX3_LPP_DMA_GLOBL 0xE000FF00
#define FX3_PIB_DMA_GLOBL 0xE001FF00
#define FX3_UIB_DMA_GLOBL 0xE003FF00
#define FX3_UIBIN_DMA_GLOBL 0xE004FF00
struct Fx3DmaDescriptor {
uint32_t dscr_buffer;
uint32_t dscr_sync;
uint32_t dscr_chain;
uint32_t dscr_size;
};
extern uint16_t Fx3DmaAllocateDescriptor(void);
extern void Fx3DmaFreeDescriptor(uint16_t d);
extern void Fx3DmaAbortSocket(uint32_t socket);
extern void Fx3DmaFillDescriptorThrough(uint32_t prod_socket, uint32_t cons_socket,
uint16_t descriptor, volatile void *buffer, uint16_t length,
uint16_t wrchain, uint16_t rdchain);
extern void Fx3DmaFillDescriptorRead(uint32_t socket, uint16_t descriptor,
const volatile void *buffer,
uint16_t length, uint16_t chain);
extern void Fx3DmaFillDescriptorWrite(uint32_t socket, uint16_t descriptor,
volatile void *buffer, uint16_t length,
uint16_t chain);
extern void Fx3DmaSimpleTransferRead(uint32_t socket, uint16_t descriptor,
const volatile void *buffer, uint16_t length);
extern void Fx3DmaSimpleTransferWrite(uint32_t socket, uint16_t descriptor,
volatile void *buffer, uint16_t length);
extern void Fx3DmaStartProducer(uint32_t socket, uint16_t descriptor,
uint32_t size, uint32_t count);
extern void Fx3DmaStartConsumer(uint32_t socket, uint16_t descriptor,
uint32_t size, uint32_t count);
#endif /* BSP_DMA_H_ */

77
bsp/fx3.ld

@ -0,0 +1,77 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
ENTRY(_start)
SECTIONS
{
. = 0x40003000;
/* Stacks in DTCM */
__stack_sys = 0x10002000; /* 6KB */
__stack_undef = 0x10000800; /* 128B */
__stack_abort = 0x10000780; /* 128B */
__stack_firq = 0x10000700; /* 256B */
__stack_irq = 0x10000600; /* 1KB */
__stack_super = 0x10000200; /* 512B */
.text :
{
*(.init*)
*(.text*)
*(.fini*)
*(.rodata*)
*(.eh_frame*)
. = ALIGN(4);
}
.data :
{
*(.init_array*)
*(.fini_array*)
*(.got)
*(.data*)
. = ALIGN(4);
}
.bss :
{
__bss_start__ = .;
*(.bss*)
. = ALIGN(4);
__bss_end__ = .;
}
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
}
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
}
__exidx_end = .;
_end = .;
__heap_end = 0x40040000;
}

69
bsp/gctl.c

@ -0,0 +1,69 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/gctl.h>
#include <bsp/regaccess.h>
#include <bsp/util.h>
#include <rdb/gctl.h>
void Fx3GctlInitClock(void)
{
/* Select minimum scalers for all clocks */
Fx3WriteReg32(FX3_GCTL_CPU_CLK_CFG,
(1UL << FX3_GCTL_CPU_CLK_CFG_MMIO_DIV_SHIFT) |
(1UL << FX3_GCTL_CPU_CLK_CFG_DMA_DIV_SHIFT) |
(3UL << FX3_GCTL_CPU_CLK_CFG_SRC_SHIFT) |
((CPU_DIV - 1UL) << FX3_GCTL_CPU_CLK_CFG_CPU_DIV_SHIFT));
Fx3UtilDelayUs(10);
/* Change PLL feedback divisor if needed */
if (Fx3GetField32(FX3_GCTL_PLL_CFG, FBDIV) != PLL_FBDIV) {
Fx3SetField32(FX3_GCTL_PLL_CFG, FBDIV, PLL_FBDIV);
Fx3UtilDelayUs(10);
while ((Fx3ReadReg32(FX3_GCTL_PLL_CFG) & FX3_GCTL_PLL_CFG_PLL_LOCK) == 0)
;
Fx3UtilDelayUs(10);
}
}
void Fx3GctlInitIoMatrix(Fx3GctlPinAltFunc_t alt_func)
{
/* Disable all GPIO overrides */
Fx3WriteReg32(FX3_GCTL_GPIO_SIMPLE, 0);
Fx3WriteReg32(FX3_GCTL_GPIO_SIMPLE+4, 0);
Fx3WriteReg32(FX3_GCTL_GPIO_COMPLEX, 0);
Fx3WriteReg32(FX3_GCTL_GPIO_COMPLEX+4, 0);
Fx3UtilDelayUs(1);
/* Configure matrix */
Fx3WriteReg32(FX3_GCTL_IOMATRIX,
(alt_func << FX3_GCTL_IOMATRIX_S1CFG_SHIFT) |
(alt_func == FX3_GCTL_ALTFUNC_GPIF32BIT_UART_I2S?
FX3_GCTL_IOMATRIX_S0CFG : 0));
}
void Fx3GctlHardReset(void)
{
Fx3UtilDelayUs(5);
Fx3ClearReg32(FX3_GCTL_CONTROL, FX3_GCTL_CONTROL_HARD_RESET_N);
Fx3UtilDelayUs(5);
}

54
bsp/gctl.h

@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_GCTL_H_
#define BSP_GCTL_H_
#include <stdint.h>
#ifndef PLL_FBDIV
#define PLL_FBDIV 21 /* -> SYS_CLK = 403200000 */
#endif
#define SYS_CLK (19200000 * PLL_FBDIV)
#ifndef CPU_DIV
#define CPU_DIV 2
#endif
#define CPU_CLK (SYS_CLK / CPU_DIV)
/* Alternate function for GPIO 33-57 */
typedef enum {
FX3_GCTL_ALTFUNC_GPIO = 0,
FX3_GCTL_ALTFUNC_GPIO_UART = 1,
FX3_GCTL_ALTFUNC_GPIO_SPI = 2,
FX3_GCTL_ALTFUNC_GPIO_I2S = 3,
FX3_GCTL_ALTFUNC_UART_SPI_I2S = 4,
FX3_GCTL_ALTFUNC_GPIF32BIT_UART_I2S = 5
} Fx3GctlPinAltFunc_t;
extern void Fx3GctlInitClock(void);
extern void Fx3GctlInitIoMatrix(Fx3GctlPinAltFunc_t alt_func);
extern void Fx3GctlHardReset(void);
#endif /* BSP_GCTL_H_ */

220
bsp/gpif.c

@ -0,0 +1,220 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/gpif.h>
#include <bsp/regaccess.h>
#include <bsp/irq.h>
#include <bsp/util.h>
#include <bsp/uart.h>
#include <rdb/gctl.h>
#include <rdb/pib.h>
#include <rdb/vic.h>
static void Fx3GpifPibIsr(void) __attribute__ ((isr ("IRQ")));
static void Fx3GpifPibIsr(void)
{
uint32_t req = Fx3ReadReg32(FX3_PIB_INTR) & Fx3ReadReg32(FX3_PIB_INTR_MASK);
Fx3WriteReg32(FX3_PIB_INTR, req);
Fx3UartTxString("Fx3GpifPibIsr\n");
if (req & FX3_PIB_INTR_GPIF_ERR) {
Fx3UartTxString(" GPIF ERROR\n");
/* Pause on error */
Fx3SetReg32(FX3_GPIF_WAVEFORM_CTRL_STAT, FX3_GPIF_WAVEFORM_CTRL_STAT_PAUSE);
}
if (req & FX3_PIB_INTR_GPIF_INTERRUPT) {
Fx3UartTxString(" GPIF\n");
uint32_t gpif_req = Fx3ReadReg32(FX3_GPIF_INTR) & Fx3ReadReg32(FX3_GPIF_INTR_MASK);
Fx3WriteReg32(FX3_GPIF_INTR, gpif_req);
if (gpif_req & FX3_GPIF_INTR_GPIF_INTR)
Fx3UartTxString(" INTR\n");
if (gpif_req & FX3_GPIF_INTR_GPIF_DONE)
Fx3UartTxString(" DONE\n");
}
Fx3WriteReg32(FX3_VIC_ADDRESS, 0);
}
void Fx3GpifStart(uint8_t state, uint8_t alpha)
{
Fx3WriteReg32(FX3_GPIF_INTR, Fx3ReadReg32(FX3_GPIF_INTR));
Fx3WriteReg32(FX3_GPIF_INTR_MASK,
FX3_GPIF_INTR_MASK_GPIF_INTR | FX3_GPIF_INTR_MASK_GPIF_DONE);
Fx3SetField32(FX3_GPIF_WAVEFORM_CTRL_STAT, ALPHA_INIT, alpha);
Fx3SetReg32(FX3_GPIF_WAVEFORM_CTRL_STAT,
FX3_GPIF_WAVEFORM_CTRL_STAT_WAVEFORM_VALID);
Fx3WriteReg32(FX3_GPIF_WAVEFORM_SWITCH,
(Fx3ReadReg32(FX3_GPIF_WAVEFORM_SWITCH) &
~(FX3_GPIF_WAVEFORM_SWITCH_DESTINATION_STATE_SHIFT |
FX3_GPIF_WAVEFORM_SWITCH_TERMINAL_STATE_MASK |
FX3_GPIF_WAVEFORM_SWITCH_SWITCH_NOW |
FX3_GPIF_WAVEFORM_SWITCH_WAVEFORM_SWITCH)) |
(state << FX3_GPIF_WAVEFORM_SWITCH_DESTINATION_STATE_SHIFT));
Fx3SetReg32(FX3_GPIF_WAVEFORM_SWITCH,
FX3_GPIF_WAVEFORM_SWITCH_SWITCH_NOW |
FX3_GPIF_WAVEFORM_SWITCH_WAVEFORM_SWITCH);
}
void Fx3GpifStop(void)
{
Fx3SetReg32(FX3_GPIF_WAVEFORM_CTRL_STAT, FX3_GPIF_WAVEFORM_CTRL_STAT_PAUSE);
Fx3UtilDelayUs(10);
Fx3WriteReg32(FX3_GPIF_WAVEFORM_CTRL_STAT, 0);
}
void Fx3GpifInvalidate(void)
{
unsigned i;
Fx3WriteReg32(FX3_GPIF_CONFIG, 0x220);
for (i=0; i<256; i++) {
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + i*16 + 8, 0);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + i*16 + 8, 0);
}
for (i=0; i<4; i++)
Fx3WriteReg32(FX3_GPIF_THREAD_CONFIG + i*4, 0);
}
static void Fx3GpifConfigureCommon(const uint16_t *functions,
uint16_t num_functions,
const uint32_t *registers,
uint16_t num_registers)
{
unsigned i;
if (functions && num_functions) {
if (num_functions > 32)
num_functions = 32;
for(i=0; i<num_functions; i++) {
Fx3WriteReg32(FX3_GPIF_FUNCTION + i*4, functions[i]);
}
}
if (registers && num_registers) {
for(i=num_registers; i--; )
Fx3WriteReg32(FX3_GPIF_CONFIG + i*4, registers[i]);
}
}
void Fx3GpifConfigure(const Fx3GpifWaveform_t *waveforms,
uint16_t num_waveforms,
const uint16_t *functions, uint16_t num_functions,
const Fx3GpifRegisters_t *registers)
{
unsigned i;
if (waveforms && num_waveforms) {
for(i=0; i<num_waveforms; i++) {
const Fx3GpifWaveform_t *left = &waveforms[waveforms[i].left];
const Fx3GpifWaveform_t *right = &waveforms[waveforms[i].right];
unsigned pos = waveforms[i].state[0] & FX3_GPIF_LEFT_WAVEFORM_NEXT_STATE_MASK;
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + pos*16 + 0, left->state[0]);
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + pos*16 + 4, left->state[1]);
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + pos*16 + 8, left->state[2]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + pos*16 + 0, right->state[0]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + pos*16 + 4, right->state[1]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + pos*16 + 8, right->state[2]);
}
}
Fx3GpifConfigureCommon(functions, num_functions, &registers->config,
sizeof(*registers)/sizeof(uint32_t));
}
void Fx3GpifConfigureCompat(const Fx3GpifWaveformCompat_t *waveforms,
const uint8_t *waveform_select,
uint16_t num_waveforms,
const uint16_t *functions, uint16_t num_functions,
const uint32_t *registers, uint16_t num_registers)
{
unsigned i;
if (waveforms && num_waveforms) {
for(i=0; i<num_waveforms; i++) {
const Fx3GpifWaveformCompat_t *w =
&waveforms[waveform_select? waveform_select[i]:i];
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + i*16 + 0, w->left[0]);
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + i*16 + 4, w->left[1]);
Fx3WriteReg32(FX3_GPIF_LEFT_WAVEFORM + i*16 + 8, w->left[2]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + i*16 + 0, w->right[0]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + i*16 + 4, w->right[1]);
Fx3WriteReg32(FX3_GPIF_RIGHT_WAVEFORM + i*16 + 8, w->right[2]);
}
}
Fx3GpifConfigureCommon(functions, num_functions, registers, num_registers);
}
void Fx3GpifPibStart(uint16_t clock_divisor_x2)
{
Fx3WriteReg32(FX3_GCTL_PIB_CORE_CLK,
(((clock_divisor_x2 >> 1)-1) << FX3_GCTL_PIB_CORE_CLK_DIV_SHIFT) |
(3UL << FX3_GCTL_PIB_CORE_CLK_SRC_SHIFT));
if (clock_divisor_x2 & 1)
Fx3SetReg32(FX3_GCTL_PIB_CORE_CLK, FX3_GCTL_PIB_CORE_CLK_HALFDIV);
Fx3SetReg32(FX3_GCTL_PIB_CORE_CLK, FX3_GCTL_PIB_CORE_CLK_CLK_EN);
Fx3WriteReg32(FX3_PIB_POWER, 0);
Fx3UtilDelayUs(10);
Fx3SetReg32(FX3_PIB_POWER, FX3_PIB_POWER_RESETN);
while(!(Fx3ReadReg32(FX3_PIB_POWER) & FX3_PIB_POWER_ACTIVE))
;
Fx3ClearReg32(FX3_PIB_DLL_CTRL, FX3_PIB_DLL_CTRL_ENABLE);
Fx3UtilDelayUs(1);
Fx3WriteReg32(FX3_PIB_DLL_CTRL,
(clock_divisor_x2<11? FX3_PIB_DLL_CTRL_HIGH_FREQ : 0UL) |
FX3_PIB_DLL_CTRL_ENABLE);
Fx3UtilDelayUs(1);
Fx3ClearReg32(FX3_PIB_DLL_CTRL, FX3_PIB_DLL_CTRL_DLL_RESET_N);
Fx3UtilDelayUs(1);
Fx3SetReg32(FX3_PIB_DLL_CTRL, FX3_PIB_DLL_CTRL_DLL_RESET_N);
Fx3UtilDelayUs(1);
while(!(Fx3ReadReg32(FX3_PIB_DLL_CTRL) & FX3_PIB_DLL_CTRL_DLL_STAT))
;
Fx3WriteReg32(FX3_VIC_VEC_ADDRESS + (FX3_IRQ_GPIF_CORE<<2), Fx3GpifPibIsr);
Fx3WriteReg32(FX3_PIB_INTR, Fx3ReadReg32(FX3_PIB_INTR));
Fx3WriteReg32(FX3_PIB_INTR_MASK, FX3_PIB_INTR_MASK_GPIF_ERR |
FX3_PIB_INTR_MASK_GPIF_INTERRUPT);
Fx3WriteReg32(FX3_VIC_INT_ENABLE, (1UL << FX3_IRQ_GPIF_CORE));
}
void Fx3GpifPibStop(void)
{
Fx3WriteReg32(FX3_PIB_INTR_MASK, 0UL);
Fx3WriteReg32(FX3_VIC_INT_CLEAR, (1UL << FX3_IRQ_GPIF_CORE));
Fx3WriteReg32(FX3_PIB_INTR_MASK, 0UL);
Fx3WriteReg32(FX3_PIB_INTR, ~0UL);
Fx3WriteReg32(FX3_PIB_POWER, 0UL);
Fx3UtilDelayUs(10);
Fx3ClearReg32(FX3_GCTL_PIB_CORE_CLK, FX3_GCTL_PIB_CORE_CLK_CLK_EN);
}
Fx3GpifStat_t Fx3GpifGetStat(uint8_t *current_state)
{
uint32_t stat = Fx3ReadReg32(FX3_GPIF_WAVEFORM_CTRL_STAT);
if (current_state)
*current_state =
(stat & FX3_GPIF_WAVEFORM_CTRL_STAT_CURRENT_STATE_MASK)
>> FX3_GPIF_WAVEFORM_CTRL_STAT_CURRENT_STATE_SHIFT;
return (stat & FX3_GPIF_WAVEFORM_CTRL_STAT_GPIF_STAT_MASK)
>> FX3_GPIF_WAVEFORM_CTRL_STAT_GPIF_STAT_SHIFT;
}

237
bsp/gpif.h

@ -0,0 +1,237 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_GPIF_H_
#define BSP_GPIF_H_
#include <stdint.h>
#include <rdb/gpif.h>
/* Perform bitwise operations on the following constants to achieve the
corresponding logical operations on the four 1-bit operands */
#define FX3_GPIF_FUNCTION_Fa 0xAAAAU
#define FX3_GPIF_FUNCTION_Fb 0xCCCCU
#define FX3_GPIF_FUNCTION_Fc 0xF0F0U
#define FX3_GPIF_FUNCTION_Fd 0xFF00U
/* Fixed function alphas and betas */
/* (Alpha 4-7 and Beta 0-3 are user defined) */
#define FX3_GPIF_ALPHA_DQ_OEN (1UL<<0) /* Alpha 0 */
#define FX3_GPIF_ALPHA_UPDATE_DOUT (1UL<<1) /* Alpha 1 */
#define FX3_GPIF_ALPHA_SAMPLE_DIN (1UL<<2) /* Alpha 2 */
#define FX3_GPIF_ALPHA_SAMPLE_AIN (1UL<<3) /* Alpha 3 */
#define FX3_GPIF_BETA_THREAD_0 (0UL<<4) /* Beta 4&5 */
#define FX3_GPIF_BETA_THREAD_1 (1UL<<4) /* - " - */
#define FX3_GPIF_BETA_THREAD_2 (2UL<<4) /* - " - */
#define FX3_GPIF_BETA_THREAD_3 (3UL<<4) /* - " - */
#define FX3_GPIF_BETA_RQ_POP (1UL<<6) /* Beta 6 */
#define FX3_GPIF_BETA_WQ_PUSH (1UL<<7) /* Beta 7 */
#define FX3_GPIF_BETA_RQ_POP_ADDR (1UL<<8) /* Beta 8 */
#define FX3_GPIF_BETA_WQ_PUSH_ADDR (1UL<<9) /* Beta 9 */
#define FX3_GPIF_BETA_A_OEN (1UL<<10) /* Beta 10 */
/* 11 = ? */
#define FX3_GPIF_BETA_COUNT_CTRL (1UL<<12) /* Beta 12 */
#define FX3_GPIF_BETA_LD_CTRL_COUNT (1UL<<13) /* Beta 13 */
#define FX3_GPIF_BETA_COUNT_ADDR (1UL<<14) /* Beta 14 */
#define FX3_GPIF_BETA_LD_ADDR_COUNT (1UL<<15) /* Beta 15 */
#define FX3_GPIF_BETA_COUNT_DATA (1UL<<16) /* Beta 16 */
#define FX3_GPIF_BETA_LD_DATA_COUNT (1UL<<17) /* Beta 17 */
#define FX3_GPIF_BETA_INTR_CPU (1UL<<18) /* Beta 18 */
#define FX3_GPIF_BETA_INTR_HOST (1UL<<19) /* Beta 19 */
#define FX3_GPIF_BETA_UPDATE_AOUT (1UL<<20) /* Beta 20 */
#define FX3_GPIF_BETA_REGISTER_ACCESS (1UL<<21) /* Beta 21 */
/* 22, 23, 24 = ? */
#define FX3_GPIF_BETA_ASSERT_DRQ (1UL<<25) /* Beta 25 */
#define FX3_GPIF_BETA_DEASSERT_DRQ (1UL<<26) /* Beta 26 */
/* 27, 28, 29 = ? */
#define FX3_GPIF_BETA_COMMIT (1UL<<30) /* Beta 30 */
#define FX3_GPIF_BETA_PP_ACCESS (1UL<<31) /* Beta 31 */
/* For compatibility with GPIF II Designer output */
typedef struct {
uint32_t left[3], right[3];
} Fx3GpifWaveformCompat_t;
typedef struct {
uint32_t state[3];
uint16_t left, right;
} Fx3GpifWaveform_t;
#define GPIF_START_STATE(n) {(n)&0xff,0,0}
#define GPIF_STATE(n,Fa,Fb,Fc,Fd,f0,f1,AL,AR,B,rep,BD) { \
((n)&0xff)|(((Fa)&0x1f)<<8)|(((Fb)&0x1f)<<13)|(((Fc)&0x1f)<<18)|(((Fd)&0x1f)<<23)|(((f0)&0xf)<<28), \
(((f0)&0x10)>>4)|(((f1)&0x1f)<<1)|(((AL)&0xff)<<6)|(((AR)&0xff)<<14)|(((B)&0x3ff)<<22), \
(((B)&0xfffffc00)>>10)|(((rep)&0xff)<<22)|(((BD)&1)<<30)|(1UL<<31)}
typedef enum {
FX3_GPIF_CTRL_BUS_DIRECTION_INPUT = 0,
FX3_GPIF_CTRL_BUS_DIRECTION_OUTPUT,
FX3_GPIF_CTRL_BUS_DIRECTION_BIDIR,
FX3_GPIF_CTRL_BUS_DIRECTION_OPEN_DRAIN,
} Fx3GpifCtrlBusDirection_t;
typedef enum {
FX3_GPIF_OEN_CFG_OUTPUT = 0,
FX3_GPIF_OEN_CFG_INPUT,
FX3_GPIF_OEN_CFG_DYNAMIC, /* Controlled by alpha/beta */
} Fx3GpifOenCfg_t;
typedef enum {
FX3_GPIF_LAMBDA_INDEX_CTL0 = 0, /* GPIO 17 */
FX3_GPIF_LAMBDA_INDEX_CTL1, /* GPIO 18 */
FX3_GPIF_LAMBDA_INDEX_CTL2, /* GPIO 19 */
FX3_GPIF_LAMBDA_INDEX_CTL3, /* GPIO 20 */
FX3_GPIF_LAMBDA_INDEX_CTL4, /* GPIO 21 */
FX3_GPIF_LAMBDA_INDEX_CTL5, /* GPIO 22 */
FX3_GPIF_LAMBDA_INDEX_CTL6, /* GPIO 23 */
FX3_GPIF_LAMBDA_INDEX_CTL7, /* GPIO 24 */
FX3_GPIF_LAMBDA_INDEX_CTL8, /* GPIO 25 */
FX3_GPIF_LAMBDA_INDEX_CTL9, /* GPIO 26 */
FX3_GPIF_LAMBDA_INDEX_CTL10, /* GPIO 27 */
FX3_GPIF_LAMBDA_INDEX_CTL11, /* GPIO 28 */
FX3_GPIF_LAMBDA_INDEX_CTL12, /* GPIO 29 */
FX3_GPIF_LAMBDA_INDEX_CTL13, /* GPIO 49 */
FX3_GPIF_LAMBDA_INDEX_CTL14, /* GPIO 48 */
FX3_GPIF_LAMBDA_INDEX_CTL15, /* GPIO 47 */
FX3_GPIF_LAMBDA_INDEX_OUT_REG_CR_VALID = 16,
FX3_GPIF_LAMBDA_INDEX_IN_REG_CR_VALID = 17,
FX3_GPIF_LAMBDA_INDEX_CTRL_CNT_HIT = 18,
FX3_GPIF_LAMBDA_INDEX_ADDR_CNT_HIT = 19,
FX3_GPIF_LAMBDA_INDEX_DATA_CNT_HIT = 20,
FX3_GPIF_LAMBDA_INDEX_CTRL_CMP_MATCH = 21,
FX3_GPIF_LAMBDA_INDEX_ADDR_CMP_MATCH = 22,
FX3_GPIF_LAMBDA_INDEX_DATA_CMP_MATCH = 23,
FX3_GPIF_LAMBDA_INDEX_DMA_WM = 24,
FX3_GPIF_LAMBDA_INDEX_DMA_RDY_ADDR = 25,
FX3_GPIF_LAMBDA_INDEX_DMA_RDY = 26,
/* 27, 28 = ? */
FX3_GPIF_LAMBDA_INDEX_INTR_PEND = 29,
FX3_GPIF_LAMBDA_INDEX_FW_TRG = 30,
FX3_GPIF_LAMBDA_INDEX_OUT_ADDR_VALID = 31,
} Fx3GpifLambdaIndex_t;
typedef enum {
FX3_GPIF_OMEGA_INDEX_ALPHA4 = 0,
FX3_GPIF_OMEGA_INDEX_ALPHA5,
FX3_GPIF_OMEGA_INDEX_ALPHA6,
FX3_GPIF_OMEGA_INDEX_ALPHA7,
FX3_GPIF_OMEGA_INDEX_BETA0 = 8,
FX3_GPIF_OMEGA_INDEX_BETA1,
FX3_GPIF_OMEGA_INDEX_BETA2,
FX3_GPIF_OMEGA_INDEX_BETA3,
FX3_GPIF_OMEGA_INDEX_EMPTY_FULL_TH0 = 16,
FX3_GPIF_OMEGA_INDEX_EMPTY_FULL_TH1,
FX3_GPIF_OMEGA_INDEX_EMPTY_FULL_TH2,
FX3_GPIF_OMEGA_INDEX_EMPTY_FULL_TH3,
FX3_GPIF_OMEGA_INDEX_PARTIAL_TH0,
FX3_GPIF_OMEGA_INDEX_PARTIAL_TH1,
FX3_GPIF_OMEGA_INDEX_PARTIAL_TH2,
FX3_GPIF_OMEGA_INDEX_PARTIAL_TH3,
FX3_GPIF_OMEGA_INDEX_EMPTY_FULL_CURRENT,
FX3_GPIF_OMEGA_INDEX_PARTIAL_CURRENT,
FX3_GPIF_OMEGA_INDEX_PP_DRQR5,
FX3_GPIF_OMEGA_INDEX_CONSTANT_0 = 31
} Fx3GpifOmegaIndex_t;
typedef struct {
uint32_t config;
uint32_t bus_config;
uint32_t bus_config2;
uint32_t ad_config;
uint32_t status;
uint32_t intr;
uint32_t intr_mask;
uint32_t serial_in_config;
uint32_t serial_out_config;
uint32_t ctrl_bus_direction;
uint32_t ctrl_bus_default;
uint32_t ctrl_bus_polarity;
uint32_t ctrl_bus_toggle;
uint32_t ctrl_bus_select[16];
uint32_t ctrl_count_config;
uint32_t ctrl_count_reset;
uint32_t ctrl_count_limit;
uint32_t addr_count_config;
uint32_t addr_count_reset;
uint32_t addr_count_limit;
uint32_t state_count_config;
uint32_t state_count_limit;
uint32_t data_count_config;
uint32_t data_count_reset;
uint32_t data_count_limit;
uint32_t ctrl_comp_value;
uint32_t ctrl_comp_mask;
uint32_t data_comp_value;
uint32_t data_comp_mask;
uint32_t addr_comp_value;
uint32_t addr_comp_mask;
uint32_t data_ctrl;
uint32_t ingress_data[4];
uint32_t egress_data[4];
uint32_t ingress_address[4];
uint32_t egress_address[4];
uint32_t thread_config[4];
uint32_t lambda_stat;
uint32_t alpha_stat;
uint32_t beta_stat;
uint32_t waveform_ctrl_stat;
uint32_t waveform_switch;
uint32_t waveform_switch_timeout;
uint32_t crc_config;
uint32_t crc_data;
uint32_t beta_deassert;
} Fx3GpifRegisters_t;
typedef enum {
FX3_GPIF_INVALID = 0,
FX3_GPIF_ARMED = 2,
FX3_GPIF_RUNNING,
FX3_GPIF_DONE,
FX3_GPIF_PAUSED,
FX3_GPIF_SWITCHING,
FX3_GPIF_ERROR,
} Fx3GpifStat_t;
extern void Fx3GpifStart(uint8_t state, uint8_t alpha);
extern void Fx3GpifStop(void);
extern void Fx3GpifInvalidate(void);
extern void Fx3GpifConfigure(const Fx3GpifWaveform_t *waveforms,
uint16_t num_waveforms,
const uint16_t *functions, uint16_t num_functions,
const Fx3GpifRegisters_t *registers);
extern void Fx3GpifConfigureCompat(const Fx3GpifWaveformCompat_t *waveforms,
const uint8_t *waveform_select,
uint16_t num_waveforms,
const uint16_t *functions, uint16_t num_functions,
const uint32_t *registers, uint16_t num_registers);
extern void Fx3GpifPibStart(uint16_t clock_divisor_x2);
extern void Fx3GpifPibStop(void);
extern Fx3GpifStat_t Fx3GpifGetStat(uint8_t *current_state);
#endif /* BSP_GPIF_H_ */

104
bsp/gpio.c

@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/gpio.h>
#include <bsp/regaccess.h>
#include <bsp/util.h>
#include <rdb/gpio.h>
#include <rdb/gctl.h>
void Fx3GpioInitClock(void)
{
Fx3WriteReg32(FX3_GCTL_GPIO_FAST_CLK,
FX3_GCTL_GPIO_FAST_CLK_CLK_EN |
(3UL << FX3_GCTL_GPIO_FAST_CLK_SRC_SHIFT) |
((GPIO_FAST_DIV - 1UL) << FX3_GCTL_GPIO_FAST_CLK_DIV_SHIFT));
Fx3UtilDelayUs(10);
Fx3WriteReg32(FX3_GCTL_GPIO_SLOW_CLK,
FX3_GCTL_GPIO_SLOW_CLK_CLK_EN |
((GPIO_SLOW_DIV - 1UL) << FX3_GCTL_GPIO_SLOW_CLK_DIV_SHIFT));
Fx3UtilDelayUs(10);
}
void Fx3GpioSetupSimple(uint8_t num, uint32_t config)
{
if (num < 61 &&
!(Fx3ReadReg32(FX3_GCTL_GPIO_COMPLEX + ((num & 32) >> 3))
& (1UL << (num & 31)))) {
Fx3WriteReg32(FX3_GPIO_SIMPLE + (num << 2), config);
Fx3SetReg32(FX3_GCTL_GPIO_SIMPLE + ((num & 32) >> 3),
1UL << (num & 31));
}
}
void Fx3GpioSetupComplex(uint8_t num, uint32_t config, uint32_t timer,
uint32_t period, uint32_t threshold)
{
if (num < 61) {
// There are only 8 instances of complex GPIO. The low 3 bits of
// the GPIO number selects which instance it is connected to.
uint8_t instance = num & 7;
if (!(Fx3ReadReg32(FX3_GCTL_GPIO_COMPLEX + ((num & 32) >> 3))
& (1UL << (num & 31)))) {
// Check for conflicting simple I/O
if ((Fx3ReadReg32(FX3_GCTL_GPIO_SIMPLE + ((num & 32) >> 3))
& (1UL << (num & 31))))
// GPIO already in use
return;
// Check for conflicting complex I/O
uint32_t mask = 0x01010101UL << instance;
if ((Fx3ReadReg32(FX3_GCTL_GPIO_COMPLEX + 0) & mask) ||
(Fx3ReadReg32(FX3_GCTL_GPIO_COMPLEX + 4) & mask))
// Instance already in use
return;
}
Fx3ClearReg32(FX3_PIN_STATUS + (instance << 4), FX3_PIN_STATUS_ENABLE);
Fx3WriteReg32(FX3_PIN_TIMER + (instance << 4), timer);
Fx3WriteReg32(FX3_PIN_PERIOD + (instance << 4), period);
Fx3WriteReg32(FX3_PIN_THRESHOLD + (instance << 4), threshold);
Fx3WriteReg32(FX3_PIN_STATUS + (instance << 4), config);
Fx3SetReg32(FX3_GCTL_GPIO_COMPLEX + ((num & 32) >> 3),
1UL << (num & 31));
}
}
void Fx3GpioSetOutputValueSimple(uint8_t num, uint8_t value)
{
if (num < 61) {
Fx3WriteReg32(FX3_GPIO_SIMPLE + (num << 2),
(Fx3ReadReg32(FX3_GPIO_SIMPLE + (num << 2)) &
~(FX3_GPIO_SIMPLE_INTR | FX3_GPIO_SIMPLE_OUT_VALUE)) |
(value & FX3_GPIO_SIMPLE_OUT_VALUE));
}
}
uint8_t Fx3GpioGetInputValueSimple(uint8_t num)
{
if (num < 61) {
return (Fx3ReadReg32(FX3_GPIO_SIMPLE + (num << 2)) & FX3_GPIO_SIMPLE_IN_VALUE) >> 1;
} else {
return 0;
}
}

89
bsp/gpio.h

@ -0,0 +1,89 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_GPIO_H_
#define BSP_GPIO_H_
#include <stdint.h>
#include <rdb/gpio.h>
#include <bsp/gctl.h>
#ifndef GPIO_FAST_DIV
#define GPIO_FAST_DIV 2
#endif
#ifndef GPIO_SLOW_DIV
#define GPIO_SLOW_DIV 48
#endif
#define GPIO_FAST_CLK (SYS_CLK / GPIO_FAST_DIV)
#define GPIO_SLOW_CLK (GPIO_FAST_CLK / GPIO_SLOW_DIV)
typedef enum {
FX3_GPIO_TIMER_MODE_SHUTDOWN = 0,
FX3_GPIO_TIMER_MODE_FAST_CLK,
FX3_GPIO_TIMER_MODE_SLOW_CLK,
FX3_GPIO_TIMER_MODE_STANDBY_CLK,
FX3_GPIO_TIMER_MODE_POS_EDGE,
FX3_GPIO_TIMER_MODE_NEG_EDGE,
FX3_GPIO_TIMER_MODE_ANY_EDGE,
} Fx3GpioTimerMode_t;
typedef enum {
FX3_GPIO_INTR_MODE_NONE = 0,
FX3_GPIO_INTR_MODE_POS_EDGE,
FX3_GPIO_INTR_MODE_NEG_EDGE,
FX3_GPIO_INTR_MODE_ANY_EDGE,
FX3_GPIO_INTR_MODE_LOW_LEVEL,
FX3_GPIO_INTR_MODE_HIGH_LEVEL,
FX3_GPIO_INTR_MODE_TIMER_THRESHOLD,
FX3_GPIO_INTR_MODE_TIMER_0,
} Fx3GpioIntrMode_t;
typedef enum {
FX3_GPIO_PIN_MODE_STATIC = 0,
FX3_GPIO_PIN_MODE_TOGGLE,
FX3_GPIO_PIN_MODE_SAMPLENOW,
FX3_GPIO_PIN_MODE_PULSENOW,
FX3_GPIO_PIN_MODE_PULSE,
FX3_GPIO_PIN_MODE_PWM,
FX3_GPIO_PIN_MODE_MEASURE_LOW,
FX3_GPIO_PIN_MODE_MEASURE_HIGH,
FX3_GPIO_PIN_MODE_MEASURE_LOW_ONCE,
FX3_GPIO_PIN_MODE_MEASURE_HIGH_ONCE,
FX3_GPIO_PIN_MODE_MEASURE_NEG,
FX3_GPIO_PIN_MODE_MEASURE_POS,
FX3_GPIO_PIN_MODE_MEASURE_ANY,
FX3_GPIO_PIN_MODE_MEASURE_NEG_ONCE,
FX3_GPIO_PIN_MODE_MEASURE_POS_ONCE,
FX3_GPIO_PIN_MODE_MEASURE_ANY_ONCE,
} Fx3GpioPinMode_t;
extern void Fx3GpioInitClock(void);
extern void Fx3GpioSetupSimple(uint8_t num, uint32_t config);
extern void Fx3GpioSetupComplex(uint8_t num, uint32_t config, uint32_t timer,
uint32_t period, uint32_t threshold);
extern void Fx3GpioSetOutputValueSimple(uint8_t num, uint8_t value);
extern uint8_t Fx3GpioGetInputValueSimple(uint8_t num);
#endif /* BSP_GPIO_H_ */

40
bsp/irq.c

@ -0,0 +1,40 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/irq.h>
#include <bsp/regaccess.h>
#include <bsp/cache.h>
#include <rdb/vic.h>
void Fx3IrqInit(void)
{
Fx3WriteReg32(FX3_VIC_INT_CLEAR, ~0UL);
Fx3WriteReg32(FX3_VIC_INT_SELECT, 0UL);
Fx3IrqInstallVectors();
Fx3CacheCleanDCache();
Fx3CacheInvalidateICache();
/* Move vector base to 0 */
uint32_t creg;
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(creg));
creg &= ~(1UL << 13);
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" : : "r"(creg));
}

64
bsp/irq.h

@ -0,0 +1,64 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_IRQ_H_
#define BSP_IRQ_H_
#include <stdint.h>
typedef enum {
FX3_IRQ_GCTL_CORE = 0,
FX3_IRQ_SW_INTR = 1,
FX3_IRQ_WATCHDOG_TIMER = 4,
FX3_IRQ_GPIF_DMA = 6,
FX3_IRQ_GPIF_CORE = 7,
FX3_IRQ_USB_DMA = 8,
FX3_IRQ_USB_CORE = 9,
FX3_IRQ_STORAGE_DMA = 11,
FX3_IRQ_STORAGE0_CORE = 12,
FX3_IRQ_STORAGE1_CORE = 13,
FX3_IRQ_I2C_CORE = 15,
FX3_IRQ_I2S_CORE = 16,
FX3_IRQ_SPI_CORE = 17,
FX3_IRQ_UART_CORE = 18,
FX3_IRQ_GPIO_CORE = 19,
FX3_IRQ_PERIPH_DMA = 20,
FX3_IRQ_GCTL_POWER = 21,
} Fx3IrqSource_t;
static inline void Fx3IrqEnableInterrupts(void)
{
uint32_t cpsr;
__asm__ __volatile__("mrs %0,cpsr" : "=r"(cpsr));
__asm__ __volatile__("msr cpsr_c,%0" : : "r"(cpsr&0x3f));
}
static inline void Fx3IrqDisableInterrupts(void)
{
uint32_t cpsr;
__asm__ __volatile__("mrs %0,cpsr" : "=r"(cpsr));
__asm__ __volatile__("msr cpsr_c,%0" : : "r"(cpsr|0xc0));
}
extern void Fx3IrqInit(void);
extern void Fx3IrqInstallVectors(void);
#endif /* BSP_IRQ_H_ */

34
bsp/regaccess.h

@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BSP_REGACCESS_H_
#define BSP_REGACCESS_H_
#include <stdint.h>
#define Fx3ReadReg32(a) (*(volatile uint32_t *)(void*)(a))
#define Fx3WriteReg32(a, v) ((*(volatile uint32_t *)(void*)(a))=(uint32_t)(v))
#define Fx3SetReg32(a, v) Fx3WriteReg32((a), Fx3ReadReg32((a)) | (v))
#define Fx3ClearReg32(a, v) Fx3WriteReg32((a), Fx3ReadReg32((a)) & ~(v))
#define Fx3SetField32(a, f, v) Fx3WriteReg32((a), (Fx3ReadReg32((a)) & ~(a ## _ ## f ## _MASK)) | (((v) << (a ## _ ## f ## _SHIFT)) & (a ## _ ## f ## _MASK)))
#define Fx3GetField32(a, f) ((Fx3ReadReg32((a)) & (a ## _ ## f ## _MASK)) >> (a ## _ ## f ## _SHIFT))
#endif /* BSP_REGACCESS_H_ */

82
bsp/uart.c

@ -0,0 +1,82 @@
/*
* Copyright (C) 2018 Marcus Comstedt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <bsp/uart.h>
#include <bsp/gctl.h>
#include <bsp/regaccess.h>
#include <bsp/util.h>
#include <rdb/uart.h>
#include <rdb/gctl.h>
void Fx3UartInit(uint32_t baud_rate, Fx3UartParity_t parity, Fx3UartStopBits_t stop_bits)
{
/* Configure baud rate generator */
Fx3WriteReg32(FX3_GCTL_UART_CORE_CLK,