Kogna RS485 and I2C

Moderators: TomKerekes, dynomotion

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Kogna RS485 and I2C

Post by jtremel » Mon Feb 05, 2024 12:25 pm

Hi Tom,

RS485 Question
In the Kogna's Hardware/Connector Descriptions manual page it says:
See the BufferedRS485Master.c and BufferedRS485 Slave Echo.c for an example of how 2 Kogna's might communicate over RS485.
Where can I find these example programs? I don't see them in the typical "KmotionX.X.X\C Programs" folder.

I2C Question

Do you have any examples (or hints) for using Kogna's hardware i2C?

User avatar
TomKerekes
Posts: 2676
Joined: Mon Dec 04, 2017 1:49 am

Re: Kogna RS485 and I2C

Post by TomKerekes » Mon Feb 05, 2024 10:51 pm

Hi Jim,
RS485 Question
In the Kogna's Hardware/Connector Descriptions manual page it says:
See the BufferedRS485Master.c and BufferedRS485 Slave Echo.c for an example of how 2 Kogna's might communicate over RS485.
Where can I find these example programs? I don't see them in the typical "KmotionX.X.X\C Programs" folder.
They are included in Version 5.2.3 in:
C:\KMotion5.3.2\C Programs\RS232

I've also attached them.


I2C Question

Do you have any examples (or hints) for using Kogna's hardware i2C?
No we don't currently have any. On one hand the I2C on the TMS320C6748 is very flexible and configurable, but on the other hand it has a maximum rate of 400Kbits/s and doesn't have any fifo so needs to be serviced every word.

The Processor Peripheral Reference manual can be found here. Chapter 21 is on the I2C.

I think the EDMA can be used to service it so no interrupts would be required. We'd rather not use interrupts as that can cause many timing issues and such.

If you tell us what you are trying to do. Bit rate? Master? Slave? Word size? Do words need to be contiguous? Amount of data to send? Receive? We might be able to come up with an example.

I've attached an example from the TI Starterware Kit that sends data using EDMA to blink some sort of LED. But many changes would be required to run in the KMotion environment instead of the TI environment. We have existing routines to configure the Kogna IO pins so that wouldn't need to be handled.
Attachments
i2cEdma.c
(13.15 KiB) Downloaded 197 times
BufferedRS485Master.c
(1.13 KiB) Downloaded 194 times
BufferedRS485 Slave Echo.c
(1.13 KiB) Downloaded 192 times
Regards,

Tom Kerekes
Dynomotion, Inc.

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Re: Kogna RS485 and I2C

Post by jtremel » Tue Feb 06, 2024 12:21 am

Thanks Tom!

I have a machine I am currently developing and I am getting ready to integrate a few mass flow controllers into the system.

The MFC's can be interfaced with either RS485 or i2C communications.

While I may end up settling on RS485, I have been VERY interested in building out my knowledge/codebase to be able to take advantage of the SPI & I2C hardware peripherals (and hopefully driven through DMA) on the Kogna. This is something I use regularly on other embedded platforms (i.e. STM32) and I have a lot of value for building that capability out for my use on Kogna as well.

I already have many existing Kflop applications where I bit-bang SPI transmission though software - but would have liked to use the hardware.

For reference, here is the i2C interface for the MFC's.
https://sensirion.com/media/documents/3 ... nce1.1.pdf

I am not really concerned with high-bandwidth communications with these MFC's... just implementing the ability to update the setpoint every once in a while and continuous polling the current flowrate at something like 10 Hz.

Thanks,
Jim

User avatar
TomKerekes
Posts: 2676
Joined: Mon Dec 04, 2017 1:49 am

Re: Kogna RS485 and I2C

Post by TomKerekes » Fri Feb 23, 2024 6:34 am

Here is an example for Kogna as Master to Transmit and Receive to a 3rd party PCF8575 I2C 16 bit GPIO Expander module. Here is the data sheet for the PCF8575 IC used in the module. Only connections to JP12 are +3.3V, GND, SCL, SDA. SCL and SDA should have 1KOhm pull up resistors to 3.3V. Example Blinks LED on Output P4. Example reads pins and verifies output P4 toggles properly. Transmission rate is maximum at 400KHz.

Code: Select all

// Kogna I2C Master Transmit/Receive Example 

#include "KMotionDef.h"
#include "Kogna_I2c_Lib\Kogna_I2C.c"

#define I2C_SLAVE_ADDR       (0x20u)	/* I2C address of PCF8575 expander  */

// PCF8575 I2C Quasi-bidirectional 16-bit IO Expander
// IO pins have weak pullups.  Setting Output low drives
// low as an output as open collector output.  Setting Output 
// high allows to be driven low externally as an input.
//
// Tested with Adafruit PCF8575 I2C 16 GPIO Expander Breakout
// https://learn.adafruit.com/adafruit-pcf8575


int main(void)
{
	unsigned char WriteBuff[] = { 0xff, 0xff };  // all bits high = Inputs
	unsigned char ReadBuff[] = { 0, 0 };

//	HWREG(SOC_I2C_0_REGS + I2C_ICEMDR) = 2;	// set to ignore NACKs

	SetupI2C(400000, I2C_SLAVE_ADDR);  // set bitrate and Slave Address

	for (;;)
	{
		WriteBuff[0] ^= (1<<4);  // Toggle bit 4 low/high to blink LED connected to Output 4

		//Transmit - Outputs
		I2C_Transmit(WriteBuff, sizeof(WriteBuff));	// Transmit as Master

		while (I2CMasterBusBusy(SOC_I2C_0_REGS) != 0) ;	// wait till no longer busy

		//Receive - Inputs
		I2C_Receive(ReadBuff, sizeof(ReadBuff));  // receive as Master
		
		while (I2CMasterBusBusy(SOC_I2C_0_REGS) != 0);	// wait till no longer busy
		
		// if no inputs low read should match wwrite
		if (ReadBuff[0] != WriteBuff[0] || ReadBuff[1] != WriteBuff[1])
		{
			printf("Outputs LSB %02X MSB %02X Inputs LSB %02X MSB %02X\n", 
				WriteBuff[0], WriteBuff[1], ReadBuff[0], ReadBuff[1]);
			break;
		}
		
		Delay_sec(0.25);  // delay so blink visible
	}
}



Note a Library folder named Kogna_I2C_LIB (attached as Zip file) must exist in the same folder as the example program which contains a number of support functions for programming the DSP's I2C registers and also for EDMA control to allow Hardware Direct Memory Access.
Attachments
Test I2C PCF8575 16 IOExpander.c
(1.56 KiB) Downloaded 193 times
I2C_Hardware.zip
(1.83 MiB) Downloaded 190 times
Regards,

Tom Kerekes
Dynomotion, Inc.

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Re: Kogna RS485 and I2C

Post by jtremel » Fri Feb 23, 2024 3:11 pm

Tom,

I can't seem to find the I2C Library folder in the download links.

The I2C_Hardware.zip just gives me a pdf datasheet to the IO expander.

Thanks,
Jim

User avatar
TomKerekes
Posts: 2676
Joined: Mon Dec 04, 2017 1:49 am

Re: Kogna RS485 and I2C

Post by TomKerekes » Fri Feb 23, 2024 3:36 pm

Oops sorry Jim. Here it is.
Attachments
Kogna_I2C_LIB.zip
(44.04 KiB) Downloaded 194 times
Regards,

Tom Kerekes
Dynomotion, Inc.

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Re: Kogna RS485 and I2C

Post by jtremel » Fri Feb 23, 2024 7:30 pm

Awesome!

Thank you for putting this example together!

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Re: Kogna RS485 and I2C

Post by jtremel » Sun Mar 03, 2024 3:12 pm

Tom,

Based off your example I2C program, I have been working on a demo to use the hardware SPI with and without EDMA.

My demo is working well - with the exception when my transmit and receive arrays are defined outside of my main() routine.

My example code is below.
  • I have MISO and MOSI jumped together on JP12
  • The DMA transfers using LocalTxBuff / LocalRxBuff defined in main() ARE reliable.
  • The DMA transfers using TxBuff_global / RxBuff_global are NOT reliable.
  • The DMA transfers using the gather_buffer[] are reliable.
I wish I could post a screen capture of the console window here, but I don't think I have permissions to add attachments.
Basically, when transferring with the Local and Gather buffers, the Rx Buffer always gets filled with a copy of the contents of the Tx Buffer.
When using the _global buffers, however, this is very hit and miss.
-Sometimes the Rx buffer gets filled.
-Sometimes it partially gets filled.
-Sometimes it doesn't get filled with anything.

Code: Select all

#include "KMotionDef.h"

// includes for the TI DSP register definitions and driver functions
#include "TI_SOC_Lib\hw_types.h"
#include "TI_SOC_Lib\soc_C6748.h"
#include "TI_SOC_Lib\Kogna_edma.c"

// TI SPI Register Definitions
#define EDMA_BASE SOC_EDMA30CC_0_REGS
#define SPI_BASE_ADDR SOC_SPI_1_REGS

#define SPIGCR0 0x0
#define SPIGCR1 0x4
#define SPIINT0 0x8
#define SPIFLG 0x10
#define SPIPC0 0x14
#define SPIPC1 0x18 
#define SPIDAT0 0x38
#define SPIDAT1 0x3C
#define SPIBUF 0x40
#define SPIEMU 0x44
#define SPIDELAY 0x48
#define SPIFMT0 0x50

// local function prototypes
void Init_SPI_Hardware();
void Print_SPI_Registers();
void SendSpiChar(unsigned char char2tx);		
void SPI_Txfer(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes);
void SPI_Txfer_DMA(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes);
void EdmaConfigTxSpi(unsigned char *Addr, int nBytes);
void EdmaConfigRxSPI(unsigned char *Addr, int nBytes);
void fill_buffs(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes);
void print_buffs(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes);

// number of bytes we want to test with
#define NUM_TEST_BYTES 32
	
// The buffers declared here doesn't work reliably with DMA and I don't understand why yet.
unsigned char TxBuff_global[NUM_TEST_BYTES];
unsigned char RxBuff_global[NUM_TEST_BYTES];

int main(void)
{
	int i;

    //The buffers declared here work reliably with DMA.
	unsigned char LocalTxBuff[NUM_TEST_BYTES];
	unsigned char LocalRxBuff[NUM_TEST_BYTES];

	// set pins 4 and 5 of group of 6 as I2C
	SPI_SetMode(0, 0);			// Set SPI mode as SPI or GPIO, 1=GPIO 0=SPI 2=I2C
	SPI_SetMode(1, 0);			// Set SPI mode as SPI or GPIO, 1=GPIO 0=SPI 2=I2C
	SPI_SetMode(3, 0);			// Set SPI mode as SPI or GPIO, 1=GPIO 0=SPI 2=I2C

	// Set up the DSP Registers for the SPI Hardware
	Init_SPI_Hardware();

    printf("SPI/DMA Test with LOCAL Buffer...\n");
    fill_buffs(LocalTxBuff, LocalRxBuff, NUM_TEST_BYTES);
    SPI_Txfer_DMA(LocalTxBuff, LocalRxBuff, NUM_TEST_BYTES);
    print_buffs(LocalTxBuff, LocalRxBuff, NUM_TEST_BYTES);

    printf("SPI/DMA Test with GLOBAL Buffer...\n");
    fill_buffs(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);
    SPI_Txfer_DMA(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);
    print_buffs(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);

    printf("SPI/DMA Test with GATHER Buffer...\n");
    fill_buffs(&gather_buffer[0], &gather_buffer[NUM_TEST_BYTES], NUM_TEST_BYTES);
    SPI_Txfer_DMA(&gather_buffer[0],  &gather_buffer[NUM_TEST_BYTES], NUM_TEST_BYTES);
    print_buffs(&gather_buffer[0],  &gather_buffer[NUM_TEST_BYTES], NUM_TEST_BYTES);

	// delay a bit
	Delay_sec(0.15);
	printf("Testing Non DMA SPI Transfers...\n");
    fill_buffs(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);
    SPI_Txfer(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);
    print_buffs(TxBuff_global, RxBuff_global, NUM_TEST_BYTES);
}

/* fill_buffs
*------------------------------------------------------------------------------------------
* fills the tx_buff with ascending numbers and initializes the Rx buffer elements to 0xFF
*------------------------------------------------------------------------------------------*/
void fill_buffs(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes)
{
    int i;
    
    //initialize the buffers
    for(i=0; i<nBytes; i++)
	{
		tx_buff[i] = i;
		rx_buff[i] = 0xFF;
	}
}

/* SPI_Txfer
*------------------------------------------------------------------------------------------
* Will transfer nBytes over the SPI hardware (without dma).  the bytes in tx_buffer will be sent out
* MOSI and the bytes read in from MISO will fill the rx_buff  
*------------------------------------------------------------------------------------------*/
void SPI_Txfer(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes)
{
	// disable the DMA servicing for the SPI data requests by setting the SPIINT0.DMAREQEN to 1.
    HWREG(SPI_BASE_ADDR + SPIINT0) &= (0xFFFFFFFF & 0<<16);
	
	int i=0;
	for(i=0; i<nBytes; i++)
	{
		SendSpiChar(tx_buff[i]);								// Tx a character
		while( (HWREG(SPI_BASE_ADDR + SPIFLG) & 1<<8)==0);		// wait for transaction to complete
        rx_buff[i]=HWREG(SPI_BASE_ADDR + SPIBUF);               // Read in the character from the Rx buffer
	}
}

/* SPI_Txfer_DMA
*------------------------------------------------------------------------------------------
* Will transfer nBytes over the SPI hardware using dma.  The bytes in tx_buffer will be sent out
* MOSI and the bytes read in from MISO will fill the rx_buff  
*------------------------------------------------------------------------------------------*/
void SPI_Txfer_DMA(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes)
{
    // pointer to transfer paramter set the the SPI Rx DMA. 
    EDMA3CCPaRAMEntry *p2RxPaRAM;

	EdmaConfigTxSpi(tx_buff, nBytes);
    EdmaConfigRxSPI(rx_buff, nBytes);
    
    // get the pointer to the EDMA transfer paramaters for the SPI1_RX.
	p2RxPaRAM = (EDMA3CCPaRAMEntry *)(EDMA_BASE + EDMA3CC_OPT(EDMA3_CHA_SPI1_RX));

    // print out our DMA Transfer Counts before enabling
	printf("SPI Rx DMA Source[0x%x] Dest[0x%x] ", p2RxPaRAM->srcAddr, p2RxPaRAM->destAddr);
	printf("Counts: A[%d] B[%d] C[%d]\n", p2RxPaRAM->aCnt, p2RxPaRAM->bCnt, p2RxPaRAM->cCnt);

    // enable the DMA servicing for the SPI data requests by setting the SPIINT0.DMAREQEN to 1.
    HWREG(SPI_BASE_ADDR + SPIINT0) |= 1<<16;

    // wait for transfer to complete
	while (p2RxPaRAM->cCnt){/* just wait */}

    // disable the DMA servicing for the SPI data requests by setting the SPIINT0.DMAREQEN to 0.
    HWREG(SPI_BASE_ADDR + SPIINT0) &= (0xFFFFFFFF & 0<<16);
}


/* print_buffs
*------------------------------------------------------------------------------------------
* helper routing to print out the Tx and Rx buffers to the console
*------------------------------------------------------------------------------------------*/
void print_buffs(unsigned char *tx_buff, unsigned char *rx_buff, int nBytes)
{
    int i;
    for(i=0; i<nBytes; i++)
	{
        if(i%16==0 && i!=0) printf("\n");
		printf("%02x[%02x] ", tx_buff[i], rx_buff[i]);
	}
    printf("\n\n");
}


/* SendSpiChar
*------------------------------------------------------------------------------------------
* writes a character to the the SPI Transmit Data Register 0(SPIDAT0)
* IF the SPI is enabled, this will shift the bits out MOSI while shifting bits in from MISO
*------------------------------------------------------------------------------------------*/
void SendSpiChar(unsigned char char2tx)
{
	HWREG(SPI_BASE_ADDR + SPIDAT0) = char2tx; //test
}


/* InitializeSPI
*------------------------------------------------------------------------------------------
* Sets up the DSP hardware registers for the SPI1 periph.
* the procedure follows the listing in the TMS320C6748 Technical Ref Manual
*------------------------------------------------------------------------------------------*/
void Init_SPI_Hardware()
{
	// RESET SPI
	HWREG(SPI_BASE_ADDR + SPIGCR0) = 0;
	HWREG(SPI_BASE_ADDR + SPIGCR0) = 1;
	
	//printf("SPI Reset!\n"); Print_SPI_Registers(); printf("\n\n");

	// Config for Master Mode
	HWREG(SPI_BASE_ADDR + SPIGCR1) = 3;

	// Set to 3 pin mode (enable pin control functions for MOSI, MISO, CLK)
	HWREG(SPI_BASE_ADDR + SPIPC0) = 1<<11 | 1<<10 | 1<<9;

	// Data format Register Selection - Tell CPU which format register we want to use
	HWREG(SPI_BASE_ADDR + SPIDAT1) = 0<<24;

	// Data format Register Setting
	HWREG(SPI_BASE_ADDR + SPIFMT0) = 0
		| 0<<20		/* shift direciton	| 0=MSB Firts, 1=LSB First*/
		| 0<<17		/* clock polarity 	| 0=idle low, 1=idle high*/
		| 0<<16		/* clock phase		| 0= first data bit transmitted with first clock edge, 1st tx bit output before clock edge */
		| 20<<8		/* prescaler		| 2-255 => [ SPI clock frequency = SPI module clock/(PRESCALE + 1) ] */		
		| 8<<0;		/* character length	| 2-16, number of data bits */	

	//Configure Delays for Master (SPIDELAY)
	HWREG(SPI_BASE_ADDR + SPIDELAY) = 0;

	// Selection the error interrupt notifications (SPIINT0) and (SPILVL) could be done here. 
	
	// enable the SPI 
	HWREG(SPI_BASE_ADDR + SPIGCR1) |= 1<<24;

	//printf("SPI Configured!\n"); Print_SPI_Registers(); printf("\n\n");
}

/* Print_SPI_Registers
*------------------------------------------------------------------------------------------
* helper routine to print out the SPI hardware registers for debugging
*------------------------------------------------------------------------------------------*/
void Print_SPI_Registers()
{
	printf("Config Reg => %x\n", HWREG(SPI_BASE_ADDR + SPIGCR1));
	printf("SPIPC0 => %x\n", HWREG(SPI_BASE_ADDR + SPIPC0));
	printf("SPIDAT1 => %x\n", HWREG(SPI_BASE_ADDR + SPIDAT1));
	printf("SPIFMT0 => %x\n", HWREG(SPI_BASE_ADDR + SPIFMT0));
	printf("FLAGS => %x\n", HWREG(SPI_BASE_ADDR + SPIFLG));
	printf("RX Buffer => %x\n", HWREG(SPI_BASE_ADDR + SPIBUF));
}

void EdmaConfigTxSpi(unsigned char *Addr, int nBytes)
{
    volatile unsigned int evtQ = 0;	// highest priority queue
	EDMA3CCPaRAMEntry paramSet;

	/* Enabling the PSC for EDMA3CC_0. */
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

	/* Enabling the PSC for EDMA3TC_0. */
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

	/* Intialize the Edma */
	EDMA3Init(EDMA_BASE, evtQ);
	/* Request DMA Channel and TCC */
	EDMA3RequestChannel(EDMA_BASE, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_TX, EDMA3_CHA_SPI1_TX, evtQ);

	// Enable the transfer
	EDMA3EnableTransfer(EDMA_BASE, EDMA3_CHA_SPI1_TX, EDMA3_TRIG_MODE_EVENT);


	paramSet.srcAddr = Addr;
	paramSet.destAddr = (SPI_BASE_ADDR + SPIDAT0);

	/*
	 ** SPI generates event whenever TX is empty.  We set SPI length to 1 byte and there is no fifo.
	 ** Hence per event one bytes needs to be transfered. Thus EDMA is configured in ASYNC mode
	 ** with acount = 1, bcount = total_numbytes, ccount = 1.  BSRC index should be 1 since memory pointer needs to incremented one after every byte 
	 ** transfer by EDMA. BDST index should be zero since the destination address is in constant adrressing mode(hardware register).
	 */
	paramSet.srcBIdx = 0x01;
	paramSet.srcCIdx = 0x00;
	paramSet.destBIdx = 0x00;
	paramSet.destCIdx = 0x00;
	paramSet.aCnt = 0x01;
	paramSet.bCnt = nBytes;          
	paramSet.cCnt = 0x01;
	paramSet.bCntReload = 0x00;
	paramSet.linkAddr = 0xffff;
	paramSet.opt = 0;

	/* Program the TCC */
	paramSet.opt |= ((EDMA3_CHA_SPI1_TX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);

	/* configure PaRAM Set */
	EDMA3SetPaRAM(EDMA_BASE, EDMA3_CHA_SPI1_TX, &paramSet);
}

/*
** Configures Edma to receive nBytes bytes from the SPI1 
*/
static void EdmaConfigRxSPI(unsigned char *Addr, int nBytes)
{
	volatile unsigned int evtQ = 0;	// highest priority queue
	EDMA3CCPaRAMEntry paramSet;

	/* Enabling the PSC for EDMA3CC_0. */
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

	/* Enabling the PSC for EDMA3TC_0. */
	PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

	/* Intialize the Edma */
	EDMA3Init(EDMA_BASE, evtQ);
	/* Request DMA Channel and TCC */
	EDMA3RequestChannel(EDMA_BASE, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_RX, EDMA3_CHA_SPI1_RX, evtQ);

	// Enable the transfer
	EDMA3EnableTransfer(EDMA_BASE, EDMA3_CHA_SPI1_RX, EDMA3_TRIG_MODE_EVENT);

	paramSet.srcAddr = (SPI_BASE_ADDR + SPIBUF);
	paramSet.destAddr = Addr;

	/*
	 ** SPI generates one EDMA event whenever XXXX is empty.  There is space for only one byte of data in SPIBUF.  There is no fifo.  
     ** Hence per event, one bytes needs to be transfered. Thus EDMA is configured in ASYNC mode with acount = 1, bcount = total_numbytes, ccount = 1.  
     ** BSRC index should be 1 since memory pointer needs to incremented one after every byte transfer by EDMA.
     ** BDST index should be zero since the destination address is in constant adrressing mode(hardware register).
	 */
	paramSet.srcBIdx = 0x00;
	paramSet.srcCIdx = 0x00;
	paramSet.destBIdx = 0x01;
	paramSet.destCIdx = 0x00;
	paramSet.aCnt = 0x01;
	paramSet.bCnt = nBytes;
	paramSet.cCnt = 0x01;
	paramSet.bCntReload = 0x00;
	paramSet.linkAddr = 0xffff;
	paramSet.opt = 0;

	/* Program the TCC */
	paramSet.opt |= ((EDMA3_CHA_SPI1_RX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);

	/* configure PaRAM Set */
	EDMA3SetPaRAM(EDMA_BASE, EDMA3_CHA_SPI1_RX, &paramSet);
}



User avatar
TomKerekes
Posts: 2676
Joined: Mon Dec 04, 2017 1:49 am

Re: Kogna RS485 and I2C

Post by TomKerekes » Sun Mar 03, 2024 7:33 pm

Hi Jim,

When I try to compile the code I get:

In file included from C:\KMotionSrcKogna\C Programs\Kogna\SPI\SPI Loopback.c:6:
C:\KMotionSrcKogna\C Programs\Kogna\SPI/TI_SOC_Lib\Kogna_edma.c:82: 'EDMA3CC_EMCR' undeclared

Did you modify the header files to solve this? I'd like to have exactly the same code for testing. It would be good to have the same include files for SPI and I2C without changes.
Regards,

Tom Kerekes
Dynomotion, Inc.

jtremel
Posts: 39
Joined: Fri Jun 21, 2019 10:55 pm

Re: Kogna RS485 and I2C

Post by jtremel » Sun Mar 03, 2024 8:47 pm

Hey Tom,

EDMA3CC_EMCR should be defined in hw_edma3cc.h

I didn't modify any of the files from the original Kogna_I2C_LIB folder with the exception of:
  • In my SPI dev project I renamed the folder to "TI_SOC_Lib"
  • Kogna_edma.c - I modified the folder names in the #include statements to be "TI_SOC_Lib\"


Here is a zip file of my source code folder.
Attachments
Kogna SPI2.zip
SPI Source Code Folder
(72.72 KiB) Downloaded 187 times

Post Reply