Write Register

Hi guys,

I am trying to write|read register from Intel Quark C1000 (processor of 101)

I do something like that :

#include "portable.h"
#include "scss_registers.h"

/*  QRK_WDT_BASE_ADDR : OFFSET
 *  QRK_WDT_CR : bit 0 Enable/Disable the WDT
 *  QRK_WDT_TORR : Value to reach to reset
 *  QRK_WDT_CCVR : Actual value of WDT
 *  QRK_WDT_CRR : This register is used to restart (kick) the Watchdog Timer.
 *  As a safety feature to prevent accidental restarts, the value 0x76 must be written.
 *  QRK_WDT_COMP_PARAM_1 JUST FOR TEST
 *  
 */

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial);
  Serial.println("START");
  Serial.println(MMIO_REG_VAL_FROM_BASE(QRK_WDT_BASE_ADDR, QRK_WDT_TORR), HEX); /* MUST BE 0000_0000h */
  Serial.println(MMIO_REG_VAL_FROM_BASE(QRK_WDT_BASE_ADDR, QRK_WDT_CCVR), HEX); /* MUST BE 0000_FFFFh */
  Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1), HEX); /* MUST BE 1000_0242h */
  Serial.println(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1, HEX);
  Serial.println(READ_ARC_REG(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1), HEX); /* MUST BE 1000_0242h */
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);

}

void loop() {
  // put your main code here, to run repeatedly:

}

First of all, MMIO_REG_VAL_FROM_BASE return me 0 and that's not correct (default value by data sheet are write inside comments)
And then I am trying READ_ARC_REG but this function crash my Arduino and don't print anything on serial and led at pin 13 does not go on.

Someone can help me ?

I don't think the arduino code runs on the quark, so it probably doesn't have access to all the quark registers.
The arduino code runs on the ARC core...

Hm I don't think so because I easily can access to timer inside the quark processor.

Here is an exemple :

#include "portable.h"
#include "scss_registers.h"

#define timerBase 0xB0000800
#define Timer1EOI 0x0C
#define Timer1ControlReg 0x08
#define Timer1CurrentValue 0x04

uint32_t timer1ctrl = timerBase + Timer1ControlReg;
uint32_t timer1cv = timerBase + Timer1CurrentValue;
uint32_t timer1rst = timerBase + Timer1EOI;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial);
  Serial.println("START");
  MMIO_REG_VAL(timer1ctrl) = 0x01; /* Lunch the timer */

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("timer : ");
  Serial.println(MMIO_REG_VAL(timer1cv), HEX); /* Value will dicrease until 0 and restart to the max value */

}

You can comment this line MMIO_REG_VAL(timer1ctrl) = 0x01; /* Lunch the timer */ and see that timer doesn't decrease anymore.

I didn't test all register, but I guess I can't access to the watchdog and I don't know why :confused:

Thanks for this sample code dude, you totally helped me figure out where the QRK registers are. I am very new so I can't figure out why you are getting 0 for the first part. But I am pretty sure your program is crashing from the READ_ARC_REG code because you inputting a Quark core register into the ARC core register command. There are two cores on the board the Quark, and the ARC. You can find the ARC registers at:

no problem,
I know that 101 got 2 processors. The problem is the main core is the quark core which execute arduino program inside the arc core.
And I didn't find watchdog on arc...

It is why i would access to watchdog inside quark core.

for the crash you're right I guess too.

The ARC and the "host" processor (x86) share a large chunk of memory that contains a lot of the memory-mapped IO, including the Watchdog Timer. Both cores can access these registers using the same base address.

Howeve, the ARC core has a seperate physical memory space (referred to as "auxiliary memory space" in the datasheet) which can ONLY be accessed by the ARC core. The ARC toolchain provides some instrinsics "_sr()" and "_lr()", which are required to explicitly request an address from the ARC's auxliliary memory. READ_ARC_REG uses these intrinsics, and so should only be used when you need something from ARC's auxiliary memory.

This is probably why you're crashing on READ_ARC_REG-- that address may not even exist in the auxiliary memory space, or if it does, we have no idea what it holds.

Since the WDOG timer's registers live in the common MMIO space, then MMIO_REG_VAL is the correct way to read/write watchdog registers from ARC.

Okay got it,
crash problem is resolved, but still don't get why I can't read default value by using MMIO_REG_VAL.

This line :
Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1), HEX);

should return 1000_0242h as specified in datasheet, isn't he (see page 437 of datasheet) ?

(Base address watrchdog is B0000000h and comp param 1 value is 0xF4 so i am reading register B00000F4h of memory)

the problem is that i get only 0h value.

here is the code :

#include "portable.h"
#include "scss_registers.h"

/*  QRK_WDT_BASE_ADDR : B0000000h
 *  QRK_WDT_CR : bit 0 Enable/Disable the WDT
 *  QRK_WDT_TORR : Value to reach to reset
 *  QRK_WDT_CCVR : Actual value of WDT
 *  QRK_WDT_CRR : This register is used to restart (kick) the Watchdog Timer.
 *  As a safety feature to prevent accidental restarts, the value 0x76 must be written.
 *  QRK_WDT_COMP_PARAM_1 JUST FOR TEST
 *  
 */

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial);
  Serial.println("START");
  Serial.println(MMIO_REG_VAL_FROM_BASE(QRK_WDT_BASE_ADDR, QRK_WDT_TORR), HEX); /* MUST BE 0000_0000h */
  Serial.println(MMIO_REG_VAL_FROM_BASE(QRK_WDT_BASE_ADDR, QRK_WDT_CCVR), HEX); /* MUST BE 0000_FFFFh */
  Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1), HEX); /* MUST BE 1000_0242h */
  Serial.println(QRK_WDT_BASE_ADDR + QRK_WDT_COMP_PARAM_1, HEX);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);

}

void loop() {
  // put your main code here, to run repeatedly:

}

and here the result :

START
0
0
0
B00000F4

That's just the default value.... how do you know those registers haven't been written to yet?

As you said, they are maybe initialize in boot, but i didn't find anything about watchdog in code source from intel.

I tried a little program that should start the watchdog and reset automatically my arduino board (cause I don't reset timer) and I still got only 0 value...

At least write and read back the value is not possible...

Here is the new code I tried :

#include "portable.h"
#include "scss_registers.h"

/*  QRK_WDT_BASE_ADDR : B0000000h
 *  QRK_WDT_CR : bit 0 Enable/Disable the WDT
 *  QRK_WDT_TORR : Value to reach to reset
 *  QRK_WDT_CCVR : Actual value of WDT
 *  QRK_WDT_CRR : This register is used to restart (kick) the Watchdog Timer.
 *  As a safety feature to prevent accidental restarts, the value 0x76 must be written.
 *  QRK_WDT_COMP_PARAM_1 JUST FOR TEST
 *  
 */

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_TORR) |= 0x74; /* ~29s Watchdog */
  Serial.print("read at address : ");
  Serial.print(QRK_WDT_BASE_ADDR + QRK_WDT_TORR, HEX);
  Serial.print(" the value : ");
  Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_TORR));
  MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_CR) |= 0x01; /* start watchdog */
  Serial.print("read at address : ");
  Serial.print(QRK_WDT_BASE_ADDR + QRK_WDT_CR, HEX);
  Serial.print(" the value : ");
  Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_CR));
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(MMIO_REG_VAL(QRK_WDT_BASE_ADDR + QRK_WDT_CCVR), HEX); /* current value of WDT */

}

Here the printed value :

read at address : B0000004 the value : 0
read at address : B0000000 the value : 0
0
0
0
0
0
0
0
0
0
0
etc etc

maybe they are protected or something ?

No idea. We have not developed any drivers for the WDT and the Arduino101, so I have little experience with the hardware.

Fortunately, though, somebody HAS written a driver for the same hardware (You won't be able to run it in a sketch, however the code will be a useful reference for how to use the WDT hardware).

Well, i tried to write function like the code you gave me... and i am still with 0 values all the time... maybe it's my board or I do'nt know...
Thanks anyway !

Sorry, not sure if I can help you much more. If you need the watchdog timer, I recommend using something like Zephyr which has a driver for the watchdog timer. Currently, we don't have an Arduino library for it.

Check out the Curie ODK, Edge, IoT & 5G Development. It will allow you to build both Arduino sketches & Zephyr applicatiosnfor your board.