Merge branch 'main' into button
This commit is contained in:
Коммит
555eee62ef
|
@ -0,0 +1,35 @@
|
|||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 12 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: javascript, python
|
||||
|
||||
- run: |
|
||||
./check.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
|
@ -8,3 +8,4 @@ genid/*.user
|
|||
genid/.vs
|
||||
rolling.txt
|
||||
genid.exe
|
||||
tmp
|
||||
|
|
|
@ -13,6 +13,8 @@ in particular the PADAUK PMS150C, PMS171B, and PMS131.
|
|||
* `scripts` contains various utility scripts (they are not currently used in build process)
|
||||
* `jm-*` contains project files and `main.asm` files for several Jacdac modules; they each include the base Jacdac implementation and a single service
|
||||
|
||||
If you create a new device folder, run `./check.sh` script to check for duplicate firmware IDs.
|
||||
|
||||
## Requirements
|
||||
|
||||
To run (software) UART at 1mbaud (as required by Jacdac), the MCU has to run at 8MHz (or more, but PADAUK chips only do up to 8MHz).
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
node scripts/linter.js */*.prj
|
|
@ -399,7 +399,8 @@ ENDM
|
|||
WORD memidx
|
||||
BYTE flags
|
||||
BYTE tx_pending
|
||||
BYTE isr0, isr1, isr2
|
||||
BYTE isr0, isr1
|
||||
BYTE rx_data
|
||||
|
||||
BYTE blink
|
||||
|
||||
|
@ -420,7 +421,7 @@ ENDM
|
|||
BYTE pkt_service_command_l
|
||||
BYTE pkt_service_command_h
|
||||
BYTE pkt_payload[payload_size]
|
||||
BYTE rx_data // this is overwritten during rx if packet too long (but that's fine)
|
||||
BYTE isr2 // this is overwritten during rx if packet too long (but that's fine)
|
||||
BYTE rng_x
|
||||
|
||||
// so far:
|
||||
|
@ -447,6 +448,13 @@ ENDM
|
|||
|
||||
#define rx_buflimit isr0
|
||||
|
||||
#ifdef PWR_SERVICE
|
||||
#define rx_flags isr1
|
||||
#define rx_prev_data isr2
|
||||
#define rx_pwr_neq rx_flags.0
|
||||
#define rx_pwr_flip_sw rx_flags.1
|
||||
#endif
|
||||
|
||||
.rx_init EXPAND
|
||||
PAPH.PIN_JACDAC = 1
|
||||
call reset_tm2
|
||||
|
@ -495,6 +503,9 @@ interrupt:
|
|||
|
||||
clear frm_sz // make sure packet is invalid, if we do not recv anything
|
||||
mov a, 0
|
||||
#ifdef PWR_SERVICE
|
||||
clear rx_flags
|
||||
#endif
|
||||
goto rx_wait_start
|
||||
|
||||
IDSIZE equ 8
|
||||
|
@ -555,12 +566,73 @@ get_id:
|
|||
|
||||
rx_start:
|
||||
mov TM2CT, a // a is 0 here
|
||||
// setup TM2 to expire in 16T
|
||||
// setup TM2 to expire in 16us
|
||||
$ TM2S 8BIT, /1, /2
|
||||
|
||||
#ifdef PWR_SERVICE
|
||||
pwr_test_size equ 8
|
||||
.mova rx_prev_data, rx_data
|
||||
clear rx_data
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
set1 rx_data.0
|
||||
ifset rx_pwr_flip_sw
|
||||
set0 PA.PIN_SWITCH
|
||||
set0 rx_pwr_flip_sw
|
||||
nop
|
||||
mov a, memidx$0
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
set1 rx_data.1
|
||||
sub a, pkt_addr + (pwr_test_size + 2)
|
||||
ifclear OV
|
||||
mov a, -(pwr_test_size + 2)
|
||||
add a, (pwr_test_size + 3)
|
||||
sl a
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
set1 rx_data.2
|
||||
|
||||
pcadd a
|
||||
// a is always even - so this is unreachable
|
||||
nop
|
||||
// case of memidx==0 or memidx>9; we want the match to always succeed
|
||||
mov a, rx_prev_data
|
||||
goto _bit3
|
||||
// cases of memidx==1,...,8
|
||||
.for v, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
||||
mov a, v
|
||||
goto _bit3
|
||||
.endm
|
||||
// cases of memidx==9 - i.e., we are just past the first 8 bytes, now is time to flip the switch if they match
|
||||
set1 rx_pwr_flip_sw
|
||||
goto _bit3
|
||||
|
||||
_bit3:
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
set1 rx_data.3
|
||||
ifset rx_pwr_neq // if no match
|
||||
set0 rx_pwr_flip_sw // do not flip switch
|
||||
sub a, rx_prev_data
|
||||
ifclear ZF
|
||||
set1 rx_pwr_neq // if no match, clear the match flag
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
set1 rx_data.4
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov a, 0x20 // use regular loop reception from bit 5 on
|
||||
#else
|
||||
clear rx_data
|
||||
nop
|
||||
mov a, 0x01
|
||||
#endif
|
||||
|
||||
rx_next_bit:
|
||||
// ----------------------------------------------------
|
||||
ifset PA.PIN_JACDAC
|
||||
or rx_data, a
|
||||
nop
|
||||
|
@ -569,7 +641,12 @@ rx_next_bit:
|
|||
ceqsn a, 0x80
|
||||
goto rx_next_bit
|
||||
rx_lastbit:
|
||||
#ifdef PWR_SERVICE
|
||||
// re-enable switch; it was disabled (if any) for 7 out of 8 bits, and this is a convienient place to re-enable it
|
||||
set1 PA.PIN_SWITCH
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
ifset PA.PIN_JACDAC
|
||||
or rx_data, a
|
||||
mov a, rx_data
|
||||
|
@ -579,7 +656,9 @@ rx_lastbit:
|
|||
ifset ZF // if rx_buflimit==0
|
||||
inc rx_buflimit // rx_buflimit++ -> keep rx_buflimit at 0
|
||||
mov a, 0
|
||||
mov TM2CT, a
|
||||
mov TM2CT, a // clear TM2CT before the wait (of 16us before start bit)
|
||||
#endif
|
||||
|
||||
// wait for serial transmission to start
|
||||
rx_wait_start:
|
||||
.repeat 20
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
.CHIP PMS150C
|
||||
// Give package map to writer pcount VDD PA0 PA3 PA4 PA5 PA6 PA7 GND SHORTC_MSK1 SHORTC_MASK1 SHIFT
|
||||
//.writer package 6, 1, 0, 4, 27, 25, 26, 0, 28, 0x0007, 0x0007, 0
|
||||
//{{PADAUK_CODE_OPTION
|
||||
.Code_Option Security Disable
|
||||
.Code_Option Bootup_Time Fast
|
||||
.Code_Option Drive Normal
|
||||
.Code_Option LVR 3.0V
|
||||
//}}PADAUK_CODE_OPTION
|
||||
|
||||
// all pins on PA
|
||||
#define PIN_LED 5
|
||||
#define PIN_JACDAC 6
|
||||
#define PIN_LOG 7
|
||||
|
||||
#define LED_SINK 1
|
||||
|
||||
// Cost given in comment: words of flash/bytes of RAM
|
||||
// #define CFG_T16_32BIT 1 // 1/1
|
||||
#define CFG_BROADCAST 1 // 20/0
|
||||
#define CFG_RESET_IN 1 // 24/1
|
||||
#define CFG_FW_ID 0x3f44a5eb // 24/0
|
||||
|
||||
#define PWR_SERVICE 1
|
||||
|
||||
#define PIN_SWITCH 4
|
||||
|
||||
.include ../jd/jdheader.asm
|
||||
|
||||
#define PIN_LIMITER 3
|
||||
.include ../services/power.asm
|
||||
|
||||
main:
|
||||
.ADJUST_IC SYSCLK=IHRC/2, IHRC=16MHz, VDD=3.3V
|
||||
PADIER = (1 << PIN_JACDAC) | (1 << PIN_LIMITER)
|
||||
|
||||
.include ../jd/jdmain.asm
|
|
@ -0,0 +1,27 @@
|
|||
[INI]
|
||||
PROJECT=SINGLE
|
||||
[LINKS]
|
||||
~main.asm
|
||||
[Ram_Break]
|
||||
Break1=No 0000
|
||||
Break2=No 0000
|
||||
Break3=No 0000
|
||||
Break4=No 0000
|
||||
[Stack_Break]
|
||||
Break1=No 0000 00FF
|
||||
Break2=No 0000 00FF
|
||||
Break3=No 0000 00FF
|
||||
Break4=No 0000 00FF
|
||||
Break5=No 0000 00FF
|
||||
Break6=No 0000 00FF
|
||||
Break7=No 0000 00FF
|
||||
Break8=No 0000 00FF
|
||||
[Ctrl_Break]
|
||||
Mark=51 1
|
||||
ICE=0 6 2 CE4
|
||||
[HEAD]
|
||||
[DEPEND]
|
||||
~..\jd\jdheader.asm
|
||||
~..\jd\jdmain.asm
|
||||
~..\services\power.asm
|
||||
~$:INC_PDK\PMS150C.INC
|
|
@ -0,0 +1,66 @@
|
|||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
|
||||
function looksRandom(n) {
|
||||
const s = n.toString(16)
|
||||
const h = "0123456789abcdef"
|
||||
for (let i = 0; i < h.length; ++i) {
|
||||
const hh = h[i]
|
||||
if (s.indexOf(hh + hh + hh) >= 0) return false
|
||||
}
|
||||
if (/f00d|dead|deaf|beef/.test(s)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
function genRandom() {
|
||||
for (; ;) {
|
||||
const m = (Math.random() * 0xfff_ffff) | 0x3000_0000
|
||||
if (looksRandom(m)) return m
|
||||
}
|
||||
}
|
||||
|
||||
function fail(msg) {
|
||||
console.error(msg)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const fwidmap = {}
|
||||
function validateFile(prjFn) {
|
||||
console.log(`scan: ${prjFn}`)
|
||||
const prj = fs.readFileSync(prjFn, "utf-8")
|
||||
let mainASM = ""
|
||||
let links = false
|
||||
for (const ln of prj.split(/\r?\n/)) {
|
||||
if (!mainASM && links && ln[0] == "~") {
|
||||
mainASM = ln.slice(1)
|
||||
links = false
|
||||
}
|
||||
if (ln == "[LINKS]")
|
||||
links = true
|
||||
}
|
||||
if (!mainASM) fail(`can't find main.asm in ${prjFn}`)
|
||||
mainASM = path.join(path.dirname(prjFn), mainASM)
|
||||
console.log(` main: ${mainASM}`)
|
||||
let main = fs.readFileSync(mainASM, "utf-8")
|
||||
const m = /#define CFG_FW_ID (0[xX]?[a-fA-F0-9]*)/.exec(main)
|
||||
if (!m) fail(`no CFG_FW_ID in ${mainASM}`)
|
||||
let fwid = parseInt(m[1])
|
||||
let fwidstr = `0x${fwid.toString(16)}`
|
||||
if (fwid === 0) {
|
||||
fwid = genRandom()
|
||||
fwidstr = `0x${fwid.toString(16)}`
|
||||
main = main.replace(m[0], `#define CFG_FW_ID ${fwidstr}`)
|
||||
console.log(` setting firmware ID to: ${fwidstr}`)
|
||||
fs.writeFileSync(mainASM, main)
|
||||
}
|
||||
if (fwidmap[fwidstr])
|
||||
fail(`firmware ID conflict on ${fwidstr} between ${mainASM} and ${fwidmap[fwidstr]}; replace one of them with 0x0 to re-generate`)
|
||||
|
||||
fwidmap[fwidstr] = mainASM
|
||||
}
|
||||
|
||||
const files = process.argv.slice(2)
|
||||
if (files.length == 0)
|
||||
fail(`usage: node ${process.argv[1]} folder/device.prj...`)
|
||||
files.forEach(validateFile)
|
||||
console.log("All good!")
|
|
@ -0,0 +1,36 @@
|
|||
#define SERVICE_CLASS 0x1fa4c95a
|
||||
|
||||
BYTE t_sample
|
||||
|
||||
/*
|
||||
TODO:
|
||||
send PWR packet every ~500 ms while limiter is enabled
|
||||
monitor limiter - input on PIN_LIMITER no pull
|
||||
- LED ~10% ON when providing power
|
||||
- LED normal blinking when not providing power
|
||||
on PWR cmd - disable limiter (output 0 on PIN_LIMITER) for 1000ms
|
||||
|
||||
*/
|
||||
|
||||
.serv_init EXPAND
|
||||
PAC.PIN_SWITCH = 1
|
||||
PA.PIN_SWITCH = 1
|
||||
ENDM
|
||||
|
||||
.serv_process EXPAND
|
||||
.ev_process
|
||||
ENDM
|
||||
|
||||
.serv_prep_tx MACRO
|
||||
ifset tx_pending.txp_event
|
||||
goto ev_prep_tx
|
||||
ENDM
|
||||
|
||||
serv_rx:
|
||||
goto rx_process_end
|
||||
|
||||
.serv_ev_payload EXPAND
|
||||
// no payloads
|
||||
ENDM
|
||||
|
||||
.ev_impl
|
Загрузка…
Ссылка в новой задаче