aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUri Shaked2019-12-07 13:08:46 +0200
committerUri Shaked2019-12-07 13:08:46 +0200
commit92898c67a4da42992a8115ffa7b12781e49f2eae (patch)
tree00e94786829b3c2cef833e94b45efb393be06b6d
parentchore: update package-lock.json (diff)
downloadavr8js-92898c67a4da42992a8115ffa7b12781e49f2eae.tar.gz
avr8js-92898c67a4da42992a8115ffa7b12781e49f2eae.tar.bz2
avr8js-92898c67a4da42992a8115ffa7b12781e49f2eae.zip
feat(usart): add onLineTransmit callback
-rw-r--r--src/usart.spec.ts43
-rw-r--r--src/usart.ts13
2 files changed, 56 insertions, 0 deletions
diff --git a/src/usart.spec.ts b/src/usart.spec.ts
index f0dacc4..dadfc78 100644
--- a/src/usart.spec.ts
+++ b/src/usart.spec.ts
@@ -113,4 +113,47 @@ describe('USART', () => {
expect(cpu.data[0xc0]).toEqual(0x40 | 0x20); // UCSR0A: TXC | UDRE
});
});
+
+ describe('onLineTransmit', () => {
+ it('should call onLineTransmit with the current line buffer after every newline', () => {
+ const cpu = new CPU(new Uint16Array(1024));
+ const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ);
+ usart.onLineTransmit = jest.fn();
+ cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN
+ cpu.writeData(0xc6, 0x48); // 'H'
+ cpu.writeData(0xc6, 0x65); // 'e'
+ cpu.writeData(0xc6, 0x6c); // 'l'
+ cpu.writeData(0xc6, 0x6c); // 'l'
+ cpu.writeData(0xc6, 0x6f); // 'o'
+ cpu.writeData(0xc6, 0xa); // '\n'
+ expect(usart.onLineTransmit).toHaveBeenCalledWith('Hello');
+ });
+
+ it('should not call onLineTransmit if no newline was received', () => {
+ const cpu = new CPU(new Uint16Array(1024));
+ const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ);
+ usart.onLineTransmit = jest.fn();
+ cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN
+ cpu.writeData(0xc6, 0x48); // 'H'
+ cpu.writeData(0xc6, 0x69); // 'i'
+ expect(usart.onLineTransmit).not.toHaveBeenCalled();
+ });
+
+ it('should clear the line buffer after each call to onLineTransmit', () => {
+ const cpu = new CPU(new Uint16Array(1024));
+ const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ);
+ usart.onLineTransmit = jest.fn();
+ cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN
+ cpu.writeData(0xc6, 0x48); // 'H'
+ cpu.writeData(0xc6, 0x69); // 'i'
+ cpu.writeData(0xc6, 0xa); // '\n'
+ cpu.writeData(0xc6, 0x74); // 't'
+ cpu.writeData(0xc6, 0x68); // 'h'
+ cpu.writeData(0xc6, 0x65); // 'e'
+ cpu.writeData(0xc6, 0x72); // 'r'
+ cpu.writeData(0xc6, 0x65); // 'e'
+ cpu.writeData(0xc6, 0xa); // '\n'
+ expect(usart.onLineTransmit).toHaveBeenCalledWith('there');
+ });
+ });
});
diff --git a/src/usart.ts b/src/usart.ts
index da5cee0..8d5691c 100644
--- a/src/usart.ts
+++ b/src/usart.ts
@@ -28,6 +28,7 @@ export const usart0Config: USARTConfig = {
};
export type USARTTransmitCallback = (value: u8) => void;
+export type USARTLineTransmitCallback = (value: string) => void;
// Register bits
const UCSRA_RXC = 0x80; // USART Receive Complete
@@ -57,6 +58,9 @@ const UCSRC_UCPOL = 0x1; // Clock Polarity
export class AVRUSART {
public onByteTransmit: USARTTransmitCallback | null = null;
+ public onLineTransmit: USARTLineTransmitCallback | null = null;
+
+ private lineBuffer: string = '';
constructor(private cpu: CPU, private config: USARTConfig, private freqMHz: number) {
this.cpu.writeHooks[config.UCSRA] = (value) => {
@@ -73,6 +77,15 @@ export class AVRUSART {
if (this.onByteTransmit) {
this.onByteTransmit(value);
}
+ if (this.onLineTransmit) {
+ const ch = String.fromCharCode(value);
+ if (ch === '\n') {
+ this.onLineTransmit(this.lineBuffer);
+ this.lineBuffer = '';
+ } else {
+ this.lineBuffer += ch;
+ }
+ }
this.cpu.data[config.UCSRA] |= UCSRA_UDRE | UCSRA_TXC;
};
}