Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lion-soc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

## Setup
* [Project IceStorm](https://github.com/standardsemiconductor/VELDT-info#project-icestorm)
* [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain)
* [riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain)
* Need `riscv64-unknown-*` binaries e.g.:
```console
foo@bar:~$ git clone https://github.com/riscv/riscv-gnu-toolchain.git
foo@bar:~$ git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git
foo@bar:~$ cd riscv-gnu-toolchain
foo@bar:~/riscv-gnu-toolchain$ git submodule update --init --recursive
foo@bar:~/riscv-gnu-toolchain$ ./configure --prefix=/opt/riscv/
foo@bar:~/riscv-gnu-toolchain$ ./configure --prefix=/opt/riscv/ --enable-multilib
foo@bar:~/rsicv-gnu-toolchain$ sudo make
foo@bar:~/riscv-gnu-toolchain$ export PATH=$PATH:/opt/riscv/bin
```
Expand Down Expand Up @@ -82,7 +82,7 @@ Status Byte:
76543210
......**
||__Transmitter Status: 0 = Empty (Idle), 1 = Full (Busy)
|___Receiver Status: 0 = Empty, 1 = Full
|___Receiver Status: 0 = Full, 1 = Empty
```

#### UART Usage Examples
Expand All @@ -101,7 +101,7 @@ Status Byte:
li a0, 0x4 # set pointer to UART peripheral memory location
1: lbu a1, 0x2(a0) # read status register
andi a1, a1, 0x2 # mask receiver status
beqz a1, 1b # wait until receiver full
bnez a1, 1b # wait until receiver full
lbu a1, 0x1(a0) # read receiver buffer
```
### SPI Flash
Expand Down
149 changes: 149 additions & 0 deletions lion-soc/app/Boot.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative ((<|>))
import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (
Concurrently(Concurrently, runConcurrently),
concurrently_,
mapConcurrently_,
race_
)
import Control.Concurrent.STM (
TChan,
atomically,
dupTChan,
newBroadcastTChanIO,
newTChan,
newTChanIO,
readTChan,
writeTChan
)
import Control.Monad (forever, forM_, join, void, (<=<))
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy.Char8 as LC (
ByteString,
getContents,
hGetContents,
hPut,
pack,
putStr,
putStrLn,
readFile,
singleton,
takeWhile
)
import System.Environment (getArgs)
import System.Hardware.Serialport (
CommSpeed(CS19200),
SerialPortSettings(..),
defaultSerialSettings,
hWithSerial
)
import System.IO (
BufferMode(LineBuffering, NoBuffering),
Handle,
hGetChar,
hPutChar,
hSetBuffering,
hSetNewlineMode,
stdin,
universalNewlineMode
)

main :: IO ()
main = boot =<< parseArgs <$> getArgs

parseArgs :: [String] -> (FilePath, Maybe FilePath)
parseArgs = \case
[serialPath] -> (serialPath, Nothing)
[serialPath, imagePath] -> (serialPath, Just imagePath)
_ -> ("/dev/ttyUSB0", Just "_build/demo/led/led.bin")

boot :: (FilePath, Maybe FilePath) -> IO ()
boot (serialPath, imagePathM) =
hWithSerial serialPath serialSettings $ \serialHandle -> do
hSetBuffering stdin NoBuffering
hSetBuffering serialHandle NoBuffering
hSetNewlineMode serialHandle universalNewlineMode
interactSerial imagePathM =<< mkBoot serialHandle

data Boot = Boot
{ bootHandle :: Handle
, fromSerialTChan :: TChan LC.ByteString
, toSerialTChan :: TChan LC.ByteString
}

mkBoot :: Handle -> IO Boot
mkBoot hndl = do
fromSerial <- newBroadcastTChanIO
toSerial <- newTChanIO
return $ Boot{ bootHandle = hndl
, fromSerialTChan = fromSerial
, toSerialTChan = toSerial
}

interactSerial :: Maybe FilePath -> Boot -> IO ()
interactSerial imagePathM boot =
mapConcurrently_
($ boot)
[ fromSerial
, toSerial
, toStdout
, setup imagePathM
]

fromSerial :: Boot -> IO ()
fromSerial boot = do
bs <- LC.hGetContents $ bootHandle boot
atomically $ writeTChan (fromSerialTChan boot) bs

toSerial :: Boot -> IO ()
toSerial boot = join $ atomically $ do
bs <- readTChan $ toSerialTChan boot
return $ LC.hPut (bootHandle boot) bs

fromStdin :: Boot -> IO ()
fromStdin boot = writeSerial boot =<< LC.getContents

toStdout :: Boot -> IO ()
toStdout boot = LC.putStr =<< readSerial boot
toStdout boot = join $ atomically $ do
bs <- readTChan (fromSerialTChan boot)
return $ LC.putStr bs

setup :: Maybe FilePath -> Boot -> IO ()
setup imagePathM boot = do
write "a"
--atomically $ do
-- chan <- dupTChan $ fromSerialTChan boot
-- _ <- LC.takeWhile (/= '?') <$> readTChan chan
-- return ()
--fmap (LC.dropWhile (/= '?')) $ readTChan =<< dupTChan (fromSerialTChan boot)
case imagePathM of
Nothing -> write "e"
Just path -> do
write "n"
LC.putStrLn $ "\nUploading " <> LC.pack path
write =<< LC.readFile path
LC.putStrLn "Done"
fromStdin boot
where
write = writeSerial boot

writeSerial :: Boot -> LC.ByteString -> IO ()
writeSerial boot = atomically . writeTChan (toSerialTChan boot)

-- hPutChar serialHandle '\n'
-- threadDelay 1000
-- hPutChar serialHandle 'n'
-- forM_ imagePathM $ C.hPut serialHandle <=< C.readFile
-- case imagePathM of
-- Nothing -> hPutChar serialHandle 'e'
-- Just imagePath -> do
-- hPutChar serialHandle 'n'
-- C.hPut serialHandle =<< C.readFile imagePath
-- interactUart serialHandle

serialSettings :: SerialPortSettings
serialSettings = defaultSerialSettings{ commSpeed = CS19200 }
36 changes: 36 additions & 0 deletions lion-soc/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ main = shakeArgs opts $ do
, "_build/bios/bios.rom3"
]

phony "demo" $ do
need [ "_build/demo/led/led.bin"]

-- yosys synthesis
"_build/Soc.json" %> \out -> do
putInfo "Synthesizing Soc"
Expand Down Expand Up @@ -111,6 +114,39 @@ main = shakeArgs opts $ do
"bios/bios.S"
"-o"
[out]

"_build/demo/led/led.o" %> \out -> do
need [ "demo/link.ld"
, "demo/crt0.S"
, "demo/firmware.c"
, "demo/led/led.c"
]
cmd_ "riscv64-unknown-elf-gcc"
"-march=rv32i"
"-mabi=ilp32"
"-Wall"
"-g"
"-ffreestanding"
"-O0"
"-Wl,--gc-sections"
"-nostartfiles"
"-Wl,-T,demo/link.ld demo/crt0.S demo/firmware.c demo/led/led.c"
"-o"
[out]
"_build/demo/led/led.bin" %> \out -> do
need ["_build/demo/led/led.o"]
cmd_ "riscv64-unknown-elf-objcopy"
"-O"
"binary"
"_build/demo/led/led.o"
[out]
cmd_ "dd"
"if=/dev/zero"
"of=_build/demo/led/led.bin"
"bs=1"
"count=1"
"seek=131071"

where
opts = shakeOptions
{ shakeFiles = buildDir
Expand Down
Loading