unable to read data from interrupt triggered UART

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

unable to read data from interrupt triggered UART

1,198 Views
stdcerr
Contributor IV

Hi,

 

I'm attempt to read data from an RFID reader (agrident ASR550) connected to UART4 (on  MK64FN1M0VLL12)
but am unable to, i.e. my callback does not  seem to get triggered at all as I expect it to when a tag is scanned. I have the following functions:

uart_status_t uart4_init(void) {
	uart_status_t rv;
	uart_state_t RFIDState;
	uart_user_config_t RFIDUserConfig = {0};
	RFIDUserConfig.baudRate = 9600;
	RFIDUserConfig.stopBitCount = 1;
	RFIDUserConfig.bitCountPerChar = 8;

	rv = UART_DRV_Init(RFID_UART_INSTANCE,&RFIDState,&RFIDUserConfig);
	if (rv != kStatus_UART_Success) {
		PRINTF("\r\n ERROR in uart4_init(), rv %d\r\n",rv);
		return rv;
	}
	UART_DRV_InstallRxCallback(RFID_UART_INSTANCE,rfid_callback,RFID_Buff,NULL,true);
	return rv;
}
/******************************************************************************/

void rfid_callback(uint32_t instance,
        		   void* RFIDState) {
	int i = 0;

   	for (i=0; i<BUF_SIZE; i++) {
   		PRINTF(" [%d] 0x%x\r\n", i, (uint8_t)RFID_Buff[i]);
   	}
}

RFID_Buff is defined as follows:

uint8_t RFID_Buff[BUF_SIZE]={0};

and the macros are defined as:

#define RFID_UART_INSTANCE 4
#define RFID_UART_BASEADDR UART4
#define BUF_SIZE 20

Does my code look right or can anybody point out a problem?I'm also troubleshooting the hardware and will add any findings I may make here.

Thanks!

0 Kudos
11 Replies

1,195 Views
mjbcswitzerland
Specialist V

Hi

The K64F's UART4 Rx can be multiplexed to either PTE25 or PTC14.
Are you sure that this has been set correctly?

 

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements

 

0 Kudos

1,191 Views
stdcerr
Contributor IV

> The K64F's UART4 Rx can be multiplexed to either PTE25 or PTC14.
> Are you sure that this has been set correctly?

Good point, I'm not sure actually. I want to set it to PTC14, how do I do so?

0 Kudos

1,185 Views
mjbcswitzerland
Specialist V

Hi

I don't know how it is done in your environment. In the uTasker environment is is does with
#if defined UART4_ON_C
_CONFIG_PERIPHERAL(C, 14, (PC_14_UART4_RX | UART_PULL_UPS)); // UART4_RX on PC14 (alt. function 3)
#else
_CONFIG_PERIPHERAL(E, 25, (PE_25_UART4_RX | UART_PULL_UPS)); // UART4_RX on PE25 (alt. function 3)
#endif

which melds down (more or less) to
PORTC_PCR14 = 3;

in the case of PTC14. Therefore search the project for where  PORTC_PCR14 or PORTE_PC25 are being accessed.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements

 

0 Kudos

1,183 Views
stdcerr
Contributor IV

Thanks, I'm looking into it. I'm using KSDK 1.3.0

0 Kudos

1,176 Views
stdcerr
Contributor IV

I've found the following for KSDK that needs to be invoked at init (untested):

case UART4_IDX:                      /* UART4 */
      /* Affects PORTC_PCR14 register */
      PORT_HAL_SetMuxMode(PORTC,14u,kPortMuxAlt3);
      /* Affects PORTC_PCR15 register */
      PORT_HAL_SetMuxMode(PORTC,15u,kPortMuxAlt3);
      break;

 

0 Kudos

1,153 Views
mjbcswitzerland
Specialist V

Hi

The setup looks OK in that case.

I have also attached a K64 application that sets up the same ports for UART4 and will echo receptions or allow a command line interface to be used. The K64 runs from 48MHz HIRC so will work on any HW. You can verify HW and check the register setups in the debugger as comparison.

The SDK that you are using looks very old and I don't think NXP supports it any more and I expect they will suggest you moving to the new SDK.

If you haven't already invested a lot of work specific to the environment you can also look at the uTasker project (it is available as open source, free commercial or supported commercial) which gives a similar UART interface - see below, and has been used sucessfully in many K64 industrial application with lots of intensive UART interface s(4G modems, Modbus, RF interface etc.)

 

TTYTABLE tInterfaceParameters; // table for passing information to driver
tInterfaceParameters.Channel = UART_4; // set UART channel for serial use
tInterfaceParameters.ucSpeed = SERIAL_BAUD_9600; // baud rate
tInterfaceParameters.Config = (CHAR_8 | NO_PARITY | ONE_STOP | USE_XON_OFF | CHAR_MODE);
tInterfaceParameters.Rx_tx_sizes.RxQueueSize = RX_BUFFER_SIZE; // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = TX_BUFFER_SIZE; // output buffer size
tInterfaceParameters.Task_to_wake = OWN_TASK; // wake self when messages have been received
tInterfaceParameters.ucDMAConfig = UART_TX_DMA; // activate DMA on transmission

SerialID = fnOpen(TYPE_TTY, FOR_I_O, ptrInterfaceParameters); // open or change the channel with defined configurations (initially inactive)
fnDriver(SerialID, (TX_ON | RX_ON), 0); // enable rx and tx

fnWrite(SerialID, "Hello, World!", 14); // send test output

// Task_to_wake is worken on each reception and reads the data with
length = fnRead(SerialID, buffer, sizeof(buffer);

 

It allows the K64 to be simulated in real-time so you can connect UART devices to the PC and develop, test, debug without needing the HW, which dramatically improves development efficiency (its simulator makes setup errors immediately visible and will warn of anthing that it finds being used out of specification, etc. If you need a different Kinetis or an i.MX RT upgrade applications developed with it will also run there with virtually no porting effort (apart from defining the new pin mapping).

mjbcswitzerland_0-1602161689518.png

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements

 

0 Kudos

1,140 Views
stdcerr
Contributor IV

I have done significant work in the current environment so I don't think switching to using uTasker would make sense at this point. I have verified that RS-232 signals are delivered to PTC14 on my board but I still don't see my interrupt callback being invoked.

As for the UART setup, I changed the initialization around a bit and now have:

setup the GPIOS:

      /* Affects PORTC_PCR14 register */
      PORT_HAL_SetMuxMode(PORTC,14u,kPortMuxAlt3);
      /* Affects PORTC_PCR15 register */
      PORT_HAL_SetMuxMode(PORTC,15u,kPortMuxAlt3);

then initialize the UART to 9600,n,8,1 & set the rx callback:

uart_status_t RFID_UART_Init(void) {
	uart_status_t rv;
	uart_state_t UartState;
	uart_user_config_t RFIDUartConfig = {0};
	RFIDUartConfig.baudRate = 9600;
	RFIDUartConfig.parityMode = kUartParityDisabled;
	RFIDUartConfig.stopBitCount = kUartOneStopBit;
	RFIDUartConfig.bitCountPerChar = kUart8BitsPerChar;


	rv = UART_DRV_Init(RFID_UART_INSTANCE,&UartState,&RFIDUartConfig);
	if (rv != kStatus_UART_Success) {
		PRINTF("\r\n ERROR in uart4_init(), rv %d\r\n",rv);
		return rv;
	}
	UART_DRV_InstallRxCallback(RFID_UART_INSTANCE,rfid_callback,RFID_Buff,NULL,true);
	return rv;
}

The rfid_callback() looks like:

void rfid_callback(uint32_t instance,
        		   void* RFIDState) {
	memcpy(RFIDState,&RFIDdata,sizeof(uart_state_t));

}

 where RFIDdata is a global defined like: uart_state_t RFIDdata={0};

but again, my problem is that rfid_callback() isn't getting invoked. What Am I missing?

Maybe enabling the UART4 Rx interrupt?

0 Kudos

1,133 Views
stdcerr
Contributor IV

I have also attempted something like this now:

do{
			        status = UART_DRV_GetReceiveStatus(RFID_UART_INSTANCE, NULL);
					PRINTF("Current status: 0x%x\r\n",status);
					RFIDdata.rxSize = 0;
					// Call received API
					UART_DRV_ReceiveData(RFID_UART_INSTANCE, &rxChar, 1u);
					// Wait until we receive a character
				    while (kStatus_UART_RxBusy == UART_DRV_GetReceiveStatus(RFID_UART_INSTANCE, NULL)){}
				    // Echo received character
				    PRINTF("\r\nrxChar 0x%x\r\n",rxChar);

			}while(1);

but I still get nothing even with Current status 0x0

0 Kudos

1,121 Views
mjbcswitzerland
Specialist V

Hi

These are the registers after configuring UART4 for interrupt operation. Please compare with the values you have by viewing them in the debugger.

mjbcswitzerland_1-1602273186812.png

 

 

mjbcswitzerland_0-1602273154465.png

 

Regards

Mark

 

1,103 Views
stdcerr
Contributor IV

Thank you for this! I'm working on testing the UART functionality in isolation of any other parts of the project to be able to get to the bottom of what's happening exactly! I do appreciate your help and availability for further communications, which I might come back to!

Thank you in advance!

0 Kudos

1,135 Views
mjbcswitzerland
Specialist V

Hi

I would expect the UART API to handle interrupt configurations.
However use the debugger to see whether the UART's status register is showing the rx interrupt flag set or not when you send a charcater. Check the interrupt enable mask in the UART and then check the NVIC to see whether it is not being left masked for UART4.

You should also see received bytes in the UART Rx Data register - if not check the UART clock. The K64 has 6 standard UARTs - UARTs 0 and 1 are clocked from the system clock an UARTs 2..4 from the bus clock.

Also you should find the binary I attached runs and give a reference of register settings to compare with.

From experience with many project conversions the uTasker project usually speeds developments by around a factor of 5, which means that if you are around >= 80% through a development it probably won't help the final deadline but anything before it probably will. I can take a look at your present project if required to estimate the porting time - a one day turnaround port can usually be offered to commercial users [https://www.utasker.com/services.html] but you can also use it free in its open source form.

Note also that I can offer a remote desktop debugging session (up to 40 minutes free) to identify your particular issue. I have worked on around 300 Kinetis product developments during the last 8 years and so I don't think that more than a few minutes would be needed to identify the issue.

Regards

Mark

0 Kudos