Simulator Hello World in MPLAB IDE: Put stimulus on pins using Pin/Register Actions - simulator

I've written a hello-world program for an 8-bit PIC microcontroller and want to run it on the MPLAB X IDE simulator.
I want to create a stimulus on its pins, and have the result appear in the microcontroller's register which corresponds to the input pins, (having set a watch on the register).
What I have achieved so far: The program seems to run fine on the simulator, and I can create an "asynchronous" stimulus, i.e. fire a change of the stimulus (such as applying a logic 0 on an input pin) when I click the "fire" button. This changes the contents of the PORTC register. However I cannot get "synchronous" stimulus to work (e.g. automatically toggling the stimulus logic value applied to an input pin). PORTC does not change. (However the simulator output suggests the stimulus is being applied).
There are examples written by Microchip for the MPLAB 8.x IDE simulator which I have tried to apply to MPLAB X (v2.0) but I cannot get working. To establish what I'm doing wrong, (or if I'm encountering a bug), perhaps someone could help in one of the following ways:
Give an example of a working hello-world
Spot any errors in the process I've followed (see below for my steps)
Follow my steps to see if the problem can be replicated
This is what I have tried:
Summary of steps followed:
Create project and set target device to be "PIC16F77"
Add source file main.c
Set the simulator as the hardware tool, and XC8 as the C compiler
Add a variable watch on the PORTC special function register
Configure an asynchronous stimulus
Configure a synchronous stimulus
Build project
Run in debug mode
Single-step the program and look for changes of the PORTC register.
Create a new project in the MPLAB X IDE with a source file main.c, and selecting "PIC16F77" as the target device:
#include <htc.h>
__CONFIG(
FOSC_HS
& WDTE_OFF
& PWRTE_OFF
& BOREN_OFF
);
void main(void) {
// set tristate port directions: 1=input, 0=output
TRISC = 0b11111111;
while (1);
}
I add a variable watch on the PORTC SFR register:
Configure an asynchronous stimulus in the window/tab Stimulus > Asynchronous :
Configure a synchronous stimulus in the window/tab Stimulus > Pin/Register Actions
Then finally:
I build the project, run in debug mode, pause, and single-step through the program.
When I click on the "fire" button of the asynchronous stimulus and then click the Step-Over button, the value in PORTC register changes as expected.
But when running through the program, the synchronous stimulus never seems to have any effect. It appears that the stimuli are repeatedly being applied, but there is no effect on the value in the PORTC register. It can be seen in the window/tab: Output > Stimulus that the stimulus is being applied:
I don't understand why the asynchronous stimulus works fine, but the synchronous stimulus appears to be applied but is not producing the desired effect.

The problem was that the synchronous PORTC stimuli set via the Pin/Register Actions tab were not changing the value on the input pins. Instead, it sets the value of PORTC register and thus only affects the value in the register when TRISC is set to OUTPUT within the C code, i.e. 0b00000000.
I have yet to work out how to set the pins' values when they are inputs, synchronously.

Related

Device-side enqueue causes CL_OUT_OF_RESOURCES

I have a program utilizing OpenCL 2.0 because I want to take advantage of device-side enqueue. I have a test program that performs the following tasks on the host side:
Allocates 16 kilobytes of floating point memory on the device and zeros it out.
Builds the OpenCL program below, and creates a kernel of masterKernel()
Sets the first argument of masterKernel() (heap) to the allocated memory in step 1
Enqueues that masterKernel() via clEnqueueNDRangeKernel() with a work_dim of 1 and a global work size of 1. (So it only runs once, with get_global_id(0) always being zero)
Reads the memory back into the host and displays it.
Here is the OpenCL code:
//This function was stripped down to nothing for testing purposes.
kernel void childKernel(global float* heap)
{
}
//Enqueues the child kernel.
kernel void masterKernel(global float* heap)
{
ndrange_t ndRange = ndrange_1D(16); //Arbitrary, could be any number.
if(get_global_id(0) == 0)
{
enqueue_kernel(get_default_queue(), 0, ndRange,
^{ childKernel(heap); });
}
}
The program builds successfully. However, when I try to run masterKernel(), The call to enqueue_kernel() here causes the host side call to clEnqueueNDRangeKernel() to fail with an error code of CL_OUT_OF_RESOURCES. OpenCL's documentation says enqueue_kernel() should return CL_SUCCESS or CL_ENQUEUE_FAILURE depending on if the block enqueues successfully or not. It does not say that clEnqueueNDRangeKernel() itself should fail. Here are some other things I've tried:
Commenting out the call to enqueue_kernel() causes the program to succeed.
Adding a line that sets heap[0] to any number causes the host-side program to reflect that change. So I know that it's not a problem with how I'm feeding the arguments in
Modifying the if statement so that it reads something impossible like if(get_global_id(0) == 6000) still causes the error. This tells me that the error is not caused by enqueue_kernel() executing (I verified get_global_size(0) == 1), but merely that it exists in the program at all.
Modifying the if statement to if(0) does make the error not happen.
Making it so childKernel() actually does something does not make the error go away.
I am not really sure what to try next. I know my device supports OpenCL 2.0. My device is an AMD Radeon R9 380 graphics card. I do not have access to any other OpenCL 2.0 capable hardware to test it on.
I ended up figuring this one out. This issue happened because I did not create a device-side queue (one with the flags of CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT).

PIC18F OSCCON Register Requied if I define OSC = INTIO1?

New to microcontrollers, need to wrap my head around this basic thing:
So, I'm trying to program a PIC18F4520, I know I can set an external clock using #define OSC = HS and connecting the crystal between the required pins. I have a doubt that is, if I define the Oscillator requirement as #define OSC = INTIO2
BaSically this:
#include <xc.h>
#pragma config OSC=INTIO1 //HERE!!
#pragma config PWRT=OFF
#pragma config WDT=OFF
#pragma config DEBUG=OFF, LVP=OFF
void delay(int);
void main(void) {
return;
}
Do I need to set the OSCCON register and the CONFIG1 register?
I could recommend you to go inside the MPLAB X Software to Window -> PIC Memory Views -> Configuration Bits. This will show you a new window to help you to configure properly your fuses, in this case the PIC18F4520 will show you the CONFIG1H register, inside is the OSC field, you can choose the oscillator right here with the available options.
However, you still need to tell what oscillator are you using to the microcontroller. To do this part you will need to read the PIC18F4520 Datasheet and look for the Table of Contents page (Page 6), you will see the Oscillator Configurations (Page 23 according with the Datasheet), there you have all the information required to setup the External Oscillator that you want to use properly. I hope this could solve your issues.

Low-power PWM library: PWM doesnt stop if low_power_pwm_stop is called from handler. Is this a bug?

I am using SDK 12.0.0.
I am working with low_power_pwm_init() to initialise the pwm and I have passed a handler while initialising. I want to stop the pwm from the handler hence I am calling low_power_pwm_stop() from the handler. I observe that the pwm doesnt stop.
I tried to investigate the reason for this and found that pwm_timeout_handler() in low_power_pwm.c is restarting the pwm. Below is the snippet that is suspect.
if (p_pwm_instance->pwm_state == NRF_DRV_STATE_INITIALIZED)
{
p_pwm_instance->pwm_state = NRF_DRV_STATE_POWERED_ON;
err_code = app_timer_start(*p_pwm_instance->p_timer_id, p_pwm_instance->timeout_ticks, p_pwm_instance);
APP_ERROR_CHECK(err_code);
}
In low_power_pwm_stop(), p_pwm_instance->pwm_state is assigned NRF_DRV_STATE_INITIALIZED and in the above snippet the timer is started if the driver state is NRF_DRV_STATE_INITIALIZED, causing the pwm to be ON again.
Is this a bug?
I had posted this question on nordic's devzone and below is the answer that I got from a nordic employee.
Hi,
I can see that this will be the case and will report it internally.
You can set a flag in the event handler and call the stop routine in
main.
Ole
So I guess this is a bug in nordic's sdk code.

jruby add RXTX serial listener

I need to read a message incoming every 500ms from the serial COMx or /dev/ttySx interfaces under jruby.
What I am trying to do is to translate this example to Ruby in order to retrigger the listener.
I am learning jRuby so I started to activate the serial port and then I am trying to add the listener in this way:
java_import('gnu.io.RXTXPort') { 'JSerialPort' }
begin
sp=JSerialPort.new('COM6')
sp.setSerialPortParams(38400,8,1,0)
rescue
puts #error_message="myerror #{$!}"
ensure
sp.close
end
It seems to work.
Next is to add the listener which in the above example is described at this line
serialPort.addEventListener(new SerialReader(in));
This is described here where an addListener method is described.
I tried many ways to call the addListener methods, but I don't manage to call by jRuby such an inner method.
I tried sp::RXTXPort::addEventListener with no luck. Long research googling set me to stall (and some frustration).
Any help welcome.

How to create a pseudo-tty for reading output and writing to input

I am using fork() and execvp() to spawn a process that must believe it is connected to an interactive terminal for it to function properly.
Once spawned, I want to capture all the output from the process, as well as be able to send input to the process.
I suspect psuedo-ttys may help here. Does anyone have a snippet on how to do this?
You want to call forkpty(). From the man page:
#include <pty.h> /* for openpty and forkpty */
pid_t forkpty(int *amaster, char *name, struct termios *termp, struct
winsize *winp);
Link with -lutil.
The forkpty() function combines openpty(), fork(), and login_tty() to
create a new process operating in a pseudo-terminal. The file descrip‐
tor of the master side of the pseudo-terminal is returned in amaster,
and the filename of the slave in name if it is not NULL. The termp and
winp parameters, if not NULL, will determine the terminal attributes
and window size of the slave side of the pseudo-terminal.
Your parent process talks to the child by reading and writing from the file descriptor that forkpty stores in "amaster" - this is called the master pseudo-terminal device. The child just talks to stdin and stdout, which are connected to the slave pseudo-terminal device.
Expect was already mentioned for use via Tcl, but it can also be used without Tcl by treating it as a C library and calling the API documented here
There's a package called "expect" which you should use. It uses a scripting language called tcl (pronounced tickle).
https://core.tcl-lang.org/expect/

Resources