串行外設(shè)接口?(SPI) 允許在板級(jí)連接設(shè)備。μVision 調(diào)試器在主從模式下模擬多個(gè)微控制器的SPI接口。
虛擬仿真寄存器?(VTREG)
以下?VTREG 用于模擬 SPI 通信:
VTREG | 描述 |
SPIxIN | 是SPI輸入寄存器,獲取當(dāng)前接收到的數(shù)據(jù)。 |
SPIxOUT | 是保存當(dāng)前傳輸數(shù)據(jù)的 SPI 輸出寄存器。 |
SPIx 的 VTREG 命名約定因器件而異。一些設(shè)備提供了不止一個(gè) SPI 接口。因此,VTREG 名稱(chēng)可能以 SPI0 或 SPI1 為前綴。使用命令 DIR VTREG檢查 SPI 接口的虛擬仿真寄存器名稱(chēng)。
SPI仿真示例
以下腳本定義了調(diào)試器信號(hào)函數(shù),這些函數(shù)使用帶有switch語(yǔ)句的簡(jiǎn)單狀態(tài)機(jī)模擬 Atmel AT250X0 SPI 存儲(chǔ)設(shè)備。
/* Define the state and address for the AT250x0.*/
define char spi_at250x0_state
define int ?spi_at250x0_address
define char spi_at250x0_status
/* MAP the memory area to use for the SPI RAM. */
map X:0x700000,X:0x70FFFF READ WRITE
/*-----------------------------------------------
This function implements the state matching for
the AT250x0.
State ??????Transition
-------------------------------------------------
0: WREN ?-> 0
0: WRDI ?-> 0
0: RDSR ?-> 0
0: Read ?-> 1: Get Address LSB -> 2: Read Byte <-
0: Write -> 3: Get Address LSB -> 4: Write Byte -> 5 <-
1: Get Addr LSB -> 2
2: Read Byte(s) -> 2
3: Get Addr LSB -> 4
4: Write Byte ??-> 5
-----------------------------------------------*/
func char spi_at250x0 (char st) {
??unsigned char opcode;
??printf ("AT250X0: STATE %un", (unsigned) st);
??switch (st) ?{
????case 0: ?/* Get OPCode */
??????opcode = SPI_OUT & 0x0007;
??????printf ("AT250X0: OPCODE %un", (unsigned) opcode);
????switch (opcode)
??????{
??????case 1: /* WRSR */
????????return (0);
??????case 2: /* Write */
????????printf ("AT250X0: WRITE OPCODE Detectedn");
????????spi_at250x0_address = (SPI_OUT & 0x08) << 5;
????????return (3);
??????case 3: /* Read */
????????printf ("AT250X0: READ OPCODE Detectedn");
????????spi_at250x0_address = (SPI_OUT & 0x08) << 5;
????????return (1);
??????case 4: /* WRDI */
????????spi_at250x0_status &= ~0x02; /* Clear Write Enable Bit */
????????return (0);
??????case 5: /* RDSR */
????????SPI_IN = spi_at250x0_status;
????????return (5);
??????case 6: /* WREN */
????????spi_at250x0_status |= 0x02; /* Set Write Enable Bit */
????????return (0);
??????}
????return (0);
??case 1: ?/* Get Address LSB for READ */
????spi_at250x0_address |= (SPI_OUT & 0xFF);
????printf ("AT250X0: Address %4.4X Detectedn", spi_at250x0_address);
????return (2);
??case 2: ?/* Read */
????printf ("AT250X0: Read %2.2X from address %4.4Xn", 'A', spi_at250x0_address);
????SPI_IN = _rbyte(X:0x700000 + spi_at250x0_address);
????spi_at250x0_address = (spi_at250x0_address + 1) % 512;
????return (2);
??case 3: ?/* Get Address LSB for WRITE */
????spi_at250x0_address |= (SPI_OUT & 0xFF);
????printf ("AT250X0: Address %4.4X Detectedn", spi_at250x0_address);
????return (4);
??case 4: ?/* Write */
????if (spi_at250x0_status & 0x02)
??????{
??????printf ("AT250X0: Write %2.2X to address %4.4Xn", SPI_OUT, spi_at250x0_address);
??????_wbyte(X:0x700000 + spi_at250x0_address, SPI_OUT);
??????spi_at250x0_status |= 0x01;
??????}
????return (5);
??case 5: ?/* Instruction End */
????return (5);
??}
return (0);
}
/*
?* This signal function watches the AT89S8252 SPI port for writes. ?If there
?* is an SPI port output and if P1.0 is LO (AT250X0 chip select) then interpret
?* the SPI output data and run the state machine.
?*/
signal void spi_watcher (void) {
spi_at250x0_state = 0;
while (1) {
??wwatch (SPI_OUT);
??printf ("SPI_OUT Detectedn");
??if ((PORT1 & 0x01) == 0)
????{
????printf ("Calling AT250X0 Routinesn");
????spi_at250x0_state = spi_at250x0 (spi_at250x0_state);
????if (spi_at250x0_status & 0x01)
??????swatch (0.000100);
??????spi_at250x0_status &= ~0x01;
????}
??else
????{
????printf ("Resetting AT250X0 Routinesn");
????spi_at250x0_state = 0;
????}
??}
}
/*-----------------------------------------------
Enable the signal function for SPI writes.
-----------------------------------------------*/
spi_watcher ();