Skip to content

Commit

Permalink
[IN] Fixes for segement display (#11)
Browse files Browse the repository at this point in the history
Added few fixes for segment display rendering.
Added pico_example test for segment display.
  • Loading branch information
matgla authored Dec 12, 2024
1 parent 5c96d03 commit 22af84d
Show file tree
Hide file tree
Showing 35 changed files with 936 additions and 52 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/rp2040_renode_osx_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
jobs:
osx_rp2040_tests:
name: "Renode MacOS"
runs-on: macos-14
runs-on: macos-15
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -26,6 +26,10 @@ jobs:
shell: bash
run: |
pip3 install --break-system-packages -r /Applications/Renode.app/Contents/MacOS/tests/requirements.txt
- name: Install MacOS mono
shell: bash
run: |
brew install mono-mdk
- uses: actions/download-artifact@v4
with:
name: pico-examples
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ report.html
mono_crash*
.DS_Store
venv
obj/
12 changes: 11 additions & 1 deletion cores/initialize_peripherals.resc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mach create $machine_name
mach create $machine_name

include $ORIGIN/../emulation/externals/w25q16.cs

Expand Down Expand Up @@ -29,6 +29,11 @@ include $ORIGIN/../emulation/peripherals/gpio/rp2040_qspi_pads.cs


include $ORIGIN/../emulation/peripherals/pio/rp2040_pio.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.CPU.PioSimPathExtension"
emulation CreateSegmentDisplayTester "piosim_path"
piosim_path path $ORIGIN/../piosim


include $ORIGIN/../emulation/peripherals/spi/rp2040_spi.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.SPI.PL022"
include $ORIGIN/../emulation/peripherals/spi/rp2040_xip_ssi.cs
Expand All @@ -48,8 +53,13 @@ include $ORIGIN/../emulation/peripherals/watchdog/rp2040_watchdog.cs
include $ORIGIN/../emulation/peripherals/i2c/rp2040_i2c.cs

include $ORIGIN/../emulation/externals/pcf8523.cs

include $ORIGIN/../emulation/externals/i_segment_display.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.Miscellaneous.ISegmentDisplay"

include $ORIGIN/../emulation/externals/segment_display.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.Miscellaneous.SegmentDisplay"


include $ORIGIN/../emulation/peripherals/psm/rp2040_psm.cs

14 changes: 14 additions & 0 deletions emulation/externals/i_segment_display.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using Antmicro.Renode.Peripherals;

namespace Antmicro.Renode.Peripherals.Miscellaneous
{
public interface ISegmentDisplay : IPeripheral
{
event Action<ISegmentDisplay, bool[], bool[]> StateChanged;
bool[] Segments { get; }
bool[] Cells { get; }
void OnGPIO(int number, bool value);
void SetSegment(int number, bool state);
}
}
2 changes: 1 addition & 1 deletion emulation/externals/pcf8523.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ public void FinishTransmission()

}
}
}
}
67 changes: 60 additions & 7 deletions emulation/externals/segment_display.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
using System;
using Antmicro.Renode.Core;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Utilities;
using System.Threading;

namespace Antmicro.Renode.Peripherals.Miscellaneous
{
public class SegmentDisplay : IPeripheral, IGPIOReceiver
public class SegmentDisplay : ISegmentDisplay, IGPIOReceiver
{
public SegmentDisplay(int segments = 7, int cells = 1, int colon = 0)
public SegmentDisplay(IMachine machine, int segments = 7, int cells = 1, int colon = 0, float? filteringTime = null)
{
sync = new object();
NumberOfSegments = segments;
NumberOfCells = cells;
this.filteringTime = filteringTime;
Colon = colon;
this.segments = new bool[NumberOfSegments];
this.cells = new bool[NumberOfCells];
this.machine = machine;
Reset();
}

Expand All @@ -28,6 +32,7 @@ public void Reset()
{
this.segments[s] = false;
}
timeoutStarted = false;
}

public void OnGPIO(int number, bool value)
Expand All @@ -48,32 +53,44 @@ public void OnGPIO(int number, bool value)
}
}

public event Action<SegmentDisplay, bool[], bool[]> StateChanged;
public event Action<ISegmentDisplay, bool[], bool[]> StateChanged;

public void SetSegment(int number, bool state)
{
bool stateChanged = false;

lock (sync)
{
if (segments[number] != state)
{
segments[number] = state;
StateChanged?.Invoke(this, cells, segments);
this.Log(LogLevel.Noisy, "Segment[{0}] state changed to: {1}", number, state);
stateChanged = true;
}
}

if (stateChanged)
{
TriggerStateChange();
}

}

public void SetCell(int number, bool state)
{
bool stateChanged = false;
lock (sync)
{
if (cells[number] != state)
{
cells[number] = state;
StateChanged?.Invoke(this, cells, segments);
this.Log(LogLevel.Noisy, "Cell[{0}] state changed to: {1}", number, state);
stateChanged = true;
}
}

if (stateChanged)
{
TriggerStateChange();
}
}

public bool[] Segments
Expand All @@ -91,8 +108,44 @@ public bool[] Cells
public readonly int NumberOfCells;
public readonly int Colon;

private void TriggerStateChange()
{
// if filtering time is set
// code will filter out events that occured in time less than filteringTime
// this is needed to filter out fast switching changes on GPIO to be visible as single shot
if (filteringTime != null)
{
lock (sync)
{
if (timeoutStarted)
{
return;
}
timeoutStarted = true;
}
System.Threading.Timer timer = null;
timer = new System.Threading.Timer((t) =>
{
lock (sync)
{
StateChanged?.Invoke(this, cells, segments);
timeoutStarted = false;
}
timer.Dispose();
}, null, (int)(filteringTime.Value * 1000), System.Threading.Timeout.Infinite);
}
else
{
StateChanged?.Invoke(this, cells, segments);
}

}

private readonly object sync;
private bool[] segments;
private bool[] cells;
private float? filteringTime;
private IMachine machine;
private bool timeoutStarted;
}
}
2 changes: 0 additions & 2 deletions emulation/peripherals/dma/rpdma.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

using Antmicro.Renode.Core;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Core.Structure.Registers;
using Antmicro.Renode.Utilities;
using System;
Expand All @@ -24,7 +23,6 @@ namespace Antmicro.Renode.Peripherals.DMA
// data for CRC may be lost after DMA peripheral to peripheral operation
//
// basically is copy of DmaEngine with CRC calculation injected

public class RPDMA : RP2040PeripheralBase, IGPIOReceiver, IKnownSize, INumberedGPIOOutput
{
private enum DREQ
Expand Down
48 changes: 44 additions & 4 deletions emulation/peripherals/pio/rp2040_pio.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,49 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;

namespace Antmicro.Renode.Peripherals.CPU
{

public static class PioSimPathExtension
{
public static void CreateSegmentDisplayTester(this Emulation emulation, string name)
{
var piosimPath = new PioSimPath();
emulation.ExternalsManager.AddExternal(piosimPath, name);
}
}

public class PioSimPath : IExternal
{
public string path;
}
// parts of this class can be left unmodified;
// to integrate an external simulator you need to
// look for comments in the code below
public class RP2040PIOCPU : BaseCPU, IRP2040Peripheral, IGPIOReceiver, ITimeSink, IDisposable, IDoubleWordPeripheral, IKnownSize
{
private static string GetSourceFileDirectory([CallerFilePath] string sourceFilePath = "")
{
// Retrieve all environment variables
IDictionary environmentVariables = Environment.GetEnvironmentVariables();

// Print each environment variable and its value
foreach (DictionaryEntry entry in environmentVariables)
{

Logger.Log(LogLevel.Error, "file: {0}: {1}", entry.Key, entry.Value);
}
return Path.GetDirectoryName(sourceFilePath);
}

private static string GetPioSimLibraryPath()
private static string GetPioSimPath()
{
return Path.GetFullPath(GetSourceFileDirectory() + "/../../../piosim/");
}

private static string GetPioSimLibraryPath(string basepath)
{
string libraryName;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand All @@ -43,14 +72,25 @@ private static string GetPioSimLibraryPath()
{
libraryName = "libpiosim.so";
}
return Path.GetFullPath(GetSourceFileDirectory() + "/../../../piosim/" + libraryName);
return Path.GetFullPath(basepath + "/" + libraryName);
}

public RP2040PIOCPU(string cpuType, IMachine machine, ulong address, GPIOPort.RP2040GPIO gpio, uint id, RP2040Clocks clocks, Endianess endianness = Endianess.LittleEndian, CpuBitness bitness = CpuBitness.Bits32)
public RP2040PIOCPU(string cpuType, IMachine machine, ulong address, GPIOPort.RP2040GPIO gpio, uint id, RP2040Clocks clocks,
Endianess endianness = Endianess.LittleEndian, CpuBitness bitness = CpuBitness.Bits32)
: base(id + 100, cpuType, machine, endianness, bitness)
{
pioId = (int)id;
string libraryFile = GetPioSimLibraryPath();
// Get the directory of the executing assembly
string piosimPath = "";
if (EmulationManager.Instance.CurrentEmulation.ExternalsManager.TryGetByName("piosim_path", out PioSimPath result))
{
piosimPath = result.path;
}
else
{
piosimPath = GetPioSimPath();
}
string libraryFile = GetPioSimLibraryPath(piosimPath);
binder = new NativeBinder(this, libraryFile);
machine.GetSystemBus(this).Register(this, new BusRangeRegistration(new Antmicro.Renode.Core.Range(address, (ulong)Size)));
this.gpio = gpio;
Expand Down
17 changes: 17 additions & 0 deletions raspberry_clock.repl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using "boards/raspberry_pico.repl"

led1: Miscellaneous.LED @ gpio 0

segment_display: Miscellaneous.SegmentDisplay @ gpio 1 {
cells: 4;
segments: 8;
colon: 2
}

gpio:
0 -> led1@0
[1-12] -> segment_display@[0-11]


button: Miscellaneous.Button @ gpio 13
-> gpio@13
9 changes: 5 additions & 4 deletions tests/build_pico_examples.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
#!/bin/sh
#!/bin/bash
START=`pwd`
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
echo "Using script directory: $SCRIPT_DIR"

cd $SCRIPT_DIR
revision=`cat ./pico_examples_revision`
revision=`cat $SCRIPT_DIR/pico_examples_revision`
echo "Using Pico Examples revision: $revision"

if [ ! -d pico-examples ]; then
git clone https://github.com/raspberrypi/pico-examples.git
git checkout $value
for i in pico_examples_patches/*.patch; do
cd pico-examples
cd pico-examples
git am < ../${i}
cd ..
done
Expand All @@ -22,4 +23,4 @@ cd build
PICO_SDK_FETCH_FROM_GIT=1 cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DPICO_BOARD=pico
cmake --build .
cd ../..
cd $START
cd $START
2 changes: 2 additions & 0 deletions tests/prepare.resc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ path add $ORIGIN/..
log "Loading board initialization file"
include $board_initialization_file

include $ORIGIN/testers/load_testers.resc

log "Loading firmware file"
sysbus LoadELF $global.TEST_FILE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ Run successfully 'onboard_temperature' example
Create Terminal Tester sysbus.uart0

Execute Command sysbus.adc SetOnboardTemperature 27.8
${l} Wait For Next Line On Uart timeout=1
${l} Wait For Next Line On Uart timeout=2
@{elements} Split String ${l.line}
Should Be Equal As Numbers With Tolerance ${elements}[3] 27.8 0.1

Execute Command sysbus.adc SetOnboardTemperature 40.2
Wait For Line On Uart 40 timeout=2
${l} Wait For Next Line On Uart timeout=1
${l} Wait For Next Line On Uart timeout=2
@{elements} Split String ${l.line}
Should Be Equal As Numbers With Tolerance ${elements}[3] 40.2 0.1

Expand Down
6 changes: 3 additions & 3 deletions tests/testcases/dma/hello_dma/hello_dma.robot
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
Suite Setup Setup
Suite Teardown Teardown
Test Teardown Test Teardown
Test Timeout 40 seconds
Test Timeout 120 seconds

Resource ${CURDIR}/../../../common.resource

*** Test Cases ***
Run successfully 'hello_adc' example
Run successfully 'hello_dma' example
Execute Command include @${CURDIR}/hello_dma.resc
Execute Command logLevel -1

Create Terminal Tester sysbus.uart0

Wait For Line On Uart Hello, world! (from DMA) timeout=1
Wait For Line On Uart Hello, world! (from DMA) timeout=4


Loading

0 comments on commit 22af84d

Please sign in to comment.