mirror of
https://github.com/commaai/agnos-builder.git
synced 2026-08-22 00:33:52 +08:00
move a bunch of stuff into userspace/root/
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Generated by iptables-save v1.8.4 on Thu May 26 16:34:33 2022
|
||||
*security
|
||||
:INPUT ACCEPT [232864:1793459837]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [205236:11113001]
|
||||
COMMIT
|
||||
# Completed on Thu May 26 16:34:33 2022
|
||||
# Generated by iptables-save v1.8.4 on Thu May 26 16:34:33 2022
|
||||
*raw
|
||||
:PREROUTING ACCEPT [232873:1793461973]
|
||||
:OUTPUT ACCEPT [205236:11113001]
|
||||
COMMIT
|
||||
# Completed on Thu May 26 16:34:33 2022
|
||||
# Generated by iptables-save v1.8.4 on Thu May 26 16:34:33 2022
|
||||
*nat
|
||||
:PREROUTING ACCEPT [92:10264]
|
||||
:INPUT ACCEPT [83:8128]
|
||||
:OUTPUT ACCEPT [281:20487]
|
||||
:POSTROUTING ACCEPT [281:20487]
|
||||
COMMIT
|
||||
# Completed on Thu May 26 16:34:33 2022
|
||||
# Generated by iptables-save v1.8.4 on Thu May 26 16:34:33 2022
|
||||
*mangle
|
||||
:PREROUTING ACCEPT [232873:1793461973]
|
||||
:INPUT ACCEPT [232864:1793459837]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [205236:11113001]
|
||||
:POSTROUTING ACCEPT [205236:11113001]
|
||||
COMMIT
|
||||
# Completed on Thu May 26 16:34:33 2022
|
||||
# Generated by iptables-save v1.8.4 on Thu May 26 16:34:33 2022
|
||||
*filter
|
||||
:INPUT ACCEPT [16:2193]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [108:15364]
|
||||
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A INPUT -i wwan0 -j DROP
|
||||
COMMIT
|
||||
# Completed on Thu May 26 16:34:33 2022
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
### GENERATED BY SALT ###
|
||||
cat << 'EOF'
|
||||
.~ssos+.
|
||||
+8888888888i,
|
||||
{888888888888o.
|
||||
h8888888888888k
|
||||
t888888888s888k
|
||||
`t88888d/ h88k
|
||||
``` h88l
|
||||
,88k`
|
||||
.d8h`
|
||||
+d8h
|
||||
_+d8h`
|
||||
;y8h+`
|
||||
|-`
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 00-header - create the header of the MOTD
|
||||
# Copyright (C) 2009-2010 Canonical Ltd.
|
||||
#
|
||||
# Authors: Dustin Kirkland <kirkland@canonical.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
[ -r /etc/lsb-release ] && . /etc/lsb-release
|
||||
|
||||
if [ -z "$DISTRIB_DESCRIPTION" ] && [ -x /usr/bin/lsb_release ]; then
|
||||
# Fall back to using the very slow lsb_release utility
|
||||
DISTRIB_DESCRIPTION=$(lsb_release -s -d)
|
||||
fi
|
||||
|
||||
AGNOS_DESCRIPTION=$(< /VERSION)
|
||||
|
||||
# For CI builds e.g. "11-ade422a"
|
||||
if [[ "$AGNOS_DESCRIPTION" == *-* ]]; then
|
||||
AGNOS_DESCRIPTION="${AGNOS_DESCRIPTION%-*} (${AGNOS_DESCRIPTION#*-})"
|
||||
fi
|
||||
|
||||
printf "Welcome to AGNOS v%s\n" "$AGNOS_DESCRIPTION"
|
||||
printf "Based on %s (%s %s %s)\n" "$DISTRIB_DESCRIPTION" "$(uname -o)" "$(uname -r)" "$(uname -m)"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
Here are some useful commands:
|
||||
Enter the tmux session where the comma service runs
|
||||
(note: tmux prefix key has been configured to backtick)
|
||||
└── tmux a
|
||||
|
||||
Install Ubuntu packages
|
||||
└── sudo apt update && sudo apt install <pkg>
|
||||
|
||||
Install Python packages
|
||||
└── pip install <pkg>
|
||||
|
||||
When modifying AGNOS, keep in mind that the system partition isn't
|
||||
particularly large. /data/ is the largest partition, and unlike the
|
||||
rest of the partitions, it will persist across AGNOS updates.
|
||||
|
||||
Want a clean slate? Reflash AGNOS with https://flash.comma.ai.
|
||||
EOF
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
printf "\n"
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
alias l='ls -lah'
|
||||
alias gup='git pull --rebase'
|
||||
alias gl='git pull'
|
||||
alias gp='git push'
|
||||
alias gcam='git commit -a -m'
|
||||
alias gst='git status'
|
||||
alias gco='git checkout'
|
||||
alias gsu='git submodule update'
|
||||
alias dump="/data/pythonpath/selfdrive/debug/dump.py"
|
||||
alias op='/data/openpilot/tools/op.sh "$@"'
|
||||
@@ -0,0 +1,9 @@
|
||||
export EDITOR='vim'
|
||||
export VIMINIT='source $MYVIMRC'
|
||||
export MYVIMRC="~/.vimrc"
|
||||
|
||||
source $HOME/.profile
|
||||
|
||||
if [ -d "/data/openpilot" ] && [ "$(tmux display-message -p '#{session_name}')" == "comma" ] ; then
|
||||
cd /data/openpilot
|
||||
fi
|
||||
@@ -0,0 +1,2 @@
|
||||
[main]
|
||||
unpackaged=true
|
||||
@@ -0,0 +1,215 @@
|
||||
#? Config file for btop v. 1.3.0
|
||||
|
||||
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
||||
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
||||
color_theme = "Default"
|
||||
|
||||
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
||||
theme_background = True
|
||||
|
||||
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
|
||||
truecolor = True
|
||||
|
||||
#* Set to true to force tty mode regardless if a real tty has been detected or not.
|
||||
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
|
||||
force_tty = False
|
||||
|
||||
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
|
||||
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
|
||||
#* Use whitespace " " as separator between different presets.
|
||||
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
|
||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
|
||||
|
||||
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
|
||||
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
|
||||
vim_keys = False
|
||||
|
||||
#* Rounded corners on boxes, is ignored if TTY mode is ON.
|
||||
rounded_corners = True
|
||||
|
||||
#* Default symbols to use for graph creation, "braille", "block" or "tty".
|
||||
#* "braille" offers the highest resolution but might not be included in all fonts.
|
||||
#* "block" has half the resolution of braille but uses more common characters.
|
||||
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
|
||||
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
|
||||
graph_symbol = "braille"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_cpu = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_mem = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_net = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_proc = "default"
|
||||
|
||||
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
|
||||
shown_boxes = "cpu mem net proc"
|
||||
|
||||
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
||||
update_ms = 2000
|
||||
|
||||
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
|
||||
#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
|
||||
proc_sorting = "cpu lazy"
|
||||
|
||||
#* Reverse sorting order, True or False.
|
||||
proc_reversed = False
|
||||
|
||||
#* Show processes as a tree.
|
||||
proc_tree = False
|
||||
|
||||
#* Use the cpu graph colors in the process list.
|
||||
proc_colors = True
|
||||
|
||||
#* Use a darkening gradient in the process list.
|
||||
proc_gradient = True
|
||||
|
||||
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
||||
proc_per_core = True
|
||||
|
||||
#* Show process memory as bytes instead of percent.
|
||||
proc_mem_bytes = True
|
||||
|
||||
#* Show cpu graph for each process.
|
||||
proc_cpu_graphs = True
|
||||
|
||||
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
|
||||
proc_info_smaps = False
|
||||
|
||||
#* Show proc box on left side of screen instead of right.
|
||||
proc_left = False
|
||||
|
||||
#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
|
||||
proc_filter_kernel = False
|
||||
|
||||
#* In tree-view, always accumulate child process resources in the parent process.
|
||||
proc_aggregate = False
|
||||
|
||||
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
|
||||
#* Select from a list of detected attributes from the options menu.
|
||||
cpu_graph_upper = "Auto"
|
||||
|
||||
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
|
||||
#* Select from a list of detected attributes from the options menu.
|
||||
cpu_graph_lower = "Auto"
|
||||
|
||||
#* Toggles if the lower CPU graph should be inverted.
|
||||
cpu_invert_lower = True
|
||||
|
||||
#* Set to True to completely disable the lower CPU graph.
|
||||
cpu_single_graph = False
|
||||
|
||||
#* Show cpu box at bottom of screen instead of top.
|
||||
cpu_bottom = False
|
||||
|
||||
#* Shows the system uptime in the CPU box.
|
||||
show_uptime = True
|
||||
|
||||
#* Show cpu temperature.
|
||||
check_temp = True
|
||||
|
||||
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
|
||||
cpu_sensor = "Auto"
|
||||
|
||||
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
|
||||
show_coretemp = True
|
||||
|
||||
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
|
||||
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
|
||||
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
|
||||
#* Example: "4:0 5:1 6:3"
|
||||
cpu_core_map = ""
|
||||
|
||||
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
|
||||
temp_scale = "celsius"
|
||||
|
||||
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
|
||||
base_10_sizes = False
|
||||
|
||||
#* Show CPU frequency.
|
||||
show_cpu_freq = True
|
||||
|
||||
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
|
||||
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
|
||||
clock_format = "%X"
|
||||
|
||||
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
|
||||
background_update = False
|
||||
|
||||
#* Custom cpu model name, empty string to disable.
|
||||
custom_cpu_name = ""
|
||||
|
||||
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
|
||||
#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user".
|
||||
disks_filter = ""
|
||||
|
||||
#* Show graphs instead of meters for memory values.
|
||||
mem_graphs = True
|
||||
|
||||
#* Show mem box below net box instead of above.
|
||||
mem_below_net = False
|
||||
|
||||
#* Count ZFS ARC in cached and available memory.
|
||||
zfs_arc_cached = True
|
||||
|
||||
#* If swap memory should be shown in memory box.
|
||||
show_swap = True
|
||||
|
||||
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
|
||||
swap_disk = True
|
||||
|
||||
#* If mem box should be split to also show disks info.
|
||||
show_disks = True
|
||||
|
||||
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
|
||||
only_physical = True
|
||||
|
||||
#* Read disks list from /etc/fstab. This also disables only_physical.
|
||||
use_fstab = True
|
||||
|
||||
#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
|
||||
zfs_hide_datasets = False
|
||||
|
||||
#* Set to true to show available disk space for privileged users.
|
||||
disk_free_priv = False
|
||||
|
||||
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
|
||||
show_io_stat = True
|
||||
|
||||
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
|
||||
io_mode = False
|
||||
|
||||
#* Set to True to show combined read/write io graphs in io mode.
|
||||
io_graph_combined = False
|
||||
|
||||
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
|
||||
#* Example: "/mnt/media:100 /:20 /boot:1".
|
||||
io_graph_speeds = ""
|
||||
|
||||
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
|
||||
net_download = 100
|
||||
|
||||
net_upload = 100
|
||||
|
||||
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
|
||||
net_auto = True
|
||||
|
||||
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
|
||||
net_sync = True
|
||||
|
||||
#* Starts with the Network Interface specified here.
|
||||
net_iface = ""
|
||||
|
||||
#* Show battery stats in top right if battery is present.
|
||||
show_battery = True
|
||||
|
||||
#* Which battery to use if multiple are present. "Auto" for auto detection.
|
||||
selected_battery = "Auto"
|
||||
|
||||
#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
|
||||
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
|
||||
log_level = "WARNING"
|
||||
@@ -0,0 +1,26 @@
|
||||
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
||||
# The parser is also very primitive, and not human-friendly.
|
||||
fields=0 48 17 18 38 39 40 2 37 46 47 49 1
|
||||
sort_key=46
|
||||
sort_direction=1
|
||||
hide_threads=0
|
||||
hide_kernel_threads=0
|
||||
hide_userland_threads=0
|
||||
shadow_other_users=0
|
||||
show_thread_names=1
|
||||
show_program_path=1
|
||||
highlight_base_name=0
|
||||
highlight_megabytes=1
|
||||
highlight_threads=1
|
||||
tree_view=1
|
||||
header_margin=1
|
||||
detailed_cpu_time=0
|
||||
cpu_count_from_zero=1
|
||||
update_process_names=0
|
||||
account_guest_in_cpu_meter=0
|
||||
color_scheme=0
|
||||
delay=15
|
||||
left_meters=LeftCPUs Memory Swap
|
||||
left_meter_modes=1 1 1
|
||||
right_meters=RightCPUs Tasks LoadAverage Uptime
|
||||
right_meter_modes=1 2 2 2
|
||||
@@ -0,0 +1 @@
|
||||
handle SIGUSR2 nostop noprint
|
||||
@@ -0,0 +1,14 @@
|
||||
[user]
|
||||
email = device@comma.ai
|
||||
name = Comma Device
|
||||
[push]
|
||||
default = simple
|
||||
[pull]
|
||||
rebase = false
|
||||
[url "git@github.com:"]
|
||||
pushInsteadOf = "https://github.com/"
|
||||
[filter "lfs"]
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
required = true
|
||||
process = git-lfs filter-process
|
||||
@@ -0,0 +1 @@
|
||||
.ssh
|
||||
@@ -0,0 +1,22 @@
|
||||
unbind C-b
|
||||
set -g prefix `
|
||||
bind-key ` last-window
|
||||
bind-key e send-prefix
|
||||
|
||||
set -g status-position bottom
|
||||
set -g status-style bg=colour234,fg=colour137,dim
|
||||
set -g status-left ''
|
||||
|
||||
set -g status-left-length 20
|
||||
set -g history-limit 7200
|
||||
set -g status-right '#[fg=colour230,bold]#(cat /data/params/d/DongleId | cut -c 1-16) #[fg=colour233,bg=colour239,bold] #(echo "scale=1; $(cat /sys/devices/virtual/thermal/thermal_zone11/temp)/1000" | bc)°C #[fg=colour233,bg=colour241,bold] %d/%m #[fg=colour233,bg=colour245,bold] %H:%M:%S '
|
||||
set -g status-right-length 70
|
||||
setw -g window-status-current-style fg=colour81,bg=colour238,bold
|
||||
setw -g window-status-current-format ' #I#[fg=colour250]:#[fg=colour255]#W#[fg=colour50]#F '
|
||||
|
||||
setw -g window-status-style fg=colour138,bg=colour235
|
||||
setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F '
|
||||
|
||||
setw -g window-status-bell-style fg=colour255,bg=colour1,bold
|
||||
|
||||
set -g mouse off
|
||||
@@ -0,0 +1,21 @@
|
||||
syntax on
|
||||
set tabstop=2
|
||||
set shiftwidth=2
|
||||
set expandtab
|
||||
set ai
|
||||
set number
|
||||
set hlsearch
|
||||
set ruler
|
||||
set mouse=
|
||||
set viminfo=""
|
||||
set noswapfile
|
||||
highlight Comment ctermfg=green
|
||||
highlight ExtraWhitespace ctermbg=red guibg=red
|
||||
match ExtraWhitespace /\s\+$/
|
||||
|
||||
" syntax highlighting for scons files
|
||||
au BufRead,BufNewFile SConstruct set filetype=python
|
||||
au BufRead,BufNewFile SConscript set filetype=python
|
||||
|
||||
" auto resize splits
|
||||
autocmd VimResized * wincmd =
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
*.ko
|
||||
Executable
BIN
Binary file not shown.
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
sudo mount -o rw,remount /
|
||||
sudo resize2fs $(findmnt -n -o SOURCE /) &>/dev/null || sudo resize2fs $(findmnt -n -o SOURCE /)
|
||||
sudo mount -o remount,size=1500M /var
|
||||
sudo cp -r /usr/default/var/lib/dpkg /var/lib/
|
||||
sudo sed -i '/bionic/s/^/#/' /etc/apt/sources.list
|
||||
sudo sed -i '/hirsute/s/^/#/' /etc/apt/sources.list
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo mount -o ro,remount / || true
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Read the raw device model
|
||||
RAW_MODEL=$(tr -d '\0' < /sys/firmware/devicetree/base/model)
|
||||
|
||||
# Extract the device model (e.g., tici, tizi, mici)
|
||||
MODEL=$(echo "$RAW_MODEL" | sed 's/comma //g' | awk '{print $1}')
|
||||
|
||||
[ -z "$MODEL" ] && MODEL="unknown"
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
SERVICE_NAME="comma SSH - $MODEL - [$HOSTNAME]"
|
||||
|
||||
ALIAS_FILE="/data/params/d_tmp/ApiCache_Device"
|
||||
ALIAS=$(jq -e -r '.alias // empty' "$ALIAS_FILE" 2>/dev/null | grep -E '\S' || echo "$RAW_MODEL")
|
||||
|
||||
# Publish avahi service
|
||||
exec avahi-publish -s "$SERVICE_NAME" _ssh._tcp 22 "vendor=comma" "device=comma" "model=$MODEL" "alias=$ALIAS"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
|
||||
# limit display brightness with display uptime to prevent burn in
|
||||
|
||||
BL_OFF = 4
|
||||
BL_POWER_PATH = "/sys/class/backlight/panel0-backlight/bl_power"
|
||||
BRIGHTNESS_PATH = "/sys/class/backlight/panel0-backlight/brightness"
|
||||
MAX_BRIGHTNESS_PATH= "/sys/devices/platform/soc/soc:qcom,dsi-display@0/max_brightness_percent"
|
||||
|
||||
MAX_PERCENT = 90
|
||||
MIN_PERCENT = 30
|
||||
HOURLY_PERC_DECREASE = 5
|
||||
|
||||
def read(path: str) -> int:
|
||||
try:
|
||||
with open(path) as f:
|
||||
return int(f.read())
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
last_perc = None
|
||||
last_off_ts = time.monotonic()
|
||||
while True:
|
||||
try:
|
||||
# sample brightness and backlight power
|
||||
bl_power = read(BL_POWER_PATH)
|
||||
brightness = read(BRIGHTNESS_PATH)
|
||||
if bl_power == BL_OFF or brightness == 0:
|
||||
last_off_ts = time.monotonic()
|
||||
|
||||
# calculate new max
|
||||
uptime_hours = (time.monotonic() - last_off_ts) / (60*60)
|
||||
clipped_perc = MAX_PERCENT - (HOURLY_PERC_DECREASE*uptime_hours)
|
||||
clipped_perc = int(max(min(clipped_perc, MAX_PERCENT), MIN_PERCENT))
|
||||
|
||||
if clipped_perc != last_perc:
|
||||
with open(MAX_BRIGHTNESS_PATH, 'w') as f:
|
||||
f.write(f"{int(clipped_perc)}\n")
|
||||
last_perc = clipped_perc
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
time.sleep(5)
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#/usr/bin/env bash
|
||||
|
||||
source /etc/profile
|
||||
|
||||
SETUP="/usr/comma/setup"
|
||||
RESET="/usr/comma/reset"
|
||||
CONTINUE="/data/continue.sh"
|
||||
INSTALLER="/tmp/installer"
|
||||
RESET_TRIGGER="/data/__system_reset__"
|
||||
|
||||
# blip power to ~10W to see if the PSU is stable
|
||||
sudo timeout --kill-after=2 5 /home/comma/power_burn_max
|
||||
|
||||
# use max freq to boot up quickly, then limit
|
||||
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
|
||||
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq
|
||||
|
||||
echo "waiting for magic"
|
||||
for i in {1..200}; do
|
||||
if systemctl is-active --quiet magic && [ -S /tmp/drmfd.sock ]; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if systemctl is-active --quiet magic && [ -S /tmp/drmfd.sock ]; then
|
||||
echo "magic ready after ${SECONDS}s"
|
||||
else
|
||||
echo "timed out waiting for magic, ${SECONDS}s"
|
||||
fi
|
||||
|
||||
sudo chown comma: /data
|
||||
sudo chown comma: /data/media
|
||||
|
||||
handle_setup_keys () {
|
||||
# install default SSH key while still in setup
|
||||
if [[ ! -e /data/params/d/GithubSshKeys && ! -e /data/continue.sh ]]; then
|
||||
if [ ! -e /data/params/d ]; then
|
||||
mkdir -p /data/params/d_tmp
|
||||
ln -s /data/params/d_tmp /data/params/d
|
||||
fi
|
||||
|
||||
echo -n 1 > /data/params/d/AdbEnabled
|
||||
echo -n 1 > /data/params/d/SshEnabled
|
||||
cp /usr/comma/setup_keys /data/params/d/GithubSshKeys
|
||||
elif [[ -e /data/params/d/GithubSshKeys && -e /data/continue.sh ]]; then
|
||||
if cmp -s /data/params/d/GithubSshKeys /usr/comma/setup_keys; then
|
||||
rm /data/params/d/AdbEnabled
|
||||
rm /data/params/d/SshEnabled
|
||||
rm /data/params/d/GithubSshKeys
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# factory reset handling
|
||||
if [ ! -f /tmp/booted ]; then
|
||||
touch /tmp/booted
|
||||
if [ -f "$RESET_TRIGGER" ]; then
|
||||
echo "launching system reset, reset trigger present"
|
||||
rm -f $RESET_TRIGGER
|
||||
$RESET
|
||||
elif (( "$(cat /sys/class/input/input2/device/touch_count)" > 4 )); then
|
||||
echo "launching system reset, got taps"
|
||||
$RESET --tap-reset
|
||||
elif ! mountpoint -q /data; then
|
||||
echo "userdata not mounted. loading system reset"
|
||||
$RESET --recover
|
||||
fi
|
||||
fi
|
||||
|
||||
# setup /data/tmp
|
||||
rm -rf /data/tmp
|
||||
mkdir -p /data/tmp
|
||||
|
||||
# symlink vscode to userdata
|
||||
mkdir -p /data/tmp/vscode-server
|
||||
ln -s /data/tmp/vscode-server ~/.vscode-server
|
||||
ln -s /data/tmp/vscode-server ~/.cursor-server
|
||||
ln -s /data/tmp/vscode-server ~/.windsurf-server
|
||||
|
||||
while true; do
|
||||
pkill -f "$SETUP"
|
||||
handle_setup_keys
|
||||
|
||||
if [ -f $CONTINUE ]; then
|
||||
exec "$CONTINUE"
|
||||
fi
|
||||
|
||||
sudo abctl --set_success
|
||||
|
||||
# cleanup installers from previous runs
|
||||
rm -f $INSTALLER
|
||||
pkill -f $INSTALLER
|
||||
|
||||
# run setup and wait for installer
|
||||
$SETUP &
|
||||
echo "waiting for installer"
|
||||
while [ ! -f $INSTALLER ]; do
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
# run installer and wait for continue.sh
|
||||
chmod +x $INSTALLER
|
||||
$INSTALLER &
|
||||
echo "running installer"
|
||||
while [ ! -f $CONTINUE ] && ps -p $! > /dev/null; do
|
||||
sleep 0.1
|
||||
done
|
||||
done
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path("/cache/debug/")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.makedirs(ROOT, exist_ok=True)
|
||||
|
||||
boots = sorted(list(ROOT.iterdir()), key=lambda p: int(p.stem, 16), reverse=True)
|
||||
|
||||
# limit to 100 boots
|
||||
for d in boots[100:]:
|
||||
print("cleaning up", d)
|
||||
shutil.rmtree(d)
|
||||
|
||||
# make a directory for this boot
|
||||
n = 0
|
||||
if len(boots):
|
||||
n = int(boots[0].stem, 16) + 1
|
||||
boot_dir = ROOT / f"{n:08x}"
|
||||
boot_dir.mkdir(parents=True)
|
||||
|
||||
# log some stuff
|
||||
pstore = boot_dir / "pstore"
|
||||
pstore.mkdir()
|
||||
os.system(f"cp /sys/fs/pstore/* {pstore} 2>/dev/null")
|
||||
|
||||
os.system(f"uname -a > {boot_dir / 'uname'}")
|
||||
shutil.copyfile("/VERSION", boot_dir / "VERSION")
|
||||
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ensure the symlinks in the read only rootfs are
|
||||
# backed by real files and directories on userdata.
|
||||
|
||||
# tmpfiles
|
||||
systemd-tmpfiles --create /usr/comma/tmpfiles.conf
|
||||
|
||||
# /var/log/ tmpfs
|
||||
mkdir -p /var/log/
|
||||
chown root:syslog /var/log
|
||||
mount -t tmpfs -o rw,nosuid,nodev,size=128M,mode=755 tmpfs /var/log
|
||||
|
||||
# setup /home
|
||||
mkdir -p /rwtmp/home_work
|
||||
mkdir -p /rwtmp/home_upper
|
||||
chmod 755 /rwtmp/*
|
||||
mount -t overlay overlay -o lowerdir=/usr/default/home,upperdir=/rwtmp/home_upper,workdir=/rwtmp/home_work /home
|
||||
|
||||
# /etc
|
||||
mkdir -p /data/etc
|
||||
touch /data/etc/timezone
|
||||
touch /data/etc/localtime
|
||||
mkdir -p /data/etc/netplan
|
||||
mkdir -p /data/etc/NetworkManager/system-connections
|
||||
|
||||
# /cache
|
||||
chown -R comma:comma /cache/
|
||||
|
||||
# /data/ssh
|
||||
mkdir -p /data/ssh
|
||||
chown comma: /data/ssh
|
||||
|
||||
# /data/tmp - clear out
|
||||
rm -rf /data/tmp/
|
||||
mkdir -p /data/tmp/
|
||||
|
||||
# /data/persist
|
||||
if [[ ! -d /data/persist ]]; then
|
||||
sudo cp -r /system/persist /data
|
||||
fi
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
function gpio {
|
||||
echo "out" > /sys/class/gpio/gpio$1/direction
|
||||
echo $2 > /sys/class/gpio/gpio$1/value
|
||||
}
|
||||
|
||||
pins=(
|
||||
# 27 # SW_3V3_EN
|
||||
# 25 # SW_5V_EN
|
||||
30 # HUB_RST_N
|
||||
49 # SOM_ST_IO
|
||||
134 # ST_BOOT0
|
||||
41 # PANDA_1V8_EN_N
|
||||
50 # LTE_RST_N
|
||||
116 # LTE_PWRKEY
|
||||
124 # ST_RST_N
|
||||
34 # GPS_PWR_EN
|
||||
33 # GPS_SAFEBOOT_N
|
||||
32 # GPS_RST_N
|
||||
52 # LTE_BOOT
|
||||
1264 # POWER ALERT
|
||||
)
|
||||
|
||||
for p in ${pins[@]}; do
|
||||
echo $p
|
||||
|
||||
# this is SSD_3v3 EN on tici
|
||||
if [ "$p" -eq 41 ] && grep -q "comma tici" /sys/firmware/devicetree/base/model; then
|
||||
echo "Skipping $p"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo $p > /sys/class/gpio/export
|
||||
until [ -d /sys/class/gpio/gpio$p ]
|
||||
do
|
||||
sleep .05
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
HUB_RST_N=30
|
||||
gpio $HUB_RST_N 1
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# don't restart whole SoC on subsystem crash
|
||||
for i in {0..7}; do
|
||||
echo "related" | sudo tee /sys/bus/msm_subsys/devices/subsys${i}/restart_level
|
||||
done
|
||||
|
||||
# raise scaling_max so policy=performance can reach the BOOST top step
|
||||
echo 2649600 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
|
||||
echo 2649600 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq
|
||||
|
||||
# boot wifi
|
||||
echo 1 | sudo tee /sys/kernel/boot_wlan/boot_wlan
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:85f6d9e54286a3842920d6967b187478b4e43d6171c331d72d3fb3102106e101
|
||||
size 1401224
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
|
||||
function gpio {
|
||||
echo "out" > /sys/class/gpio/gpio$1/direction
|
||||
echo $2 > /sys/class/gpio/gpio$1/value
|
||||
}
|
||||
|
||||
HUB_RST_N=30
|
||||
LTE_RST_N=50
|
||||
LTE_BOOT=52
|
||||
LTE_PWRKEY=116
|
||||
|
||||
function is_modem_up {
|
||||
if lsusb -d "0x05c6:" >/dev/null 2>&1 || lsusb -d "0x2c7c:" >/dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function reset {
|
||||
echo " Resetting..."
|
||||
gpio $LTE_RST_N 1
|
||||
sleep 1
|
||||
gpio $LTE_RST_N 0
|
||||
}
|
||||
|
||||
function power_button {
|
||||
echo " Pulsing power button..."
|
||||
gpio $LTE_PWRKEY 1
|
||||
sleep 1
|
||||
gpio $LTE_PWRKEY 0
|
||||
}
|
||||
|
||||
function is_online {
|
||||
echo " Waiting until the modem comes online..."
|
||||
|
||||
for i in {0..30}; do
|
||||
if is_modem_up; then
|
||||
echo " Modem is online!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo " Waiting..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function is_offline {
|
||||
echo " Waiting until the modem goes offline..."
|
||||
|
||||
for i in {0..30}; do
|
||||
if ! is_modem_up; then
|
||||
echo " Modem is offline!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo " Waiting..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Boot into the regular mode
|
||||
gpio $LTE_BOOT 0
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting LTE..."
|
||||
|
||||
reset
|
||||
power_button
|
||||
until is_online; do
|
||||
reset
|
||||
power_button
|
||||
done
|
||||
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping LTE..."
|
||||
|
||||
if is_online; then
|
||||
power_button
|
||||
fi
|
||||
|
||||
;;
|
||||
stop_blocking)
|
||||
echo "Stopping LTE..."
|
||||
|
||||
if is_online; then
|
||||
power_button
|
||||
fi
|
||||
|
||||
until is_offline; do
|
||||
power_button
|
||||
done
|
||||
|
||||
;;
|
||||
*)
|
||||
echo "Specify either start or stop as first argument!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
import os, socket, struct, subprocess, threading, time
|
||||
from array import array
|
||||
|
||||
import pyray as rl
|
||||
|
||||
UPDATER_PATH = "/usr/comma/updater"
|
||||
WESTON_RUNTIME_DIR = "/var/tmp/weston"
|
||||
WESTON_SOCK_PATH = os.path.join(WESTON_RUNTIME_DIR, "wayland-0")
|
||||
|
||||
SOCK_PATH = "/tmp/drmfd.sock"
|
||||
DRM_DEVICE = "/dev/dri/card0"
|
||||
BACKGROUND = "/usr/comma/bg.jpg"
|
||||
|
||||
# This is needed to keep the old updater working. Updater used to be stored in
|
||||
# openpilot directly instead of in AGNOS. This will intercept the old updater
|
||||
# trying to use a Weston socket and start our own.
|
||||
def updater_weston():
|
||||
os.makedirs(WESTON_RUNTIME_DIR, exist_ok=True)
|
||||
os.chmod(WESTON_RUNTIME_DIR, 0o700)
|
||||
|
||||
try:
|
||||
os.unlink(WESTON_SOCK_PATH)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
server.bind(WESTON_SOCK_PATH)
|
||||
server.listen(1)
|
||||
|
||||
while True:
|
||||
try:
|
||||
client, _ = server.accept()
|
||||
creds = client.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
|
||||
pid, _, _ = struct.unpack("3i", creds)
|
||||
with open(f"/proc/{pid}/comm", "r") as f:
|
||||
comm = f.read().strip()
|
||||
if comm == "updater":
|
||||
with open(f"/proc/{pid}/cmdline", "rb") as f:
|
||||
updater, manifest = [p.decode("utf-8") for p in f.read().split(b"\0") if p != b""][1:]
|
||||
env = os.environ.copy()
|
||||
env.pop("DRM_FD", None)
|
||||
subprocess.run([UPDATER_PATH, updater, manifest], env=env)
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
client.shutdown(socket.SHUT_RDWR)
|
||||
client.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def power_screen():
|
||||
try:
|
||||
with open("/sys/class/backlight/panel0-backlight/bl_power", "w") as f:
|
||||
f.write("0")
|
||||
with open("/sys/class/backlight/panel0-backlight/max_brightness") as f:
|
||||
max_brightness = int((int(f.read().strip()) / 100) * 65)
|
||||
with open("/sys/class/backlight/panel0-backlight/brightness", "w") as f:
|
||||
f.write(str(max_brightness))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def show_background(tex, pos):
|
||||
rl.begin_drawing()
|
||||
rl.draw_texture(tex, int(pos.x), int(pos.y), rl.WHITE)
|
||||
rl.end_drawing()
|
||||
power_screen()
|
||||
|
||||
def handle_client(client, drm_master):
|
||||
try:
|
||||
drm_master_dup = os.dup(drm_master)
|
||||
client.sendmsg([b"x"], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array("i", [drm_master_dup]).tobytes())])
|
||||
client.recv(1)
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
os.close(drm_master_dup)
|
||||
client.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def main():
|
||||
threading.Thread(target=updater_weston, daemon=True).start()
|
||||
|
||||
while True:
|
||||
try:
|
||||
drm_master = os.open(DRM_DEVICE, os.O_RDWR | os.O_CLOEXEC)
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
||||
time.sleep(0.1)
|
||||
|
||||
os.environ['DRM_FD'] = str(drm_master)
|
||||
rl.init_window(0, 0, "not weston")
|
||||
img = rl.load_image(BACKGROUND)
|
||||
rl.image_resize(img, rl.get_screen_width(), rl.get_screen_width()//2)
|
||||
tex = rl.load_texture_from_image(img)
|
||||
rl.set_texture_filter(tex, rl.TextureFilter.TEXTURE_FILTER_BILINEAR)
|
||||
pos = rl.Vector2((rl.get_screen_width() - tex.width)/2.0, (rl.get_screen_height() - tex.height)/2.0)
|
||||
rl.unload_image(img)
|
||||
show_background(tex, pos)
|
||||
|
||||
try:
|
||||
os.unlink(SOCK_PATH)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
server.bind(SOCK_PATH)
|
||||
server.settimeout(0.1)
|
||||
server.listen(1)
|
||||
|
||||
clients = set()
|
||||
need_background = False
|
||||
|
||||
while True:
|
||||
dead = [t for t in list(clients) if not t.is_alive()]
|
||||
for t in dead:
|
||||
t.join()
|
||||
clients.discard(t)
|
||||
if not clients and need_background:
|
||||
need_background = False
|
||||
show_background(tex, pos)
|
||||
|
||||
try:
|
||||
client, _ = server.accept()
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
need_background = True
|
||||
t = threading.Thread(target=handle_client, args=(client, drm_master), daemon=True)
|
||||
t.start()
|
||||
clients.add(t)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
BIN
Binary file not shown.
+125
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import time
|
||||
import smbus2
|
||||
import select
|
||||
import datetime
|
||||
import subprocess
|
||||
|
||||
ALERT_VOLTAGE_THRESHOLD_mV = 4000
|
||||
|
||||
POWER_ALERT_GPIO_PIN = 1264
|
||||
INA231_BUS = 0
|
||||
INA231_ADDRESS = 0x40
|
||||
INA231_MASK_REG = 0x06
|
||||
INA231_LIMIT_REG = 0x07
|
||||
INA231_MASK_CONFIG = (1 << 12) # Bus undervoltage, not latching
|
||||
INA231_BUS_VOLTAGE_LSB_mV = 1.25
|
||||
VOLTAGE_FILE = "/sys/class/hwmon/hwmon1/in1_input"
|
||||
PARAM_FILE = "/data/params/d/LastPowerDropDetected"
|
||||
|
||||
alert_pin_base = f"/sys/class/gpio/gpio{POWER_ALERT_GPIO_PIN}/"
|
||||
|
||||
def set_screen_power(on):
|
||||
with open("/sys/class/backlight/panel0-backlight/bl_power", "w") as f:
|
||||
f.write("0\n" if on else "4\n")
|
||||
|
||||
def get_screen_power():
|
||||
with open("/sys/class/backlight/panel0-backlight/bl_power", "r") as f:
|
||||
return f.read(1) == "0"
|
||||
|
||||
def swap_word_bytes(val):
|
||||
return ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8)
|
||||
|
||||
def write_once(path, value):
|
||||
with open(path, 'w') as f:
|
||||
f.write(value)
|
||||
|
||||
def init_alert_pin():
|
||||
write_once(os.path.join(alert_pin_base, 'direction'), 'in')
|
||||
write_once(os.path.join(alert_pin_base, 'edge'), 'falling')
|
||||
|
||||
def init_voltage_alert():
|
||||
with smbus2.SMBus(INA231_BUS) as bus:
|
||||
bus.write_word_data(INA231_ADDRESS, INA231_MASK_REG, swap_word_bytes(INA231_MASK_CONFIG), force=True)
|
||||
bus.write_word_data(INA231_ADDRESS, INA231_LIMIT_REG, swap_word_bytes(int(ALERT_VOLTAGE_THRESHOLD_mV / INA231_BUS_VOLTAGE_LSB_mV)), force=True)
|
||||
|
||||
def read_voltage_mV():
|
||||
with open(VOLTAGE_FILE, "r") as f:
|
||||
return int(f.read().strip())
|
||||
|
||||
def read_current_mA():
|
||||
with open("/sys/class/hwmon/hwmon1/curr1_input", "r") as f:
|
||||
return int(f.read().strip())
|
||||
|
||||
def update_param(stage, v_initial, i_initial, v_final, i_final):
|
||||
try:
|
||||
os.umask(0)
|
||||
with open(os.open(PARAM_FILE, os.O_CREAT | os.O_WRONLY, 0o777), 'a') as f:
|
||||
f.write(f"{stage} {datetime.datetime.now()}, ({v_initial=} mV, {i_initial=} mA) -> ({v_final=} mV, {i_final=} mA)\n")
|
||||
f.flush()
|
||||
os.fdatasync(f.fileno())
|
||||
os.fsync(f.fileno())
|
||||
except Exception:
|
||||
print("Failed to update LastControlledShutdown param")
|
||||
|
||||
def printk(msg):
|
||||
with open('/dev/kmsg', 'w') as kmsg:
|
||||
kmsg.write(f"<3>[power drop monitor] {msg}\n")
|
||||
print(msg)
|
||||
|
||||
def perform_controlled_shutdown():
|
||||
printk("Power alert received!")
|
||||
|
||||
prev_screen_power = get_screen_power()
|
||||
set_screen_power(False)
|
||||
|
||||
v_initial = read_voltage_mV()
|
||||
i_initial = read_current_mA()
|
||||
update_param("PREP", v_initial, i_initial, None, None)
|
||||
|
||||
# Wait 100ms before checking voltage level again
|
||||
t = time.monotonic()
|
||||
while time.monotonic() - t < 0.1:
|
||||
time.sleep(0.01)
|
||||
|
||||
v_now = read_voltage_mV()
|
||||
i_now = read_current_mA()
|
||||
if v_now > ALERT_VOLTAGE_THRESHOLD_mV:
|
||||
printk("Voltage restored. Not shutting down!")
|
||||
update_param("ABORT", v_initial, i_initial, v_now, i_now)
|
||||
set_screen_power(prev_screen_power)
|
||||
return
|
||||
|
||||
update_param("SHUTDOWN", v_initial, i_initial, v_now, i_now)
|
||||
|
||||
# Kill services that draw a lot of power
|
||||
printk("Killing services")
|
||||
subprocess.call(["/usr/bin/systemctl", "kill", "--signal=9", "comma"])
|
||||
set_screen_power(False)
|
||||
|
||||
printk("Halt")
|
||||
subprocess.call(["/usr/sbin/halt", "-f"])
|
||||
|
||||
if __name__ == '__main__':
|
||||
init_alert_pin()
|
||||
init_voltage_alert()
|
||||
|
||||
# Setup interrupt
|
||||
f = open(os.path.join(alert_pin_base, 'value'), 'r')
|
||||
po = select.poll()
|
||||
po.register(f, select.POLLPRI)
|
||||
|
||||
# Interrupt loop
|
||||
f.read()
|
||||
while True:
|
||||
try:
|
||||
events = po.poll(60000)
|
||||
if events:
|
||||
f.seek(0)
|
||||
state_last = f.read().strip()
|
||||
if int(state_last) == 0:
|
||||
perform_controlled_shutdown()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import fcntl
|
||||
import struct
|
||||
import threading
|
||||
import subprocess
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
FN = "/var/tmp/power_watchdog"
|
||||
PARAM_FILE = "/data/params/d/LastAgnosPowerMonitorShutdown"
|
||||
THRESHOLD = timedelta(hours=1.0)
|
||||
timestamps = {}
|
||||
|
||||
|
||||
def read(path: str, num: bool = False):
|
||||
try:
|
||||
with open(path) as f:
|
||||
if num:
|
||||
return float(f.read())
|
||||
return f.read()
|
||||
except Exception:
|
||||
return 0 if num else ""
|
||||
|
||||
|
||||
def check_touches():
|
||||
global timestamps
|
||||
|
||||
event_format = "llHHi"
|
||||
event_size = struct.calcsize(event_format)
|
||||
|
||||
with open("/dev/input/by-path/platform-894000.i2c-event", "rb") as event_file:
|
||||
fcntl.fcntl(event_file, fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
while True:
|
||||
while (event := event_file.read(event_size)):
|
||||
(sec, usec, etype, code, value) = struct.unpack(event_format, event)
|
||||
if etype != 0 or code != 0 or value != 0:
|
||||
timestamps['touch'] = time.monotonic()
|
||||
time.sleep(60)
|
||||
|
||||
def ssh_active():
|
||||
p = subprocess.run("ss | grep ssh", shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
return p.returncode == 0
|
||||
|
||||
def write_param():
|
||||
try:
|
||||
os.umask(0)
|
||||
with open(os.open(PARAM_FILE, os.O_CREAT | os.O_WRONLY, 0o777), 'a') as f:
|
||||
f.write(f"SHUTDOWN datetime={datetime.now()}, time.monotonic={time.monotonic()}, {timestamps=}\n")
|
||||
f.flush()
|
||||
os.fdatasync(f.fileno())
|
||||
os.fsync(f.fileno())
|
||||
except Exception as e:
|
||||
print(f"Failed to write param: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# we limit worst-case power usage when openpilot isn't managing it,
|
||||
# e.g. while building or during setup.
|
||||
|
||||
threading.Thread(target=check_touches, daemon=True).start()
|
||||
|
||||
timestamps['startup'] = time.monotonic()
|
||||
while True:
|
||||
timestamps['watchdog'] = read(FN, True)
|
||||
if ssh_active():
|
||||
timestamps['ssh'] = time.monotonic()
|
||||
if read("/data/params/d/IsEngaged").startswith("1"):
|
||||
timestamps['engaged'] = time.monotonic()
|
||||
|
||||
# store a max such that we can't go backwards
|
||||
timestamps['max'] = max(timestamps.values())
|
||||
|
||||
# time to shutoff?
|
||||
dt = timedelta(seconds=time.monotonic() - max(timestamps.values()))
|
||||
if dt > THRESHOLD:
|
||||
write_param()
|
||||
os.system("sudo poweroff")
|
||||
|
||||
print((THRESHOLD - dt), "until shutdown", f"/ {timestamps=}")
|
||||
time.sleep(60)
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b22bee10b5c17be9a64affd0d3474d6b0e7e4fcca7d14c083ecd6f3fa8b2975e
|
||||
size 24709201
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import struct
|
||||
|
||||
GAMMA_CURVES_FILE = "/persist/comma/dwo_gamma_curves"
|
||||
COMMAND_FILE = "/sys/kernel/debug/dsi_dwo_video_display/mipi_command"
|
||||
|
||||
GAMMA_ADDR = [
|
||||
[(0x00, 0x01), (0x02, 0x03), (0x04, 0x05), (0x06, 0x07), (0x08, 0x09), (0x0A, 0x0B), (0x0C, 0x0D), (0x0E, 0x0F), (0x10, 0x11), (0x12, 0x13), (0x14, 0x15), (0x16, 0x17), (0x18, 0x19), (0x1A, 0x1B), (0x1C, 0x1D), (0x1E, 0x1F), (0x20, 0x21), (0x22, 0x23), (0x24, 0x25), (0x26, 0x27), (0x28, 0x29), (0x2A, 0x2B), (0x2D, 0x2F), (0x30, 0x31), (0x32, 0x33)],
|
||||
[(0x34, 0x35), (0x36, 0x37), (0x38, 0x39), (0x3A, 0x3B), (0x3D, 0x3F), (0x40, 0x41), (0x42, 0x43), (0x44, 0x45), (0x46, 0x47), (0x48, 0x49), (0x4A, 0x4B), (0x4C, 0x4D), (0x4E, 0x4F), (0x50, 0x51), (0x52, 0x53), (0x54, 0x55), (0x56, 0x58), (0x59, 0x5A), (0x5B, 0x5C), (0x5D, 0x5E), (0x5F, 0x60), (0x61, 0x62), (0x63, 0x64), (0x65, 0x66), (0x67, 0x68)],
|
||||
[(0x69, 0x6A), (0x6B, 0x6C), (0x6D, 0x6E), (0x6F, 0x70), (0x71, 0x72), (0x73, 0x74), (0x75, 0x76), (0x77, 0x78), (0x79, 0x7A), (0x7B, 0x7C), (0x7D, 0x7E), (0x7F, 0x80), (0x81, 0x82), (0x83, 0x84), (0x85, 0x86), (0x87, 0x88), (0x89, 0x8A), (0x8B, 0x8C), (0x8D, 0x8E), (0x8F, 0x90), (0x91, 0x92), (0x93, 0x94), (0x95, 0x96), (0x97, 0x98), (0x99, 0x9A)],
|
||||
]
|
||||
|
||||
def command_mode(mode):
|
||||
return f"39 01 00 00 0A 00 02 FE {((0b1010 << 4) | mode):02X}"
|
||||
|
||||
def pack_command(command_str):
|
||||
command_buf = bytes(map(lambda x: int(x, base=16), command_str.strip().split()))
|
||||
return struct.pack(f"i{len(command_buf)}s", len(command_buf), command_buf)
|
||||
|
||||
def set_gamma(gamma):
|
||||
cmds = [command_mode(2)]
|
||||
for color_idx in range(3):
|
||||
for i, val in reversed(list(enumerate(gamma[color_idx]))):
|
||||
msb, lsb = GAMMA_ADDR[color_idx][i]
|
||||
cmds.append(f"39 0F 00 00 0A 00 02 {msb:02X} {(val >> 8) & 0xFF:02X}")
|
||||
cmds.append(f"39 {'01' if i % 10 == 0 else '0F'} 00 00 0A 00 02 {lsb:02X} {val & 0xFF:02X}")
|
||||
cmds.append(command_mode(0))
|
||||
|
||||
data = b"".join(pack_command(c) for c in cmds)
|
||||
with open(COMMAND_FILE, "wb") as f:
|
||||
f.write(data)
|
||||
print("Successfully setup screen calibration")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not os.path.exists(GAMMA_CURVES_FILE):
|
||||
print("No gamma curves found")
|
||||
exit(0)
|
||||
|
||||
assert os.path.exists(COMMAND_FILE), "MIPI command interface not found"
|
||||
|
||||
with open(GAMMA_CURVES_FILE, "r") as f:
|
||||
gamma = [[int(x, 16) for x in l.strip().split()] for l in f]
|
||||
|
||||
set_gamma(gamma)
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
SERIAL="$(cat /proc/cmdline | sed -e 's/^.*androidboot.serialno=//' -e 's/ .*$//')"
|
||||
echo "serial: '$SERIAL'"
|
||||
sysctl kernel.hostname="comma-$SERIAL"
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
setup() {
|
||||
# Check if /config is already mounted
|
||||
if ! mountpoint -q /config; then
|
||||
sudo mount -t configfs none /config
|
||||
else
|
||||
echo "/config is already mounted."
|
||||
fi
|
||||
|
||||
# Create USB gadget directory structure
|
||||
sudo mkdir -p /config/usb_gadget/g1
|
||||
cd /config/usb_gadget/g1
|
||||
sudo mkdir -p strings/0x409
|
||||
sudo mkdir -p configs/c.1/strings/0x409
|
||||
sudo mkdir -p functions/ncm.0
|
||||
|
||||
# Set Vendor and Product ID
|
||||
echo 0x04D8 | sudo tee idVendor
|
||||
echo 0x1234 | sudo tee idProduct
|
||||
|
||||
# Set strings
|
||||
echo "$(cat /proc/cmdline | sed -e 's/^.*androidboot.serialno=//' -e 's/ .*$//')" | sudo tee strings/0x409/serialnumber
|
||||
echo "comma.ai" | sudo tee strings/0x409/manufacturer
|
||||
echo "Linux USB Gadget" | sudo tee strings/0x409/product
|
||||
echo 250 | sudo tee configs/c.1/MaxPower
|
||||
|
||||
# Create ADB function
|
||||
sudo mkdir -p functions/ffs.adb
|
||||
sudo mkdir -p /dev/usb-ffs/adb
|
||||
if ! mountpoint -q /dev/usb-ffs/adb; then
|
||||
sudo mount -t functionfs adb /dev/usb-ffs/adb
|
||||
else
|
||||
echo "/dev/usb-ffs/adb is already mounted"
|
||||
fi
|
||||
|
||||
# Link both functions to configuration
|
||||
echo "NCM+ADB" | sudo tee configs/c.1/strings/0x409/configuration
|
||||
sudo rm -f configs/c.1/ncm.0
|
||||
sudo rm -f configs/c.1/ffs.adb
|
||||
sudo ln -s functions/ncm.0 configs/c.1/
|
||||
sudo ln -s functions/ffs.adb configs/c.1/
|
||||
}
|
||||
|
||||
start() {
|
||||
setprop service.adb.tcp.port -1
|
||||
|
||||
cd /config/usb_gadget/g1
|
||||
echo "a600000.dwc3" | sudo tee UDC
|
||||
}
|
||||
|
||||
stop() {
|
||||
if [ -d "/config/usb_gadget/g1" ]; then
|
||||
cd /config/usb_gadget/g1
|
||||
echo "" | sudo tee UDC
|
||||
fi
|
||||
}
|
||||
|
||||
ADB_PARAM="/data/params/d/AdbEnabled"
|
||||
if [ -f "$ADB_PARAM" ] && [ "$(< $ADB_PARAM)" == "1" ]; then
|
||||
echo "Enabling ADB"
|
||||
|
||||
setup
|
||||
systemctl start adbd
|
||||
sleep 1 # adbd does some setup before we can enable the gadget
|
||||
start
|
||||
else
|
||||
echo "Disabling ADB"
|
||||
|
||||
systemctl stop adbd
|
||||
stop
|
||||
fi
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
SSH_PARAM="/data/params/d/SshEnabled"
|
||||
if [ -f "$SSH_PARAM" ] && [ "$(< $SSH_PARAM)" == "1" ]; then
|
||||
echo "Enabling SSH"
|
||||
systemctl start ssh
|
||||
else
|
||||
echo "Disabling SSH"
|
||||
systemctl stop ssh
|
||||
fi
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b3efec8b3974e6064c6ddd9100527fcb475a1fcf148550390c77ec97a2bf37ec
|
||||
size 24709201
|
||||
@@ -0,0 +1 @@
|
||||
from="127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+iXXq30Tq+J5NKat3KWHCzcmwZ55nGh6WggAqECa5CasBlM9VeROpVu3beA+5h0MibRgbD4DMtVXBt6gEvZ8nd04E7eLA9LTZyFDZ7SkSOVj4oXOQsT0GnJmKrASW5KslTWqVzTfo2XCtZ+004ikLxmyFeBO8NOcErW1pa8gFdQDToH9FrA7kgysic/XVESTOoe7XlzRoe/eZacEQ+jtnmFd21A4aEADkk00Ahjr0uKaJiLUAPatxs2icIXWpgYtfqqtaKF23wSt61OTu6cAwXbOWr3m+IUSRUO0IRzEIQS3z1jfd1svgzSgSSwZ1Lhj4AoKxIEAIc8qJrO4uymCJ public
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
PIP_PATH=/usr/local/venv/bin/pip
|
||||
export TMPDIR=/tmp/pip-tmp
|
||||
|
||||
# setup large tmp for install
|
||||
mkdir -p $TMPDIR
|
||||
sudo mount -o remount,size=2G /tmp
|
||||
sudo mount -o rw,remount /
|
||||
sudo resize2fs $(findmnt -n -o SOURCE /) &>/dev/null || sudo resize2fs $(findmnt -n -o SOURCE /)
|
||||
|
||||
# run command
|
||||
sudo TMPDIR=$TMPDIR PIP_NO_CACHE_DIR=1 $PIP_PATH "$@"
|
||||
|
||||
# cleanup
|
||||
sudo mount -o ro,remount /
|
||||
sudo rm -rf $TMPDIR
|
||||
sudo mount -o remount /tmp
|
||||
+1
@@ -0,0 +1 @@
|
||||
pip
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
UV_PATH=/usr/bin/uv
|
||||
export TMPDIR=/tmp/uv-tmp
|
||||
|
||||
# setup large tmp for install
|
||||
mkdir -p $TMPDIR
|
||||
sudo mount -o remount,size=2G /tmp
|
||||
sudo mount -o rw,remount /
|
||||
sudo resize2fs $(findmnt -n -o SOURCE /) &>/dev/null || sudo resize2fs $(findmnt -n -o SOURCE /)
|
||||
|
||||
# run command
|
||||
sudo -E TMPDIR=$TMPDIR UV_NO_CACHE=1 $UV_PATH "$@"
|
||||
|
||||
# cleanup
|
||||
sudo mount -o ro,remount /
|
||||
sudo rm -rf $TMPDIR
|
||||
sudo mount -o remount /tmp
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
###############################################################################
|
||||
#
|
||||
# This script is used for administration of the Hexagon DSP
|
||||
#
|
||||
# Copyright (c) 2012-2016 Qualcomm Technologies, Inc.
|
||||
# All Rights Reserved.
|
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
KEEP_ALIVE=0
|
||||
subsys_name=""
|
||||
|
||||
echo -n "/firmware/image" > /sys/module/firmware_class/parameters/path
|
||||
|
||||
# Wait for adsp.mdt to show up
|
||||
count=0
|
||||
while [ ! -s /firmware/image/adsp.mdt ]; do
|
||||
sleep 0.1
|
||||
# wait 10s for /firmware mounted
|
||||
count=$(( $count + 1 ))
|
||||
if [ $count -ge 100 ]; then
|
||||
echo "[ERROR] Can not find the adsp's firmware"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
for subsys in `ls /sys/bus/msm_subsys/devices`; do
|
||||
name=`cat /sys/bus/msm_subsys/devices/${subsys}/name`
|
||||
if [ "`cat /sys/bus/msm_subsys/devices/${subsys}/name`" = "adsp" ]; then
|
||||
subsys_name="${subsys}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$KEEP_ALIVE" = "1" ]; then
|
||||
if [ -n "${subsys_name}" ]; then
|
||||
sysctl -w kernel.panic=0
|
||||
echo 1 > /sys/bus/msm_subsys/devices/${subsys_name}/keep_alive
|
||||
else
|
||||
echo "[ERROR] Can not keep adsp alive"
|
||||
fi
|
||||
fi
|
||||
|
||||
# FIXME: See ATL-3054
|
||||
echo 1 > /sys/module/subsystem_restart/parameters/enable_debug
|
||||
# Bring adsp out of reset
|
||||
echo "[INFO] Bringing adsp out of reset"
|
||||
echo "${subsys_name}"
|
||||
echo 1 > /sys/kernel/boot_adsp/boot
|
||||
|
||||
# wait boot finished
|
||||
if [ -n "${subsys_name}" ]; then
|
||||
count=0
|
||||
state=`cat /sys/bus/msm_subsys/devices/${subsys_name}/state`
|
||||
while [ "${state}" != "ONLINE" ]; do
|
||||
# wait 2s for subsys boot finished
|
||||
count=$(( $count + 1 ))
|
||||
if [ $count -ge 200 ]; then
|
||||
echo "[ERROR] adsp fail to boot"
|
||||
exit 1
|
||||
fi
|
||||
state=`cat /sys/bus/msm_subsys/devices/${subsys_name}/state`
|
||||
sleep 0.1
|
||||
done
|
||||
fi
|
||||
|
||||
Executable
+161
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
from smbus2 import SMBus
|
||||
from collections import namedtuple
|
||||
from typing import List
|
||||
|
||||
# https://datasheets.maximintegrated.com/en/ds/MAX98089.pdf
|
||||
|
||||
AmpConfig = namedtuple('AmpConfig', ['name', 'value', 'register', 'offset', 'mask'])
|
||||
EQParams = namedtuple('EQParams', ['K', 'k1', 'k2', 'c1', 'c2'])
|
||||
|
||||
def configs_from_eq_params(base, eq_params):
|
||||
return [
|
||||
AmpConfig("K (high)", (eq_params.K >> 8), base, 0, 0xFF),
|
||||
AmpConfig("K (low)", (eq_params.K & 0xFF), base + 1, 0, 0xFF),
|
||||
AmpConfig("k1 (high)", (eq_params.k1 >> 8), base + 2, 0, 0xFF),
|
||||
AmpConfig("k1 (low)", (eq_params.k1 & 0xFF), base + 3, 0, 0xFF),
|
||||
AmpConfig("k2 (high)", (eq_params.k2 >> 8), base + 4, 0, 0xFF),
|
||||
AmpConfig("k2 (low)", (eq_params.k2 & 0xFF), base + 5, 0, 0xFF),
|
||||
AmpConfig("c1 (high)", (eq_params.c1 >> 8), base + 6, 0, 0xFF),
|
||||
AmpConfig("c1 (low)", (eq_params.c1 & 0xFF), base + 7, 0, 0xFF),
|
||||
AmpConfig("c2 (high)", (eq_params.c2 >> 8), base + 8, 0, 0xFF),
|
||||
AmpConfig("c2 (low)", (eq_params.c2 & 0xFF), base + 9, 0, 0xFF),
|
||||
]
|
||||
|
||||
BASE_CONFIG = [
|
||||
AmpConfig("MCLK prescaler", 0b01, 0x10, 4, 0b00110000),
|
||||
AmpConfig("PM: enable speakers", 0b11, 0x4D, 4, 0b00110000),
|
||||
AmpConfig("PM: enable DACs", 0b11, 0x4D, 0, 0b00000011),
|
||||
AmpConfig("Enable PLL1", 0b1, 0x12, 7, 0b10000000),
|
||||
AmpConfig("Enable PLL2", 0b1, 0x1A, 7, 0b10000000),
|
||||
AmpConfig("DAI1: I2S mode", 0b00100, 0x14, 2, 0b01111100),
|
||||
AmpConfig("DAI2: I2S mode", 0b00100, 0x1C, 2, 0b01111100),
|
||||
AmpConfig("DAI1 Passband filtering: music mode", 0b1, 0x18, 7, 0b10000000),
|
||||
AmpConfig("DAI1 voice mode gain (DV1G)", 0b00, 0x2F, 4, 0b00110000),
|
||||
AmpConfig("DAI1 attenuation (DV1)", 0x0, 0x2F, 0, 0b00001111),
|
||||
AmpConfig("DAI2 attenuation (DV2)", 0x0, 0x31, 0, 0b00001111),
|
||||
AmpConfig("DAI2: DC blocking", 0b1, 0x20, 0, 0b00000001),
|
||||
AmpConfig("DAI2: High sample rate", 0b0, 0x20, 3, 0b00001000),
|
||||
AmpConfig("ALC enable", 0b1, 0x43, 7, 0b10000000),
|
||||
AmpConfig("ALC/excursion limiter release time", 0b101, 0x43, 4, 0b01110000),
|
||||
AmpConfig("ALC multiband enable", 0b1, 0x43, 3, 0b00001000),
|
||||
AmpConfig("DAI1 EQ enable", 0b0, 0x49, 0, 0b00000001),
|
||||
AmpConfig("DAI2 EQ clip detection disabled", 0b1, 0x32, 4, 0b00010000),
|
||||
AmpConfig("DAI2 EQ attenuation", 0x5, 0x32, 0, 0b00001111),
|
||||
AmpConfig("Excursion limiter upper corner freq", 0b100, 0x41, 4, 0b01110000),
|
||||
AmpConfig("Excursion limiter lower corner freq", 0b00, 0x41, 0, 0b00000011),
|
||||
AmpConfig("Excursion limiter threshold", 0b000, 0x42, 0, 0b00001111),
|
||||
AmpConfig("Distortion limit (THDCLP)", 0x6, 0x46, 4, 0b11110000),
|
||||
AmpConfig("Distortion limiter release time constant", 0b0, 0x46, 0, 0b00000001),
|
||||
AmpConfig("Right DAC input mixer: DAI1 left", 0b0, 0x22, 3, 0b00001000),
|
||||
AmpConfig("Right DAC input mixer: DAI1 right", 0b0, 0x22, 2, 0b00000100),
|
||||
AmpConfig("Right DAC input mixer: DAI2 left", 0b1, 0x22, 1, 0b00000010),
|
||||
AmpConfig("Right DAC input mixer: DAI2 right", 0b0, 0x22, 0, 0b00000001),
|
||||
AmpConfig("DAI1 audio port selector", 0b10, 0x16, 6, 0b11000000),
|
||||
AmpConfig("DAI1 in/output enable", 0b11, 0x16, 0, 0b11),
|
||||
AmpConfig("DAI2 audio port selector", 0b01, 0x1E, 6, 0b11000000),
|
||||
AmpConfig("DAI2 in/output enable", 0b11, 0x1E, 0, 0b11),
|
||||
AmpConfig("Enable left digital microphone", 0b1, 0x48, 5, 0b00100000),
|
||||
AmpConfig("Enable right digital microphone", 0b1, 0x48, 4, 0b00010000),
|
||||
AmpConfig("Enhanced volume smoothing disabled", 0b0, 0x49, 7, 0b10000000),
|
||||
AmpConfig("Volume adjustment smoothing disabled", 0b0, 0x49, 6, 0b01000000),
|
||||
AmpConfig("Zero-crossing detection disabled", 0b0, 0x49, 5, 0b00100000),
|
||||
]
|
||||
|
||||
CONFIGS = {
|
||||
"tici": [
|
||||
AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111),
|
||||
AmpConfig("Right Speaker Mixer Gain", 0b00, 0x2D, 2, 0b00001100),
|
||||
AmpConfig("Right speaker output volume", 0x1c, 0x3E, 0, 0b00011111),
|
||||
AmpConfig("DAI2 EQ enable", 0b1, 0x49, 1, 0b00000010),
|
||||
|
||||
*configs_from_eq_params(0x84, EQParams(0x274F, 0xC0FF, 0x3BF9, 0x0B3C, 0x1656)),
|
||||
*configs_from_eq_params(0x8E, EQParams(0x1009, 0xC6BF, 0x2952, 0x1C97, 0x30DF)),
|
||||
*configs_from_eq_params(0x98, EQParams(0x0F75, 0xCBE5, 0x0ED2, 0x2528, 0x3E42)),
|
||||
*configs_from_eq_params(0xA2, EQParams(0x091F, 0x3D4C, 0xCE11, 0x1266, 0x2807)),
|
||||
*configs_from_eq_params(0xAC, EQParams(0x0A9E, 0x3F20, 0xE573, 0x0A8B, 0x3A3B)),
|
||||
],
|
||||
"tizi": [
|
||||
AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111),
|
||||
AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111),
|
||||
AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011),
|
||||
AmpConfig("Right Speaker Mixer Gain", 0b00, 0x2D, 2, 0b00001100),
|
||||
AmpConfig("Left speaker output volume", 0x17, 0x3D, 0, 0b00011111),
|
||||
AmpConfig("Right speaker output volume", 0x17, 0x3E, 0, 0b00011111),
|
||||
|
||||
AmpConfig("DAI2 EQ enable", 0b0, 0x49, 1, 0b00000010),
|
||||
AmpConfig("DAI2: DC blocking", 0b0, 0x20, 0, 0b00000001),
|
||||
AmpConfig("ALC enable", 0b0, 0x43, 7, 0b10000000),
|
||||
AmpConfig("DAI2 EQ attenuation", 0x2, 0x32, 0, 0b00001111),
|
||||
AmpConfig("Excursion limiter upper corner freq", 0b001, 0x41, 4, 0b01110000),
|
||||
AmpConfig("Excursion limiter threshold", 0b100, 0x42, 0, 0b00001111),
|
||||
AmpConfig("Distortion limit (THDCLP)", 0x0, 0x46, 4, 0b11110000),
|
||||
AmpConfig("Distortion limiter release time constant", 0b1, 0x46, 0, 0b00000001),
|
||||
AmpConfig("Left DAC input mixer: DAI1 left", 0b0, 0x22, 7, 0b10000000),
|
||||
AmpConfig("Left DAC input mixer: DAI1 right", 0b0, 0x22, 6, 0b01000000),
|
||||
AmpConfig("Left DAC input mixer: DAI2 left", 0b1, 0x22, 5, 0b00100000),
|
||||
AmpConfig("Left DAC input mixer: DAI2 right", 0b0, 0x22, 4, 0b00010000),
|
||||
AmpConfig("Right DAC input mixer: DAI2 left", 0b0, 0x22, 1, 0b00000010),
|
||||
AmpConfig("Right DAC input mixer: DAI2 right", 0b1, 0x22, 0, 0b00000001),
|
||||
AmpConfig("Volume adjustment smoothing disabled", 0b1, 0x49, 6, 0b01000000),
|
||||
],
|
||||
}
|
||||
|
||||
class Amplifier:
|
||||
AMP_I2C_BUS = 0
|
||||
AMP_ADDRESS = 0x10
|
||||
|
||||
def __init__(self, debug=False):
|
||||
self.debug = debug
|
||||
|
||||
def _get_shutdown_config(self, amp_disabled: bool) -> AmpConfig:
|
||||
return AmpConfig("Global shutdown", 0b0 if amp_disabled else 0b1, 0x51, 7, 0b10000000)
|
||||
|
||||
def _set_configs(self, configs: List[AmpConfig]) -> None:
|
||||
with SMBus(self.AMP_I2C_BUS) as bus:
|
||||
for config in configs:
|
||||
if self.debug:
|
||||
print(f"Setting \"{config.name}\" to {config.value}:")
|
||||
|
||||
old_value = bus.read_byte_data(self.AMP_ADDRESS, config.register, force=True)
|
||||
new_value = (old_value & (~config.mask)) | ((config.value << config.offset) & config.mask)
|
||||
bus.write_byte_data(self.AMP_ADDRESS, config.register, new_value, force=True)
|
||||
|
||||
if self.debug:
|
||||
print(f" Changed {hex(config.register)}: {hex(old_value)} -> {hex(new_value)}")
|
||||
|
||||
def set_configs(self, configs: List[AmpConfig]) -> bool:
|
||||
# retry in case panda is using the amp
|
||||
for _ in range(10):
|
||||
try:
|
||||
self._set_configs(configs)
|
||||
return True
|
||||
except OSError:
|
||||
print("Failed to set amp config, retrying...")
|
||||
time.sleep(0.02)
|
||||
return False
|
||||
|
||||
def set_global_shutdown(self, amp_disabled: bool) -> bool:
|
||||
return self.set_configs([self._get_shutdown_config(amp_disabled), ])
|
||||
|
||||
def initialize_configuration(self, model: str) -> bool:
|
||||
cfgs = [
|
||||
self._get_shutdown_config(True),
|
||||
*BASE_CONFIG,
|
||||
*CONFIGS[model],
|
||||
self._get_shutdown_config(False),
|
||||
]
|
||||
return self.set_configs(cfgs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("/sys/firmware/devicetree/base/model") as f:
|
||||
model = f.read().strip('\x00')
|
||||
model = model.split('comma ')[-1]
|
||||
|
||||
if model in CONFIGS:
|
||||
amp = Amplifier()
|
||||
amp.initialize_configuration(model)
|
||||
else:
|
||||
print(f"Skipping, no config for {model}")
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
/usr/comma/sound/adsp-start.sh
|
||||
|
||||
echo "waiting for sound card to come online"
|
||||
while [ ! -d /proc/asound/sdm845tavilsndc ] || [ "$(cat /proc/asound/card0/state 2> /dev/null)" != "ONLINE" ] ; do
|
||||
sleep 0.01
|
||||
done
|
||||
echo "sound card online"
|
||||
|
||||
while ! /usr/comma/sound/tinymix controls | grep -q "SEC_MI2S_RX Audio Mixer MultiMedia1"; do
|
||||
sleep 0.01
|
||||
done
|
||||
echo "tinymix controls ready"
|
||||
|
||||
/usr/comma/sound/tinymix set "SEC_MI2S_RX Audio Mixer MultiMedia1" 1
|
||||
if grep -q mici /sys/firmware/devicetree/base/model; then
|
||||
/usr/comma/sound/tinymix set "MultiMedia1 Mixer SEC_MI2S_TX" 1
|
||||
else
|
||||
/usr/comma/sound/tinymix set "MultiMedia1 Mixer TERT_MI2S_TX" 1
|
||||
/usr/comma/sound/tinymix set "TERT_MI2S_TX Channels" Two
|
||||
fi
|
||||
|
||||
# setup the amplifier registers
|
||||
/usr/local/venv/bin/python /usr/comma/sound/amplifier.py
|
||||
Executable
BIN
Binary file not shown.
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
from tabulate import tabulate
|
||||
|
||||
# serial with timestamps:
|
||||
# grabserial -d /dev/serial/by-id/usb-FTDI_FT230X* -t
|
||||
|
||||
# systemd-analyze critical-chain comma.service
|
||||
|
||||
# boot chart:
|
||||
# systemd-analyze plot > /tmp/bootup.svg
|
||||
|
||||
def get_journal_time(x):
|
||||
out = subprocess.check_output("journalctl -x -o short-monotonic", shell=True, encoding='utf8')
|
||||
jlines = out.strip().splitlines()
|
||||
for l in jlines:
|
||||
if x in l:
|
||||
t = l.split('[')[1].split(']')[0]
|
||||
return float(t)
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
ts = {
|
||||
"PON": 1.5, # estimate from powering on to XBL
|
||||
|
||||
# these are dumped over serial, use the ones from the XBL
|
||||
"XBL": 2.4,
|
||||
"ABL": 3.7, # 3s of this is waiting for fastboot + factory reset tapping
|
||||
}
|
||||
def tot_since_kern():
|
||||
return sum(ts.values()) - (ts['PON'] + ts['XBL'] + ts['ABL'])
|
||||
|
||||
out = subprocess.check_output("systemd-analyze", shell=True, encoding='utf8')
|
||||
l = out.splitlines()[0].split(' ')
|
||||
ts['kernel'] = float(l[3][:-1])
|
||||
#ts['systemd'] = float(l[6][:-1])
|
||||
|
||||
ts['comma'] = get_journal_time("Starting comma.service") - tot_since_kern()
|
||||
|
||||
# print
|
||||
tot = 0
|
||||
total = sum(ts.values())
|
||||
tab = []
|
||||
for s, t in ts.items():
|
||||
tot += t
|
||||
tab.append([
|
||||
s,
|
||||
round(t, 2),
|
||||
round(tot, 2),
|
||||
str(round(t/total * 100)) + "%",
|
||||
])
|
||||
|
||||
# TODO: add openpilot time-to-onroad
|
||||
tab.append(['onroad', '?', '?', '-'])
|
||||
print(tabulate(tab))
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def run(cmd):
|
||||
return subprocess.check_output(cmd, shell=True, encoding='utf8')
|
||||
|
||||
|
||||
def test_setup():
|
||||
# TODO: write some real unit tests for this
|
||||
proc = subprocess.Popen('/usr/comma/setup', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
time.sleep(5)
|
||||
assert proc.poll() is None
|
||||
proc.terminate()
|
||||
|
||||
def test_reset():
|
||||
proc = subprocess.Popen('/usr/comma/reset', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
time.sleep(5)
|
||||
assert proc.poll() is None
|
||||
proc.terminate()
|
||||
|
||||
def test_modem():
|
||||
out = run("mmcli -m 0 --output-json")
|
||||
mm = json.loads(out)
|
||||
from pprint import pprint
|
||||
pprint(mm)
|
||||
|
||||
# modem is up
|
||||
g = mm['modem']['generic']
|
||||
assert g['manufacturer'] == 'QUALCOMM INCORPORATED'
|
||||
assert g['model'] == 'QUECTEL Mobile Broadband Module'
|
||||
assert g['revision'] == 'EG25GGBR07A08M2G'
|
||||
|
||||
# sim is present
|
||||
assert g['sim'] == '/org/freedesktop/ModemManager1/SIM/0'
|
||||
|
||||
# blue prime is active
|
||||
out = run("nmcli con show --active")
|
||||
assert "blue-prime" in out
|
||||
|
||||
def test_wifi():
|
||||
out = run("nmcli dev wifi")
|
||||
networks = out.strip().splitlines()[1:]
|
||||
assert len(networks) > 5
|
||||
|
||||
def test_python_shims():
|
||||
subprocess.check_call("cd /data/openpilot && scons -h", shell=True, stdout=subprocess.DEVNULL)
|
||||
|
||||
def test_dmesg():
|
||||
# TODO: ensure no new errors in dmesg. would catch things like the brightness setting bug
|
||||
pass
|
||||
|
||||
def test_systemd_services():
|
||||
pass
|
||||
|
||||
def test_boot_time():
|
||||
out = subprocess.check_output("systemd-analyze", shell=True, encoding='utf8')
|
||||
|
||||
a = out.splitlines()[0]
|
||||
print(out, a)
|
||||
|
||||
# check comma service
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
def mmcli(cmd):
|
||||
try:
|
||||
out = subprocess.check_output(["mmcli", "-J", *cmd])
|
||||
return json.loads(out)
|
||||
except Exception as e:
|
||||
raise Exception(f"modem command failed: {cmd}") from e
|
||||
|
||||
def test_modem():
|
||||
# wait for the modem to come back up after flashing
|
||||
n = 0
|
||||
cnt = 0
|
||||
while n == 0:
|
||||
n = len(mmcli(["-L"])['modem-list'])
|
||||
if n > 1:
|
||||
raise Exception(f"Wrong number of modems ({n})")
|
||||
|
||||
cnt += 1
|
||||
if cnt > 100:
|
||||
raise Exception("Modem never came up")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
cnt = 0
|
||||
while True:
|
||||
modem = mmcli(["-m", "any"])
|
||||
if modem['modem']['generic']['sim'] != '--':
|
||||
break
|
||||
|
||||
cnt += 1
|
||||
if cnt > 100:
|
||||
raise Exception("SIM missing")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
# force to LTE
|
||||
#os.system("mmcli -m any --set-allowed-modes='4g'")
|
||||
|
||||
# set initial eps bearer apn
|
||||
#sim_id = mmcli(['-i', '0'])['sim']['properties']['iccid']
|
||||
#if sim_id.startswith('8901410'):
|
||||
# os.system('mmcli -m any --3gpp-set-initial-eps-bearer-settings="apn=Broadband"')
|
||||
|
||||
print("waiting for cell connection")
|
||||
time.sleep(7)
|
||||
|
||||
expected = [
|
||||
# key, expected value, error msg
|
||||
(['generic', 'manufacturer'], "QUALCOMM INCORPORATED", "Modem: wrong manufacturer"),
|
||||
(['generic', 'model'], "QUECTEL Mobile Broadband Module", "Modem: wrong model"),
|
||||
(['generic', 'revision'], "EG25GGBR07A08M2G", "Modem: wrong revision"),
|
||||
(['generic', 'carrier-configuration'], ["VoLTE-ATT", "Commercial-TMO_VoLTE"], "Modem: wrong carrier configuration"),
|
||||
(['generic', 'carrier-configuration-revision'], ["0501033C", "05010505"], "Modem: wrong carrier configuration revision"),
|
||||
|
||||
(['generic', 'supported-capabilities'], [['gsm-umts, lte'], ], "Modem: wrong capabilities"),
|
||||
(['3gpp', 'operator-name'], ["--", "AT&T", "T-Mobile"], "Modem: wrong operator"),
|
||||
]
|
||||
for key, val, err_msg in expected:
|
||||
v = modem['modem']
|
||||
for k in key:
|
||||
v = v.get(k)
|
||||
if isinstance(val, list):
|
||||
assert v in val, f"{err_msg} ({v})"
|
||||
else:
|
||||
assert v == val, f"{err_msg} ({v})"
|
||||
|
||||
os.system("date >> /data/tmp/modem_log")
|
||||
os.system("sudo su -c 'tail /data/tmp/modem_log > /dev/console'")
|
||||
os.system("sudo su -c 'wc -l /data/tmp/modem_log > /dev/console'")
|
||||
os.sync()
|
||||
|
||||
time.sleep(2)
|
||||
os.system("sudo reboot")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_modem()
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
good = """
|
||||
Starting Sound...
|
||||
[INFO] Bringing adsp out of reset
|
||||
subsys4
|
||||
waiting for sound card to come online
|
||||
sound card online
|
||||
sound.service: Succeeded.
|
||||
Finished Sound.
|
||||
""".strip()
|
||||
|
||||
if __name__ == "__main__":
|
||||
time.sleep(3)
|
||||
log = subprocess.check_output("journalctl -o cat -u sound", shell=True, encoding='utf8').strip()
|
||||
passed = log == good
|
||||
with open('/data/tmp/sound_log', 'a') as f:
|
||||
f.write(f"{passed}\n")
|
||||
|
||||
os.system("journalctl -u sound.service -o short-monotonic >> /data/tmp/sound_service_log")
|
||||
os.system("sudo su -c 'tail /data/tmp/sound_log > /dev/console'")
|
||||
os.system("sudo su -c 'wc -l /data/tmp/sound_log > /dev/console'")
|
||||
os.sync()
|
||||
|
||||
if passed:
|
||||
time.sleep(2)
|
||||
os.system("sudo reboot")
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RATE=${1:-1}
|
||||
|
||||
log_message() {
|
||||
# /var/log/syslog
|
||||
cat /usr/include/sqlite3.h | systemd-cat -t SPAM_TEST
|
||||
|
||||
# /var/log/kern.log
|
||||
#cat /usr/include/sqlite3.h | sudo tee /dev/kmsg > /dev/null
|
||||
}
|
||||
|
||||
# verify config is good
|
||||
sudo logrotate -d /etc/logrotate.conf
|
||||
|
||||
sudo rm -rf /var/log/*
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart rsyslog
|
||||
sudo systemctl restart systemd-journald
|
||||
sudo systemctl restart logrotate-hourly.timer
|
||||
|
||||
while true; do
|
||||
for i in $(seq 1 $RATE); do
|
||||
log_message
|
||||
done
|
||||
|
||||
echo
|
||||
df -h /var/
|
||||
sudo du -hs /var/log/* || true
|
||||
|
||||
sleep 1
|
||||
done
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# silences a ruby warning
|
||||
# https://bugs.launchpad.net/ubuntu/+source/iptables-netflow/+bug/1907932
|
||||
export RUBYOPT="-W0"
|
||||
|
||||
irqtop
|
||||
@@ -0,0 +1,23 @@
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# See tmpfiles.d(5) for details
|
||||
|
||||
# /var: rebuild enough for services to be happy
|
||||
d /var/crash 0755 - - -
|
||||
q /var/tmp 1777 root root 30d
|
||||
|
||||
d /var/lib/dpkg 0755 - - -
|
||||
f /var/lib/dpkg/lock-frontend 0755 - - -
|
||||
f /var/lib/dpkg/status 0755 - - -
|
||||
|
||||
d /var/lib/logrotate 0755 - - -
|
||||
|
||||
d /var/spool 0755 - - -
|
||||
d /var/spool/cron/atjobs 0755 - - -
|
||||
|
||||
d /var/cache/pollinate 0755 pollinate daemon -
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a94ab8395f20d20a9d5a2a2bacca0694f072df8421cf13adca6250d28065bdc
|
||||
size 24709205
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
|
||||
if __name__ == "__main__":
|
||||
# we are the last line of defense for /var/log filling up
|
||||
while True:
|
||||
usage = os.statvfs('/var/log')
|
||||
percent = (usage.f_blocks - usage.f_bavail) / usage.f_blocks * 100
|
||||
if percent > 70:
|
||||
for fn in os.listdir('/var/log'):
|
||||
file_path = os.path.join('/var/log', fn)
|
||||
if os.path.isfile(file_path):
|
||||
with open(file_path, 'w'):
|
||||
pass
|
||||
time.sleep(1)
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
until [ -e $1 ]
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user