Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Raffaele

Pages: [1] 2
1
utFAT / Reading UART messages of different lengths
« on: May 05, 2021, 06:08:15 PM »
Hi,
I'm trying to read UART messages of any length on a KL03 (does not support DMA).
I use fnRead in my task, and every time a new character is received the task is triggered.
My code is very simple

Code: [Select]
QUEUE_TRANSFER length;
while (   (length = fnRead(SerialPortID, uartMessage, MEDIUM_MESSAGE)) != 0 ){
counter++;
//fnDelayLoop(600);
}

Now, here is the problem, if I do not use that fnDelayLoop, the while is entered for each character, one at a time. So, for a message of n chars, there will be n interrupts to my task and n while loops. If, instead, I use the fnDelayLoop, the while is executed only one time for the whole message (which I prefer). My understanding is that without the delay, the while terminates because the characters are too slow with respect the the execution of the while loop and the uart rx buffer is empty, so the delay allows waiting for the whole message to arrive while still in the loop.

But in this way the delay to to be used depends on the length of the message that I don't know beforehand and it is not constant. And if the delay is not enough for a long messages, then its last part will come with the initial part of the next message.
Is there a better way to do this?

2
µTasker general / Device doesn't retain low power configs
« on: February 23, 2021, 08:56:50 PM »
Hi,

sorry if the title is misleading.
I'm having issues with programming a KL03. The code that I program the device with has a low power task that periodically moves from VLPW to VLPS, and vice versa.
If I:
Program the device -> Power it off -> Power it on again
Or
Power it on -> Program with recompiled code (even the same exact code, just freshly recompiled)
 it stalls at the beginning (but I think neither in VLPW nor in VLPS, because the power consumption is larger than VLPW and lower than VLPS. I measured  the powers for each state).
Instead, if I:
Program the device -> Power it off -> Power it on -> RE-PROGRAM with the same code (not recompiled), then it works properly, and alternates between VLPW and VLPS.

What could it be?
My intuition is that during reprogramming something gets pulled high/low, probably for a certain amount of time necessary for my device to work properly.  And since this doesn't happen with a simple restart, the device/code gets stuck somewhere


3
µTasker general / MCG_Lite Clock mode switching
« on: February 12, 2021, 09:28:23 PM »
Hi,

I'm trying to switch clock mode on the KL03 from within my own task.
The "KL03 Sub-Family Reference Manual" https://www.nxp.com/docs/en/reference-manual/KL03P24M48SF0RM.pdf
on pg. 321 reports how to switch between clk modes.


I took a look at the file kinetis.c and I saw that the following instructions (not in this order) are used:

Code: [Select]
MCG_C2 |= MCG_C2_IRCS;                                               // select fast internal reference clock
MCG_C1 = MCG_C1_CLKS_HIRC;                                           // select HIRC clock source
MCG_C2 &= ~MCG_C2_IRCS;                                              // select slow internal reference clock
MCG_C2 = 1;
MCG_C2 = 0;

I have 2 questions:

1]
If I want to enter LIRC8 and move to LIRC2, passing by HIRC, I just use this set of instructions in this order in my task. Is this correct and enough?

Code: [Select]
//Enter LIRC8
MCG_C2 &= ~MCG_C2_IRCS;                                              // select slow internal reference clock
MCG_C2 = 1;

//Enter HIRC
MCG_C2 |= MCG_C2_IRCS;                                               // select fast internal reference clock
MCG_C1 = MCG_C1_CLKS_HIRC;                                           // select HIRC clock source

//Enter LIRC2
MCG_C2 &= ~MCG_C2_IRCS;                                              // select slow internal reference clock
MCG_C2 = 8;


2] What do I do with the macros in the file app_hw_kinetis.h since I would need both RUN_FROM_HIRC and RUN_FROM_LIRC? I mean, do I need to uncomment both?

Code: [Select]
#define RUN_FROM_HIRC                                                // clock from internal 48MHz RC clock
#define RUN_FROM_LIRC                                                // clock from internal 8MHz/2MHz RC clock
    #if defined RUN_FROM_HIRC
        #define SYSTEM_CLOCK_DIVIDE  2                                   // 1..16
        #define BUS_CLOCK_DIVIDE     2                                   // 1..8 (valid for bus/flash and divisor is after the system clock divider)
    #elif defined RUN_FROM_LIRC
        #define RUN_FROM_LIRC_2M                                         // select 2MHz rather than 8MHz
        #define SLOW_CLOCK_DIVIDE    2                                   // optionally divide the slow clock output (1, 2, 4, 8, 16, 32, 64 or 128)
        #define SYSTEM_CLOCK_DIVIDE  1                                   // 1..16
        #define BUS_CLOCK_DIVIDE     1                                   // 1..8 (valid for bus/flash and divisor is after the system clock divider)

Thank you

4
µTasker general / conditionally execute interrupt handler function
« on: January 16, 2021, 06:33:25 AM »
Hi,

I'm using the KL03. I have two independent parallel tasks.
One task changes from one state to another periodically. This is the simplified code:

Code: [Select]
case 1:
nState  = 2;
uTaskerMonoTimer('B', (DELAY_LIMIT) (2 * SEC), UTASKER_ACTIVATE);
break;

case 2:
nState = 1;
uTaskerMonoTimer('B', (DELAY_LIMIT) (3 * SEC), UTASKER_ACTIVATE);
break;


The other task configures a port interrupt (on a GPIO pin) and its handling function fn_rx_interrupt_handler is called whenever the interrupt is triggered externally on that pin.

Code: [Select]
static void fn_rx_interrupt_handler(void) {
fn_b();
}

All this works.

Now, I want that fn_b() is executed ONLY if nSTate==1, so I simply do:

Code: [Select]
static void fn_rx_interrupt_handler(void) {
if (nState == 1) {
fn_b();
}
}
But this doesn't work. The task ignores the interrupt. Even if I try to put the control of nState in fn_b, it still doesn't work. It is as if that if statement in the interrupt disables it

Any idea why and what I can do?

5
µTasker general / UART Tx stalls and incomplete messages
« on: December 23, 2020, 07:02:58 PM »
Hi,

I'm working with a KL_03 using the UART to transmit (no DMA, just base mode) and I am having issues. Is there anything I need to pay attention to in terms of UART Tx buffer size, baud rate, and transmission duration? Is there a correlation between them, such as a certain buffer size only works with some specific baud rates?

I have a task that runs periodically every few seconds, at each run I print UART messages of different lengths using fnDebugMsg():
1) some messages are cut or not printed completely
2) after some printouts the code stalls (I'm debugging it to understand if the problem is somewhere else or related to UART)
3) I use fnDelayLoop(x) after UART messages, but it looks like that it sometimes helps write more complete messages, other times it doesn't. I don't know how to choose the value for x



Thank you

6
µTasker general / Change Timer/Channel associated pin for PWM
« on: November 11, 2020, 11:11:53 PM »
Hi,

I'm trying to generate two different PWMs on a KL03. One uses pwm_reference = (_TIMER_1 | 0); and the associated pin is PTA0. This works.
For the other one I want to use PTA12. However, the KL family manual reports  TPM1_CH0 for both PTA0 and PTA12.

To change this, in the file kinetis_PWM.h I changed _CONFIG_PERIPHERAL(B, 11,(PORT_MUX_ALT2 | PORT_SRE_FAST | PORT_DSE_HIGH)); to _CONFIG_PERIPHERAL(A, 12,(PORT_MUX_ALT2 | PORT_SRE_FAST | PORT_DSE_HIGH));
so that the pwm_reference for PTA12  is now  TPM0_CH0 instead of  TPM1_CH0.

I set up 2 different PWMs on PTA0 and PTA12, but both pins generate the same PWM of  TPM1_CH0 A0. In other words, I am not able to modify the PWM on PTA12. Is there anything else I need to change in the code?

7
µTasker general / UART, SPI and PWM in low power modes
« on: October 15, 2020, 09:31:12 PM »
Hi,
I'm writing a task for the KL03 that generates a PWM and sometimes uses SPI master and UART. I need it to be as low power as possible.

1)
According to the KL manual* (page 84) in VLPS, UART and TPM can work as far as their clock sources are enabled (table pg 81). How do I enable them in utasker?

2) I want to use the function fnSetLowPowerMode but for it to be functional, the task    {"lowPower",  fnLowPower,   NO_QUEUE,  0, 0, UTASKER_GO} in taskConfig.c has to be enabled. Does it make sense?

3)
I'm using the function fnSetLowPowerMode(VLPS_MODE); to enter VLPS mode, but when I do it UART stops working, probably because of question (1). SPI also stops working but that's expected because SPI master works up to VLPW at 500kbps (table pg 84) correct?

4)
Is it possible to switch from VLPS_MODE to VLPW_MODE, for example, when I need to use the spi, and then back to VLPS?


* https://www.nxp.com/docs/en/reference-manual/KL03P24M48SF0RM.pdf

8
µTasker general / Incorrect PWM frequency
« on: October 01, 2020, 05:46:19 AM »
Hi,

simple question, I'm trying to generate a PWM signals with 50% duty cycle, between 650kHz-750kHz on a KL03.

For example at 600kHz I use

Code: [Select]
    pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_1);
    pwm_setup.pwm_frequency = PWM_TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(650000), 1);
    pwm_setup.pwm_value = _PWM_PERCENT(50, pwm_setup.pwm_frequency);

PWM_SYS_CLK should be 8MHz. But I don't get the right value, my PWM is at 990kHz.
What am I doing wrong?

9
µTasker general / Sleep-receive state machine with timeouts
« on: September 13, 2020, 05:53:13 PM »
Hi,
I'm trying to implement a state machine but I am having issues with the task.
I simply have two states: SLEEP and RX and I want to do

1) stay in SLEEP for T1 sec
2) after T1 sec go to RX
3) stay in RX for T2 sec (if something is received, aka interrupt on a pin, process data)

All these things work independently in my code. But I don't know how to properly activate the task


Code: [Select]
int const SLEEP = 1;
int const RX = 2;

extern void stateMachineTask(TTASKTABLE *ptrTaskTable){
switch (iState) {

case 0 :
steupIinterruptHandler();

iState = 1;
uTaskerMonoTimer('C', (DELAY_LIMIT) (0.5 * SEC), UTASKER_ACTIVATE);
break;

case SLEEP :

deactivate_data_processing();

// do sleep operations here

iState = RX;
uTaskerMonoTimer('C', (DELAY_LIMIT) (T1 * SEC), UTASKER_ACTIVATE);
break;

case RX :
activate_data_processing();

//if received interrupt, process data

iState = SLEEP;
uTaskerMonoTimer('C', (DELAY_LIMIT) (T2 * SEC), UTASKER_ACTIVATE);
break;
}
}

My major problem is that the interrupt is not triggered (it normally works). If I can suspend/resume the whole task that's fine too, but I don't know how to do it

10
µTasker general / SPI configs increases current absorption of 70mA
« on: August 18, 2020, 09:13:48 PM »
Hi,
I'm programming a KL03. My code has PWM, UART and a couple of interrupts. It is up and running and it only absorbs 2-3mA.
When I configure the SPI the absorbed current jumps to 75-80mA. Is this normal? Can I somehow reduce it? Even configuring and deconfiguring the SPI interface would be an acceptable solution since I use it rarely.

This is my config, just regular SPI:

Code: [Select]
#define INITIALISE_SPI_SD_INTERFACE()  POWER_UP(4, SIM_SCGC4_SPI0); \
                        _CONFIG_PERIPHERAL(B, 0, PB_0_SPI0_SCK); \
_CONFIG_PERIPHERAL(A, 7, (PA_7_SPI0_MOSI | PORT_SRE_FAST | PORT_DSE_HIGH)); \
_CONFIG_PERIPHERAL(A, 6, (PA_6_SPI0_MISO | PORT_PS_UP_ENABLE)); \
_CONFIG_DRIVE_PORT_OUTPUT_VALUE(A, SPI_CS1, SPI_CS1, (PORT_SRE_FAST | PORT_DSE_HIGH));\
_CONFIG_DRIVE_PORT_OUTPUT_VALUE(A, SPI_CS2, SPI_CS2, (PORT_SRE_FAST | PORT_DSE_HIGH));\
SPI0_C1 = (SPI_C1_CPHA | SPI_C1_CPOL | SPI_C1_MSTR | SPI_C1_SPE); \
SPI0_BR = (SPI_BR_SPPR_PRE_4 | SPI_BR_SPR_DIV_2); \
(void)SPI0_S; (void)SPI0_D;

I tried POWER_UP(4, SIM_SCGC4_SPI0) and POWER_DOWN(4, SIM_SCGC4_SPI0) and that reduces the current to half. How can I deconfigure the other peripherals _CONFIG_PERIPHERAL and _CONFIG_DRIVE_PORT_OUTPUT_VALUE?

11
µTasker general / UART Tx bytes are shifted
« on: August 16, 2020, 03:04:09 AM »
Hi,

I'm having a small issue with UART on a KL03.
By default the UART clock is LPUART_IRC48M                                       

Code: [Select]
        #define LPUART_IRC48M                                            // if the 48MHz clock is available clock the LPUART from it
      //#define LPUART_OSCERCLK                                          // clock the LPUART from the external clock
      //#define LPUART_MCGIRCLK                                          // clock the LPUART from MCGIRCLK (IRC8M/FCRDIV/LIRC_DIV2) - default if others are not defined

Now if I comment LPUART_IRC48M and uncomment #define LPUART_MCGIRCLK it happens that when I transmit, my characters are wrong. Basically, the transmitted bytes are shifted of 0x60
So for example, if I want to transit "A" (0x41), instead of an "A", UART transmits 0xA1 (which is 0x41 + 0x60).

What am I doing wrong? How can I fix this?
Thank you

12
µTasker general / output the system CLK
« on: June 19, 2020, 11:08:26 PM »
Hi,
simple question, how can I output the system clock on the KL03? Also I am assuming that I can only use PTA4 and PTA12 since they are the only two that have an ALT function called CLKOUT, right?

13
Hi,
I setup a UART interface on a kinetis KL03 to Tx an Rx. The device can both receive and transmit. But I'm having a problem. Every time I receive a message, the device also sends back a sequence of 0x17 or 0x11 with some 0x19?
These seem to be control commands but I am not sure why, and if there is any way to remove them

Thank you

14
µTasker general / Momentarily disable interrupt routine
« on: May 17, 2020, 04:23:02 PM »
Hi,
is it possible to momentarily disable an interrupt? Or its handler?

I mean, I configure the interrupt

Code: [Select]
INTERRUPT_SETUP interrupt_setup;
interrupt_setup.int_type       = PORT_INTERRUPT;                    // identifier to configure port interrupt
interrupt_setup.int_handler    = fn_my_interrupt_handler;           // handling function
interrupt_setup.int_priority   = PRIORITY_PORT_B_INT;              // interrupt priority level
interrupt_setup.int_port       = PORTB;                  // the port that the interrupt input is on
interrupt_setup.int_port_bits  = INTERRUPT_PIN;           // the IRQ input connected
interrupt_setup.int_port_sense = (IRQ_RISING_EDGE | PULLUP_ON);  // interrupt is to be falling edge sensitive
fnConfigureInterrupt((void *)&interrupt_setup);

Then at some point I want to suspend handling the interrupt and then activate it again. Something like this:


Code: [Select]
suspend_interrupt();
function();
reactivate_interrupt();

Is it possible?

15
µTasker general / Are there UART received interrupts?
« on: May 12, 2020, 03:37:05 PM »
Hi,

Is there something like a received UART interrupt in uTasker or how does it work? I mean I define my Serial configuration like this:

Code: [Select]
TTYTABLE tInterfaceParameters; // table for passing information to driver
QUEUE_HANDLE SerialPortID; // UART handle to be obtained during open
tInterfaceParameters.Channel = 0; // set UART channel for serial use
tInterfaceParameters.ucSpeed = SERIAL_BAUD_19200; // baud rate 19�200
tInterfaceParameters.Rx_tx_sizes.RxQueueSize = 256; // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 512; // output buffer size
tInterfaceParameters.Task_to_wake = TASK_MY_UART; // wake task on rx
#ifdef SUPPORT_FLOW_HIGH_LOW
tInterfaceParameters.ucFlowHighWater = 80; // set the flow control high in %
tInterfaceParameters.ucFlowLowWater  = 20; // set the flow control low in %
#endif
tInterfaceParameters.Config = (CHAR_8 + NO_PARITY + ONE_STOP + USE_XON_OFF + CHAR_MODE);
if ((SerialPortID = fnOpen( TYPE_TTY, FOR_I_O, &tInterfaceParameters)) != 0) {
// open the channel with defined configurations (initially inactive)
fnDriver(SerialPortID, ( TX_ON | RX_ON ), 0); // enable rx and tx
}
DebugHandle = SerialPortID;

now, when I receive a new message my task should be waken up, but how does it actually happen? Is there an interrupt that makes uTasker execute my task or does it happen just because UART senses something? I'm trying to get to that point because I can transmit over UART but my task is not executed upon reception

Thank you

Pages: [1] 2