Skip to content

Commit

Permalink
updated devicescript sample
Browse files Browse the repository at this point in the history
  • Loading branch information
pelikhan committed Oct 17, 2023
1 parent 365e709 commit f679698
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 188 deletions.
18 changes: 10 additions & 8 deletions packages/core/src/expander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import {
RequestError,
getChatCompletions,
} from "./chat"
import {
Fragment,
PromptTemplate,
allChildren,
rangeOfFragments,
rootFragment,
} from "./ast"
import { Fragment, PromptTemplate, allChildren } from "./ast"
import { Edits } from "./edits"
import { commentAttributes, stringToPos } from "./parser"
import {
Expand All @@ -18,7 +12,6 @@ import {
fileExists,
readText,
relativePath,
splitPath,
} from "./util"
import {
evalPrompt,
Expand Down Expand Up @@ -358,6 +351,15 @@ function fragmentVars(
for (const fr of allChildren(frag, true)) {
for (const ref of fr.references) {
// what about URLs?
if (/^https:\/\//.test(ref.filename)) {
if (!links.find((lk) => lk.filename === ref.filename))
links.push({
label: ref.name,
filename: ref.filename,
content: "",
})
continue
}

// check for existing file
const projectFile = project.allFiles.find(
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ const parseMdFile: Parser = (
(_, name, file) => {
newelt.references.push({
name,
filename: host.resolvePath(filename, "..", file),
filename: /^\w+:\/\//.test(file)
? file
: host.resolvePath(filename, "..", file),
})
return ""
}
Expand Down
7 changes: 7 additions & 0 deletions packages/devicescript/.coarch/cache/airequests.coarch.jsonl

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions packages/devicescript/.coarch/cache/openai.coarch.jsonl

Large diffs are not rendered by default.

103 changes: 5 additions & 98 deletions packages/devicescript/prompts/firmware.prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,113 +2,20 @@ prompt({
title: "firmware",
description: "Compile information about various sources to generate DeviceScript driver.",
categories: ["devicescript"],
system: ["system.typescript", "system.summary"],
maxTokens: 4000
system: ["system", "system.summary", "system.explanations", "system.files", "system.typescript", "system.summary"],
model: "gpt-4-32k",
maxTokens: 16000,
})

def("SPEC", env.file)
def("CODE", env.links.filter(f => f.filename.endsWith(".ts")))
def("README", env.links.filter(f => f.filename.endsWith("README.md")))
def("PSEUDO", env.links.filter(f => f.filename.endsWith(".pseudo")))

$`You are an expert at DeviceScript (https://microsoft.github.io/devicescript), a TypeScript compiler and runtime for embedded devices.
Using the information provided in SPEC, generate a DeviceScript driver for the peripherical.`

$`The base classes for I2C drivers are at https://github.com/microsoft/devicescript/blob/main/packages/drivers/src/driver.ts .
The symbols are in the '@devicescript/drivers' module.
\`\`\`ts
/**
* A helper class to implement I2C drivers
*/
export abstract class I2CDriver {
/**
* Instantiate a driver
* @param devAddr a 7 bit i2c address
* @param options
*/
constructor(devAddr: number, options?: I2CDriverOptions);
/**
* Allocates a Buffer of size length bytes.
*/
protected allocBuffer(length: number): Buffer;
/**
* Initializes the I2C device
* @throws DriverError
*/
async init(): Promise<void> {
await this.initDriver()
}
/**
* Initializes the I2C device
* @throws I2CError
*/
protected abstract initDriver(): Promise<void>;
/**
* Execute I2C transaction
* @param devAddr a 7 bit i2c address
* @param writeBuf the value to write
* @param numRead number of bytes to read afterwards
* @returns a buffer "numRead" bytes long
*/
async xfer(writeBuf: Buffer, numRead: number): Promise<Buffer>;
/**
* Write a byte to a register
* @param devAddr a 7 bit i2c address
* @param regAddr an 8 bit register address
* @param byte the value to write
* @throws I2CError
*/
async writeReg(regAddr: number, byte: number): Promise<void>;
/**
* read a byte from a register
* @param devAddr a 7 bit i2c address
* @param regAddr an 8 bit register address
* @returns a byte
* @throws I2CError
*/
async readReg(regAddr: number): Promise<number>;
/**
* write a buffer to a register
* @param devAddr a 7 bit i2c address
* @param regAddr an 8 bit register address
* @param b a byte buffer
* @throws I2CError
*/
async writeRegBuf(regAddr: number, b: Buffer): Promise<void>;
/**
* read a buffer from a register
* @param devAddr a 7 bit i2c address
* @param regAddr an 8 bit register address
* @param size the number of bytes to request
* @returns a byte buffer
* @throws I2CError
*/
async readRegBuf(regAddr: number, size: number): Promise<Buffer>;
/**
* read a raw buffer
* @param devAddr a 7 bit i2c address
* @param size the number of bytes to request
* @returns a byte buffer
* @throws I2CError
*/
async readBuf(size: number): Promise<Buffer>;
/**
* write a raw buffer
* @param devAddr a 7 bit i2c address
* @param b a byte buffer
* @throws I2CError
*/
async writeBuf(b: Buffer): Promise<void>;
}
\`\`\`
`
$`The PSEUDO file contain information about existing code in the library. Use this in CODE.`

$`Generate a README.md file (with filename starting with 'main${env.file.filename.replace(`.coarch.md`, '')}') that uses the driver
and displays meaningful information to the console. Generate the list of sources used to generate the code.`
Expand Down
24 changes: 18 additions & 6 deletions packages/devicescript/prompts/summarizecode.prompt.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
prompt({
title: "Code Summarizer",
model: "gpt-4-32k",
maxTokens: 16000,
description: "Given a source file in a programming language, extract the structure"
})

const { file } = await fetchText("https://raw.githubusercontent.com/microsoft/devicescript/main/packages/drivers/src/driver.ts")

def("FILE", file)
const urls = env.links.filter(f => /^https:\/\//.test(f.filename))
const files = await Promise.all(urls.map(async url => {
const res = await fetchText(url.filename)
return {
label: url.label,
filename: url.label,
content: res.text
}
}))
def("FILE", files)
def("SPEC", env.file)

$`You are an expert at programming in all known languages.
For each FILE 'filename.extension', generate a summarized FILE 'filename.s.extension' that ignores the internal details
of the implementation and extracts enough information for an LLM to use the code elements
in the source file. Generate comments as needed.`
For each FILE 'filename.ts', generate the code structure in FILE 'filename.extension.pseudo'
that ignores the internal detailsof the implementation and extracts enough information for an LLM
to use the code elements in the source file in the context of the SPEC task.
Do not generate a pseudo-file for SPEC.
`
1 change: 1 addition & 0 deletions packages/devicescript/prompts/todo.prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ prompt({
})

def("SPEC", env.file)
def("PSEUDO", env.links.filter(f => f.filename.endsWith(".pseudo")))
def("CODE", env.links.filter(f => f.filename.endsWith(".ts")))

$`You are an expert at DeviceScript (https://microsoft.github.io/devicescript), a TypeScript compiler and runtime for embedded devices.`
Expand Down
27 changes: 15 additions & 12 deletions packages/devicescript/src/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
# PCF8563 DeviceScript Driver
# PCF8563 Real-Time Clock Driver

This is a DeviceScript driver for the PCF8563 real-time-clock (RTC).
This is a DeviceScript driver for the PCF8563 real-time clock (RTC) peripheral.

## Usage

```typescript
import { PCF8563 } from "./pcf8563";

async function main() {
const rtc = new PCF8563();
await rtc.init();
const currentTime = await rtc.readTime();
console.log("Current time:", currentTime);
}
const rtc = new PCF8563(0x51);
await rtc.init();

main();
const currentTime = await rtc.readTime();
console.log("Current time:", currentTime);

const newTime = new Date();
await rtc.writeTime(newTime);
console.log("Time updated to:", newTime);
```

Sources:
- [datasheet](https://files.seeedstudio.com/wiki/round_display_for_xiao/RTC-PCF8563-datasheet.pdf)
- [Adafruit CircuitPython](https://github.com/adafruit/Adafruit_CircuitPython_PCF8563)
## Sources

- [PCF8563 Datasheet](https://files.seeedstudio.com/wiki/round_display_for_xiao/RTC-PCF8563-datasheet.pdf)
- [Adafruit CircuitPython PCF8563](https://github.com/adafruit/Adafruit_CircuitPython_PCF8563)
- [tuupola/pcf8563](https://github.com/tuupola/pcf8563)
10 changes: 0 additions & 10 deletions packages/devicescript/src/date.ts

This file was deleted.

18 changes: 18 additions & 0 deletions packages/devicescript/src/driver.ts.pseudo
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class I2CDriver {
constructor(devAddr, options)
init()
initDriver()
xfer(writeBuf, numRead)
writeReg(regAddr, byte)
readReg(regAddr)
writeRegBuf(regAddr, b)
readRegBuf(regAddr, size)
readBuf(size)
writeBuf(b)
}

class I2CSensorDriver extends I2CDriver {
constructor(devAddr, options)
read()
readData()
}
6 changes: 5 additions & 1 deletion packages/devicescript/src/drivers.coarch.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# DeviceScript Drivers

- [src/driver.ts](https://raw.githubusercontent.com/microsoft/devicescript/main/packages/drivers/src/driver.ts)

DeviceScript is a TypeScript like language to program micro-controllers.
DeviceScript is a TypeScript like language to program micro-controllers.
You will need to implement drivers in TypeScript using the i2c base classes.

- [./driver.ts.pseudo](./driver.ts.pseudo)
16 changes: 0 additions & 16 deletions packages/devicescript/src/main.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/devicescript/src/pcf8563.coarch.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The PCF8563 peripheral is a real-time-clock (RTC).
- [Adafruit CircuitPython](https://github.com/adafruit/Adafruit_CircuitPython_PCF8563)
- [tuupola/pcf8563](https://github.com/tuupola/pcf8563)
- [README.md](README.md)
- [driver.s.ts](driver.s.ts)
- [driver.ts.pseudo](driver.ts.pseudo)
- [pcf8563.ts](pcf8563.ts)
- [main.ts](main.ts)
- [date.ts](date.ts)
Expand Down
76 changes: 41 additions & 35 deletions packages/devicescript/src/pcf8563.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,46 @@
import { I2CDriver } from "@devicescript/drivers"
import { Date } from "./date"
import { I2CDriver } from "./driver";

const PCF8563_I2C_ADDR = 0x51 // Default I2C address from datasheet
const PCF8563_ADDR = 0x51; // Default I2C address from datasheet

const REG_SECONDS = 0x02 // Register address for SECONDS from datasheet
// Register addresses from datasheet
const SECONDS_REG = 0x02;
const MINUTES_REG = 0x03;
const HOURS_REG = 0x04;

export class PCF8563 extends I2CDriver {
constructor(i2cAddress: number = PCF8563_I2C_ADDR) {
super(i2cAddress)
}

protected async initDriver(): Promise<void> {
// Initialization sequence to set control registers
await this.writeReg(0x00, 0x00) // Control1 register: disable all alarms and interrupts
await this.writeReg(0x01, 0x00) // Control2 register: disable all alarms and interrupts
}

async readTime(): Promise<Date> {
// TODO
return undefined
}

async writeTime(date: Date): Promise<void> {
// TODO
return undefined
}

private bcdToDecimal(bcd: number): number {
return (bcd >> 4) * 10 + (bcd & 0x0f)
}

private decimalToBcd(decimal: number): number {
return ((decimal / 10) << 4) | decimal % 10
}

async stopClock(): Promise<void> {
// TODO
}
constructor(devAddr: number = PCF8563_ADDR, options: any = {}) {
super(devAddr, options);
}

async init() {
await this.initDriver();
// TODO: generate device initialization sequence to set control registers
await this.writeReg(0x00, 0x00); // Control register 1
await this.writeReg(0x01, 0x00); // Control register 2
}

async readTime(): Promise<Date> {
const buf = await this.readRegBuf(SECONDS_REG, 3);
const seconds = this.bcdToDecimal(buf[0] & 0x7F);
const minutes = this.bcdToDecimal(buf[1] & 0x7F);
const hours = this.bcdToDecimal(buf[2] & 0x3F);

return new Date(0, 0, 0, hours, minutes, seconds);
}

async writeTime(date: Date) {
const seconds = this.decimalToBcd(date.getSeconds());
const minutes = this.decimalToBcd(date.getMinutes());
const hours = this.decimalToBcd(date.getHours());

await this.writeRegBuf(SECONDS_REG, Buffer.from([seconds, minutes, hours]));
}

private bcdToDecimal(bcd: number): number {
return (bcd >> 4) * 10 + (bcd & 0x0F);
}

private decimalToBcd(decimal: number): number {
return ((decimal / 10) << 4) | (decimal % 10);
}
}

0 comments on commit f679698

Please sign in to comment.