mirror of
https://github.com/quorten/macsehw.git
synced 2024-05-29 05:41:34 +00:00
RTC: Implement missing links for physical test mode.
Also minor refactoring.
This commit is contained in:
parent
745d73b98a
commit
655c495bb3
|
@ -448,6 +448,8 @@ void lingpirq_cleanup(void)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "arduino_sdef.h"
|
#include "arduino_sdef.h"
|
||||||
|
#include "rpi-gpio.h"
|
||||||
|
#include "lin-gpirq.h"
|
||||||
#include "simavr-support.h"
|
#include "simavr-support.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -475,7 +477,26 @@ uint8_t const *VIA = vBase;
|
||||||
bool g_waitTimeUp = true;
|
bool g_waitTimeUp = true;
|
||||||
uint8_t g_timePoll = 0;
|
uint8_t g_timePoll = 0;
|
||||||
|
|
||||||
#define viaBitRead(ptr, bit) (bitRead(*(ptr), (bit)))
|
enum PhyPins { PHY_SEC1, PHY_CE, PHY_CLK, PHY_DATA };
|
||||||
|
|
||||||
|
// Physical hardware test mode (via Raspberry Pi).
|
||||||
|
bool8_t g_phyMode = false;
|
||||||
|
|
||||||
|
// Emulated RTC VIA connections to GPIO pin mappings.
|
||||||
|
uint8_t g_phyToGpio[4] = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
uint8_t viaBitRead(uint8_t *ptr, uint8_t bit)
|
||||||
|
{
|
||||||
|
if (g_phyMode) {
|
||||||
|
switch (bit) {
|
||||||
|
case rtcData:
|
||||||
|
return rpi_gpio_get_pin(g_phyToGpio[PHY_DATA]);
|
||||||
|
default:
|
||||||
|
return 0; // unrecognized signals read as zero
|
||||||
|
}
|
||||||
|
} // else
|
||||||
|
return bitRead(*(ptr), (bit));
|
||||||
|
}
|
||||||
|
|
||||||
void viaBitWrite(uint8_t *ptr, uint8_t bit, uint8_t bitvalue)
|
void viaBitWrite(uint8_t *ptr, uint8_t bit, uint8_t bitvalue)
|
||||||
{
|
{
|
||||||
|
@ -488,27 +509,42 @@ void viaBitWrite(uint8_t *ptr, uint8_t bit, uint8_t bitvalue)
|
||||||
// Send the signal to the actual hardware.
|
// Send the signal to the actual hardware.
|
||||||
switch (bit) {
|
switch (bit) {
|
||||||
case rtcEnb:
|
case rtcEnb:
|
||||||
avr_raise_irq(bench_irqs + IRQ_CE, bitvalue & 1);
|
if (g_phyMode)
|
||||||
|
rpi_gpio_set_pin(g_phyToGpio[PHY_CE], bitvalue & 1);
|
||||||
|
else
|
||||||
|
avr_raise_irq(bench_irqs + IRQ_CE, bitvalue & 1);
|
||||||
break;
|
break;
|
||||||
case rtcClk:
|
case rtcClk:
|
||||||
avr_raise_irq(bench_irqs + IRQ_CLK, bitvalue & 1);
|
if (g_phyMode)
|
||||||
|
rpi_gpio_set_pin(g_phyToGpio[PHY_CLK], bitvalue & 1);
|
||||||
|
else
|
||||||
|
avr_raise_irq(bench_irqs + IRQ_CLK, bitvalue & 1);
|
||||||
break;
|
break;
|
||||||
case rtcData:
|
case rtcData:
|
||||||
avr_raise_irq(bench_irqs + IRQ_DATA_IN, bitvalue & 1);
|
if (g_phyMode)
|
||||||
|
rpi_gpio_set_pin(g_phyToGpio[PHY_DATA], bitvalue & 1);
|
||||||
|
else
|
||||||
|
avr_raise_irq(bench_irqs + IRQ_DATA_IN, bitvalue & 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break; // unrecognized signals do nothing
|
break; // unrecognized signals do nothing
|
||||||
}
|
}
|
||||||
} else if (ptr == vBase + vDirB) {
|
} else if (ptr == vBase + vDirB) {
|
||||||
// TODO FIXME:
|
if (g_phyMode) {
|
||||||
|
// We only support changing the direction of the data pin.
|
||||||
// The main special handling we do here is to set to the
|
if (bit == rtcData) {
|
||||||
// corresponding buffer bit to the input value as soon as we
|
uint8_t fn = (bitvalue == DIR_IN) ? GPFN_INPUT : GPFN_OUTPUT;
|
||||||
// change to an input type. With the `simavr` setup, we simply
|
rpi_gpio_set_fn(g_phyToGpio[PHY_DATA], fn);
|
||||||
// set to default logic value 1 and we will get an IRQ if we
|
}
|
||||||
// should do otherwise.
|
} else {
|
||||||
if (bitvalue == DIR_IN)
|
// The main special handling we do here is to set to the
|
||||||
bitWrite(vBase[vBufB], bit, 1);
|
// corresponding buffer bit to the input value as soon as we
|
||||||
|
// change to an input type. With the `simavr` setup, we simply
|
||||||
|
// set to default logic value 1 and we will get an IRQ if we
|
||||||
|
// should do otherwise.
|
||||||
|
if (bitvalue == DIR_IN)
|
||||||
|
bitWrite(vBase[vBufB], bit, 1);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
// Update our register value.
|
// Update our register value.
|
||||||
|
@ -527,41 +563,41 @@ void viaBitWrite(uint8_t *ptr, uint8_t bit, uint8_t bitvalue)
|
||||||
silicon RTC. */
|
silicon RTC. */
|
||||||
void waitQuarterCycle(void)
|
void waitQuarterCycle(void)
|
||||||
{
|
{
|
||||||
#ifdef RPI_DRIVER
|
if (g_phyMode) {
|
||||||
struct timespec tv = { 0, 500000 };
|
struct timespec tv = { 0, 500000 };
|
||||||
struct timespec tvNext;
|
struct timespec tvNext;
|
||||||
do {
|
do {
|
||||||
if (clock_nanosleep(CLOCK_MONOTONIC, 0, &tv, &tvNext) == 0)
|
if (clock_nanosleep(CLOCK_MONOTONIC, 0, &tv, &tvNext) == 0)
|
||||||
break;
|
break;
|
||||||
tv.tv_nsec = tvNext.tv_nsec;
|
tv.tv_nsec = tvNext.tv_nsec;
|
||||||
} while (tv.tv_nsec > 0);
|
} while (tv.tv_nsec > 0);
|
||||||
#else
|
} else {
|
||||||
// Unfortunately, if the AVR runs at 32.768 kHz, I've found from
|
// Unfortunately, if the AVR runs at 32.768 kHz, I've found from
|
||||||
// simulation that serial communications are only reliable at an
|
// simulation that serial communications are only reliable at an
|
||||||
// abysmal 50 Hz serial clock speed. Therefore, running at a higher
|
// abysmal 50 Hz serial clock speed. Therefore, running at a
|
||||||
// core speed and using a phase-locked loop on the crystal clock
|
// higher core speed and using a phase-locked loop on the crystal
|
||||||
// frequency a must.
|
// clock frequency a must.
|
||||||
struct timespec tv, tvTarget;
|
struct timespec tv, tvTarget;
|
||||||
// N.B. Over here we are using cycle timers mainly to prevent
|
// N.B. Over here we are using cycle timers mainly to prevent
|
||||||
// simulation waits stretching unbearably long.
|
// simulation waits stretching unbearably long.
|
||||||
g_timePoll = 16;
|
g_timePoll = 16;
|
||||||
avr_cycle_timer_register(avr, g_timePoll, notify_timeup, NULL);
|
avr_cycle_timer_register(avr, g_timePoll, notify_timeup, NULL);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
|
||||||
tvTarget.tv_nsec = tv.tv_nsec + 500000;
|
|
||||||
tvTarget.tv_sec = tv.tv_sec;
|
|
||||||
if (tvTarget.tv_nsec >= 1000000000) {
|
|
||||||
tvTarget.tv_nsec -= 1000000000;
|
|
||||||
tvTarget.tv_sec++;
|
|
||||||
}
|
|
||||||
while (tv.tv_sec < tvTarget.tv_sec ||
|
|
||||||
(tv.tv_sec == tvTarget.tv_sec &&
|
|
||||||
tv.tv_nsec < tvTarget.tv_nsec)) {
|
|
||||||
if (!simAvrStep())
|
|
||||||
break;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||||
|
tvTarget.tv_nsec = tv.tv_nsec + 500000;
|
||||||
|
tvTarget.tv_sec = tv.tv_sec;
|
||||||
|
if (tvTarget.tv_nsec >= 1000000000) {
|
||||||
|
tvTarget.tv_nsec -= 1000000000;
|
||||||
|
tvTarget.tv_sec++;
|
||||||
|
}
|
||||||
|
while (tv.tv_sec < tvTarget.tv_sec ||
|
||||||
|
(tv.tv_sec == tvTarget.tv_sec &&
|
||||||
|
tv.tv_nsec < tvTarget.tv_nsec)) {
|
||||||
|
if (!simAvrStep())
|
||||||
|
break;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||||
|
}
|
||||||
|
g_timePoll = 0;
|
||||||
}
|
}
|
||||||
g_timePoll = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitHalfCycle(void)
|
void waitHalfCycle(void)
|
||||||
|
@ -578,26 +614,55 @@ void waitCycle(void)
|
||||||
|
|
||||||
void waitOneSec(void)
|
void waitOneSec(void)
|
||||||
{
|
{
|
||||||
#ifdef RPI_DRIVER
|
if (g_phyMode) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
#else
|
} else {
|
||||||
struct timespec tv, tvTarget;
|
struct timespec tv, tvTarget;
|
||||||
// N.B. Over here we are using cycle timers mainly to prevent
|
// N.B. Over here we are using cycle timers mainly to prevent
|
||||||
// simulation waits stretching unbearably long.
|
// simulation waits stretching unbearably long.
|
||||||
g_timePoll = 16;
|
g_timePoll = 16;
|
||||||
avr_cycle_timer_register(avr, g_timePoll, notify_timeup, NULL);
|
avr_cycle_timer_register(avr, g_timePoll, notify_timeup, NULL);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
|
||||||
tvTarget.tv_nsec = tv.tv_nsec;
|
|
||||||
tvTarget.tv_sec = tv.tv_sec + 1;
|
|
||||||
while (tv.tv_sec < tvTarget.tv_sec ||
|
|
||||||
(tv.tv_sec == tvTarget.tv_sec &&
|
|
||||||
tv.tv_nsec < tvTarget.tv_nsec)) {
|
|
||||||
if (!simAvrStep())
|
|
||||||
break;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||||
|
tvTarget.tv_nsec = tv.tv_nsec;
|
||||||
|
tvTarget.tv_sec = tv.tv_sec + 1;
|
||||||
|
while (tv.tv_sec < tvTarget.tv_sec ||
|
||||||
|
(tv.tv_sec == tvTarget.tv_sec &&
|
||||||
|
tv.tv_nsec < tvTarget.tv_nsec)) {
|
||||||
|
if (!simAvrStep())
|
||||||
|
break;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||||
|
}
|
||||||
|
g_timePoll = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viaInit(void)
|
||||||
|
{
|
||||||
|
if (g_phyMode) {
|
||||||
|
// Setup GPIO pins.
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_SEC1], GPFN_INPUT);
|
||||||
|
rpi_gpio_set_pull(g_phyToGpio[PHY_SEC1], GPUL_UP);
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_CE], GPFN_OUTPUT);
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_CLK], GPFN_OUTPUT);
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_DATA], GPFN_OUTPUT);
|
||||||
|
// Setup GPIO IRQ for 1-second pin.
|
||||||
|
lingpirq_setup(g_phyToGpio[PHY_SEC1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viaDestroy(void)
|
||||||
|
{
|
||||||
|
if (g_phyMode) {
|
||||||
|
// Cleanup GPIO pins, change to all pull-up inputs.
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_CE], GPFN_INPUT);
|
||||||
|
rpi_gpio_set_pull(g_phyToGpio[PHY_CE], GPUL_UP);
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_CLK], GPFN_INPUT);
|
||||||
|
rpi_gpio_set_pull(g_phyToGpio[PHY_CLK], GPUL_UP);
|
||||||
|
rpi_gpio_set_fn(g_phyToGpio[PHY_DATA], GPFN_INPUT);
|
||||||
|
rpi_gpio_set_pull(g_phyToGpio[PHY_DATA], GPUL_UP);
|
||||||
|
// Cleanup GPIO IRQ for 1-second pin.
|
||||||
|
lingpirq_cleanup();
|
||||||
}
|
}
|
||||||
g_timePoll = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
@ -1221,7 +1286,6 @@ bool8_t fileDumpAllXMem(const char *filename)
|
||||||
/*
|
/*
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -1672,12 +1736,11 @@ uint8_t execMultiCmdLine(char *lineBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return false on exit with error, true on graceful exit.
|
// Return false on exit with error, true on graceful exit.
|
||||||
bool8_t cmdLoop(void)
|
bool8_t cmdLoop(bool8_t notScripted)
|
||||||
{
|
{
|
||||||
uint8_t retVal = true;
|
uint8_t retVal = true;
|
||||||
char lineBuf[512];
|
char lineBuf[512];
|
||||||
char *parsePtr;
|
char *parsePtr;
|
||||||
bool8_t notScripted = isatty(STDIN_FILENO);
|
|
||||||
|
|
||||||
// Print the prompt character.
|
// Print the prompt character.
|
||||||
if (notScripted) putchar('*');
|
if (notScripted) putchar('*');
|
||||||
|
@ -2030,7 +2093,6 @@ void writehex(char *rch)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "sim_avr.h"
|
#include "sim_avr.h"
|
||||||
#include "avr_ioport.h"
|
#include "avr_ioport.h"
|
||||||
|
@ -2090,16 +2152,6 @@ void pin_change_notify(avr_irq_t *irq, uint32_t value, void *param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
sig_int(int sign)
|
|
||||||
{
|
|
||||||
printf("signal caught, simavr terminating\n");
|
|
||||||
if (avr)
|
|
||||||
avr_terminate(avr);
|
|
||||||
pramDestroy();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setupSimAvr(char *progName, const char *fname, bool8_t interactMode)
|
int setupSimAvr(char *progName, const char *fname, bool8_t interactMode)
|
||||||
{
|
{
|
||||||
elf_firmware_t f;
|
elf_firmware_t f;
|
||||||
|
@ -2237,9 +2289,6 @@ int setupSimAvr(char *progName, const char *fname, bool8_t interactMode)
|
||||||
|
|
||||||
fputs( "\nSimulation launching:\n", stdout);
|
fputs( "\nSimulation launching:\n", stdout);
|
||||||
|
|
||||||
signal(SIGINT, sig_int);
|
|
||||||
signal(SIGTERM, sig_int);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2853,15 +2902,36 @@ uint8_t getSuiteMode(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include "arduino_sdef.h"
|
#include "arduino_sdef.h"
|
||||||
|
#include "via-emu.h"
|
||||||
#include "simavr-support.h"
|
#include "simavr-support.h"
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
#include "auto-test-suite.h"
|
#include "auto-test-suite.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void mainCleanup(void)
|
||||||
|
{
|
||||||
|
viaDestroy();
|
||||||
|
if (!g_phyMode) {
|
||||||
|
if (avr)
|
||||||
|
{ avr_terminate(avr); avr = NULL; }
|
||||||
|
}
|
||||||
|
pramDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sig_int(int sign)
|
||||||
|
{
|
||||||
|
printf("signal caught, terminating\n");
|
||||||
|
mainCleanup();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *firmwareName = "";
|
char *firmwareName = "";
|
||||||
|
@ -2873,40 +2943,64 @@ int main(int argc, char *argv[])
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-h") == 0 ||
|
if (strcmp(argv[i], "-h") == 0 ||
|
||||||
strcmp(argv[i], "--help") == 0) {
|
strcmp(argv[i], "--help") == 0) {
|
||||||
printf("Usage: %s [-i] FIRMWARE_FILE\n"
|
printf(
|
||||||
"\n"
|
"Usage: %s [-i] [-r a,b,c,d] FIRMWARE_FILE\n"
|
||||||
" -i Run interactive mode\n"
|
"\n"
|
||||||
"\n", argv[0]);
|
" -i Run interactive mode\n"
|
||||||
|
" -r Physical hardware test mode (via Raspberry Pi).\n"
|
||||||
|
" Configure SEC1,CE*,CLK,DATA to the given BCM GPIO pin numbers.\n"
|
||||||
|
"\n", argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(argv[i], "-i") == 0)
|
} else if (strcmp(argv[i], "-i") == 0)
|
||||||
interactMode = true;
|
interactMode = true;
|
||||||
else
|
else if (strcmp(argv[i], "-r") == 0) {
|
||||||
|
i++;
|
||||||
|
if (i >= argc) {
|
||||||
|
fprintf(stderr, "%s: Missing command line argument.\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_phyMode = true;
|
||||||
|
sscanf(argv[i], "%d,%d,%d,%d",
|
||||||
|
g_phyToGpio + PHY_SEC1, g_phyToGpio + PHY_CE,
|
||||||
|
g_phyToGpio + PHY_CLK, g_phyToGpio + PHY_DATA);
|
||||||
|
if (g_phyToGpio[PHY_SEC1] == 0 ||
|
||||||
|
g_phyToGpio[PHY_CE] == 0 ||
|
||||||
|
g_phyToGpio[PHY_CLK] == 0 ||
|
||||||
|
g_phyToGpio[PHY_DATA] == 0) {
|
||||||
|
fprintf(stderr, "%s: Invalid pin configuration.\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
firmwareName = argv[i];
|
firmwareName = argv[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal(SIGINT, sig_int);
|
||||||
|
signal(SIGTERM, sig_int);
|
||||||
|
|
||||||
pramInit();
|
pramInit();
|
||||||
retVal = setupSimAvr(argv[0], firmwareName, interactMode);
|
viaInit();
|
||||||
|
if (!g_phyMode)
|
||||||
|
retVal = setupSimAvr(argv[0], firmwareName, interactMode);
|
||||||
if (retVal != 0)
|
if (retVal != 0)
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
if (interactMode) {
|
if (interactMode) {
|
||||||
|
bool8_t notScripted = isatty(STDIN_FILENO);
|
||||||
fputs("Launching interactive console.\n", stdout);
|
fputs("Launching interactive console.\n", stdout);
|
||||||
if (isatty(STDIN_FILENO))
|
if (notScripted)
|
||||||
fputs("Type help for summary of commands.\n", stdout);
|
fputs("Type help for summary of commands.\n", stdout);
|
||||||
if (!cmdLoop()) {
|
if (!cmdLoop(notScripted)) {
|
||||||
avr_terminate(avr);
|
mainCleanup();
|
||||||
pramDestroy();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
avr_terminate(avr);
|
mainCleanup();
|
||||||
pramDestroy();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run automated test suite.
|
// Run automated test suite.
|
||||||
fputs("Running automated test suite.\n", stdout);
|
fputs("Running automated test suite.\n", stdout);
|
||||||
retVal = !autoTestSuite(false, true, true);
|
retVal = !autoTestSuite(false, true, true);
|
||||||
avr_terminate(avr);
|
mainCleanup();
|
||||||
pramDestroy();
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user