This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi ,
I am in 5728 through ipc and dsp communication, and let dsp control gpio.
I am using a custom board.
My code is based on TI's ex02_messageq and gpio_led_blink.
The following is my core code,
/* * ======== Server.c ======== * */ /* this define must precede inclusion of any xdc header file */ #define Registry_CURDESC Test__Desc #define MODULE_NAME "Server" /* xdctools header files */ #include <xdc/std.h> #include <xdc/runtime/Assert.h> #include <xdc/runtime/Diags.h> #include <xdc/runtime/Log.h> #include <xdc/runtime/Registry.h> //C include #include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdint.h> /* package header files */ #include <ti/ipc/MessageQ.h> #include <ti/ipc/MultiProc.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> /* local header files */ #include "../shared/AppCommon.h" /* module header file */ #include "Server.h" /* GPIO header file */ #include <ti/drv/gpio/GPIO.h> #include <ti/drv/gpio/soc/GPIO_v1.h> #include <ti/csl/src/ip/gpio/V1/gpio_v2.h> #include <ti/drv/gpio/src/GPIO_osal.h> #define NUM_PORTS (8u) #define NUM_PINS_PER_PORT (32u) #define CALLBACK_INDEX_NOT_CONFIGURED (0xFFu) /* Macro to extract GPIO pin number from the gpio pin configuration */ #define GPIO_GET_PIN_NUM(gpioConfig) (((gpioConfig) & GPIO_CFG_PIN_NUM_MASK) >> \ GPIO_CFG_PIN_NUM_SHIFT) /* Macro to extract GPIO port number from the gpio pin configuration */ #define GPIO_GET_PORT_NUM(gpioConfig) (((gpioConfig) & GPIO_CFG_PORT_NUM_MASK) \ >> GPIO_CFG_PORT_NUM_SHIFT) /** \brief Mask for all pins of single gpio port */ #define GPIO_PIN_MASK_ALL (0xFFFFFFFFU) typedef struct GPIO_PortCallbackInfo_s { /* The port's 8 corresponding user defined pinId indices */ uint8_t pinIndex[NUM_PINS_PER_PORT]; } GPIO_PortCallbackInfo; /* Table of callbacks per port. */ GPIO_PortCallbackInfo gpioCallbackInfo[NUM_PORTS]; uint32_t portHwiCreatedBitMask = 0; volatile bool initCalled = false; void GPIO_setConfig_v1(uint32_t index, GPIO_PinConfig pinConfig); void GPIO_v1_hwiFxn(uintptr_t portIdx); inline uint32_t getPinNumber(uint32_t x); void GPIO_init_v1(void); void GPIO_write_v1(uint32_t index, uint32_t value); uint8_t getGpioIntIndex(GPIO_PinConfig pinConfig); /* module structure */ typedef struct { UInt16 hostProcId; // host processor id MessageQ_Handle slaveQue; // created locally } Server_Module; App_Msg * msg; /* private data */ Registry_Desc Registry_CURDESC; static Server_Module Module; char *liatest = "0000"; /* * ======== Server_init ======== */ Void Server_init(Void) { Registry_Result result; /* register with xdc.runtime to get a diags mask */ result = Registry_addModule(&Registry_CURDESC, MODULE_NAME); Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL); /* initialize module object state */ Module.hostProcId = MultiProc_getId("HOST"); GPIO_init_v1(); } /* * ======== Server_create ======== */ Int Server_create() { Int status = 0; MessageQ_Params msgqParams; char msgqName[32]; /* enable some log events */ Diags_setMask(MODULE_NAME"+EXF"); /* create local message queue (inbound messages) */ MessageQ_Params_init(&msgqParams); sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(MultiProc_self())); Module.slaveQue = MessageQ_create(msgqName, &msgqParams); if (Module.slaveQue == NULL) { status = -1; goto leave; } Log_print0(Diags_INFO,"Server_create: server is ready"); leave: Log_print1(Diags_EXIT, "<-- Server_create: %d", (IArg)status); return (status); } /* * ======== Server_exec ======== */ Int Server_exec() { Int status; Bool running = TRUE; MessageQ_QueueId queId; int flg = 0; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:"); while (running) { /* wait for inbound message */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } #if 1 if(strstr(msg->lia,"host") == NULL) flg = 1; else flg = 2; #endif if (msg->cmd == App_CMD_SHUTDOWN) { running = FALSE; } /* process the message */ Log_print1(Diags_INFO, "Server_exec: processed cmd=0x%x", msg->cmd); /* send message back */ queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */ if(flg == 1 ){ GPIO_write_v1((AM572X_LED0),GPIO_PIN_VAL_HIGH); MessageQ_put(queId, (MessageQ_Msg)msg); } if(flg == 2){ GPIO_write_v1((AM572X_LED0),GPIO_PIN_VAL_LOW); MessageQ_put(queId, (MessageQ_Msg)msg); } Task_sleep(1000); } /* while (running) */ leave: Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status); return(status); } /* * ======== Server_delete ======== */ Int Server_delete() { Int status; Log_print0(Diags_ENTRY, "--> Server_delete:"); /* delete the video message queue */ status = MessageQ_delete(&Module.slaveQue); if (status < 0) { goto leave; } leave: if (status < 0) { Log_error1("Server_finish: error=0x%x", (IArg)status); } /* disable log events */ Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status); Diags_setMask(MODULE_NAME"-EXF"); return(status); } /* * ======== Server_exit ======== */ Void Server_exit(Void) { /* * Note that there isn't a Registry_removeModule() yet: * https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448 * * ... but this is where we'd call it. */ } void GPIO_init_v1(void) { uint32_t i, j; uint32_t portCfgDone[NUM_PORTS] = {0U,0U,0U,0U,0U,0U,0U,0U}; uint32_t pinConfig; GPIO_v1_HwAttrs *hwAttrs = NULL; uint32_t portNum; portHwiCreatedBitMask = 0; /* Initialize all entries with 'not configured' key */ for (i = 0; i < NUM_PORTS; i++) { for (j = 0; j < NUM_PINS_PER_PORT; j++) { gpioCallbackInfo[i].pinIndex[j] = CALLBACK_INDEX_NOT_CONFIGURED; } } /* Perform GPIO Reset and Module Enable only once for port */ for(i = 0; i < GPIO_v1_config.numberOfPinConfigs; i++) { pinConfig = GPIO_v1_config.pinConfigs[i]; if ((pinConfig & GPIO_DO_NOT_CONFIG) != GPIO_DO_NOT_CONFIG) { portNum = GPIO_GET_PORT_NUM(pinConfig); if ((portNum > 0U) && (portNum <= NUM_PORTS)) { hwAttrs = (GPIO_v1_HwAttrs *)&GPIO_v1_hwAttrs[(portNum - 1U)]; if(portCfgDone[portNum - 1] == 0U) { portCfgDone[portNum - 1] = 1U; /* Enable the GPIO module. */ GPIOModuleEnable(hwAttrs->baseAddr); } } } } /* Configure pins and create Hwis per static array content */ for (i = 0; i < GPIO_v1_config.numberOfPinConfigs; i++) { if ((GPIO_v1_config.pinConfigs[i] & GPIO_DO_NOT_CONFIG) != GPIO_DO_NOT_CONFIG) { GPIO_setConfig_v1(i, GPIO_v1_config.pinConfigs[i]); } } initCalled = (bool)true; } void GPIO_write_v1(uint32_t index, uint32_t value) { uint32_t key; GPIO_v1_HwAttrs *hwAttrs = NULL; uint32_t pinConfig; uint32_t pinNum; uint32_t portNum; /* Input parameter validation */ GPIO_osalAssert(!((((bool)true) == initCalled) && (index < GPIO_v1_config.numberOfPinConfigs))); pinConfig = GPIO_v1_config.pinConfigs[index]; portNum = GPIO_GET_PORT_NUM(pinConfig); pinNum = GPIO_GET_PIN_NUM(pinConfig); if (((portNum > 0U) && (portNum <= NUM_PORTS)) && (pinNum < NUM_PINS_PER_PORT)) { hwAttrs = (GPIO_v1_HwAttrs *)&GPIO_v1_hwAttrs[(portNum - 1U)]; key = GPIO_osalHardwareIntDisable(); /* Clear output from pinConfig */ GPIO_v1_config.pinConfigs[index] &= ~GPIO_CFG_OUT_HIGH; if (value) { /* Set the pinConfig output bit to high */ GPIO_v1_config.pinConfigs[index] |= GPIO_CFG_OUT_HIGH; } GPIOPinWrite(hwAttrs->baseAddr, pinNum, value); GPIO_osalHardwareIntRestore(key); } sprintf(msg->lia, " *** led%d %x %x 0x%x ",index,portNum,pinNum,hwAttrs->baseAddr); } void GPIO_setConfig_v1(uint32_t index, GPIO_PinConfig pinConfig) { uint32_t key; void * hwiHandle; uint32_t gpioBase; uint32_t evtType; uint32_t intrEvtType; /* there exist a variable with same name "gpioDirection". changed to solve the misra warning "MISRA.CT.UNIQUE.ID"*/ uint8_t gpio_Direction; uint8_t gpioPin; uint8_t gpioPortIntIdx; uint32_t gpioPortIntBitMask; GPIO_PinConfig gpioPinConfig; OsalRegisterIntrParams_t interruptRegParams; uint32_t intrLineNum = GPIO_INT_LINE_1; uint32_t pinConfigVal; uint32_t portNum; uint32_t pinNum; GPIO_v1_HwAttrs *hwAttrs = NULL; uint8_t ret_flag = 0U; GPIO_osalAssert(!(index < GPIO_v1_config.numberOfPinConfigs)); pinConfigVal = GPIO_v1_config.pinConfigs[index]; portNum = GPIO_GET_PORT_NUM(pinConfigVal); pinNum = GPIO_GET_PIN_NUM(pinConfigVal); if (((portNum > 0U) && (portNum <= NUM_PORTS)) && (pinNum < NUM_PINS_PER_PORT)) { hwAttrs = (GPIO_v1_HwAttrs *)&GPIO_v1_hwAttrs[(portNum - 1U)]; gpioBase = hwAttrs->baseAddr; gpioPin = (uint8_t)pinNum; if ((pinConfig & GPIO_CFG_IN_INT_ONLY) == 0) { /* Get GPIO configuration settings */ /* Determine settings for GPIO as input or output */ if (pinConfig & GPIO_CFG_INPUT) { gpio_Direction = (uint8_t)GPIO_DIR_INPUT; } else { gpio_Direction = (uint8_t)GPIO_DIR_OUTPUT; } /* Make atomic update */ key = GPIO_osalHardwareIntDisable(); /* Set output value */ if (gpio_Direction == GPIO_DIR_OUTPUT) { GPIOPinWrite(gpioBase, (uint32_t)gpioPin, ((pinConfig & GPIO_CFG_OUT_HIGH) ? 1U : 0U)); } /* Configure the GPIO pin */ GPIODirModeSet(gpioBase, (uint32_t)gpioPin, (uint32_t)gpio_Direction); /* Update pinConfig with the latest GPIO configuration */ gpioPinConfig = GPIO_v1_config.pinConfigs[index]; gpioPinConfig &= ~GPIO_CFG_IO_MASK; gpioPinConfig |= (pinConfig & GPIO_CFG_IO_MASK); GPIO_v1_config.pinConfigs[index] = gpioPinConfig; GPIO_osalHardwareIntRestore(key); } /* Set type of interrupt and then clear it */ if (pinConfig & GPIO_CFG_INT_MASK) { /* Calculate the gpioInterruptVectors index for the GPIO pin */ gpioPortIntIdx = getGpioIntIndex(pinConfigVal); gpioPortIntBitMask = (((uint32_t)1U) << (gpioPortIntIdx - 1u)); /* If Hwi has not already been created, do so */ if ((portHwiCreatedBitMask & gpioPortIntBitMask) == 0) { /* Initialize with defaults */ Osal_RegisterInterrupt_initParams(&interruptRegParams); interruptRegParams.corepacConfig.isrRoutine = (&GPIO_v1_hwiFxn); interruptRegParams.corepacConfig.arg = (uintptr_t)(portNum); interruptRegParams.corepacConfig.priority = GPIO_v1_config.intPriority; interruptRegParams.corepacConfig.name=NULL; interruptRegParams.corepacConfig.corepacEventNum=hwAttrs->line1EventId; /* Event going in to CPU */ interruptRegParams.corepacConfig.intVecNum=hwAttrs->line1IntNum; /* Host Interrupt vector */ /* Register interrupts */ GPIO_osalRegisterInterrupt(&interruptRegParams,&(hwiHandle)); if (hwiHandle == NULL) { /* error constructing the Hwi for GPIO Port */ ret_flag = 1U; } } if(ret_flag == 0u) { key = GPIO_osalHardwareIntDisable(); /* Mark the Hwi as created */ portHwiCreatedBitMask |= gpioPortIntBitMask; /* Map correct interrupt type event based on the flag */ evtType = (pinConfig & GPIO_CFG_INT_MASK) >> GPIO_CFG_INT_LSB; switch(evtType) { case 1U: intrEvtType = GPIO_INT_TYPE_FALL_EDGE; break; case 2U: intrEvtType = GPIO_INT_TYPE_RISE_EDGE; break; case 3U: intrEvtType = GPIO_INT_TYPE_BOTH_EDGE; break; case 4U: intrEvtType = GPIO_INT_TYPE_LEVEL_LOW; break; case 5U: intrEvtType = GPIO_INT_TYPE_LEVEL_HIGH; break; default: /** If event type is none of the above then it will be forced to * FALLING EDGE interrupt event type. */ intrEvtType = GPIO_INT_TYPE_FALL_EDGE; break; } GPIOIntTypeSet(hwAttrs->baseAddr, (uint32_t)gpioPin, intrEvtType); GPIOPinIntClear(hwAttrs->baseAddr, intrLineNum, (uint32_t)gpioPin); /* Update pinConfig with the latest interrupt configuration */ gpioPinConfig = GPIO_v1_config.pinConfigs[index]; gpioPinConfig &= ~(GPIO_CFG_INT_MASK); gpioPinConfig |= (pinConfig & GPIO_CFG_INT_MASK); GPIO_v1_config.pinConfigs[index] = gpioPinConfig; GPIO_osalHardwareIntRestore(key); } } } return; } void GPIO_v1_hwiFxn(uintptr_t portIdx) { uint32_t gpioPins; uint32_t gpioBase; uint32_t gpioIndex; uint32_t bitNum; uint32_t portNo = (uint32_t)portIdx; GPIO_PortCallbackInfo *portCallbackInfo; GPIO_v1_HwAttrs *hwAttrs = (GPIO_v1_HwAttrs *)&GPIO_v1_hwAttrs[portNo - 1U]; uint32_t intrLineNum = GPIO_INT_LINE_1; portCallbackInfo = &gpioCallbackInfo[portNo -1U]; gpioBase = hwAttrs->baseAddr; /* Find out which pins have their interrupt flags set */ gpioPins = GPIORawIntStatus(gpioBase, intrLineNum, GPIO_PIN_MASK_ALL); /* Clear all the set bits at once */ GPIOIntrClearMask(gpioBase, intrLineNum, gpioPins); /* Match each set bit to its corresponding callback function */ while (gpioPins) { /* Gets the lowest order set bit number */ bitNum = getPinNumber(gpioPins); gpioIndex = portCallbackInfo->pinIndex[bitNum]; if (gpioIndex != CALLBACK_INDEX_NOT_CONFIGURED) { GPIO_v1_config.callbacks[gpioIndex](); } gpioPins &= ~(((uint32_t)1U) << bitNum); } } uint32_t getPinNumber(uint32_t x) { uint32_t idx = 0; while((x & 0x1U) == 0) { idx++; x = x>>1; } return idx; } uint8_t getGpioIntIndex(GPIO_PinConfig pinConfig) { return ((uint8_t)GPIO_GET_PORT_NUM(pinConfig)); }
I had a problem while controlling different gpio.
I tested a lot of gpio and found several problems.
1 I can control gpio4_4, 4_7, 7_7, 7_8, but can't control 4_10, 4_11, 7_10 pins with values greater than 10.
2 When I try to control gpio5 (5-2,5-3,5-10...), the following error occurs.
[ 1149.475766] ------------[ cut here ]------------ [ 1149.480422] WARNING: CPU: 1 PID: 27 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x25c/0x36c *** led0 5 10 0x4805b000 #### 0000 [ 1149.489689] 44000000.ocp:L3 Custom Error: MASTER DSP1_MDMA TARGET L4_PER1_P3 (Idle): Data Acces s in User mode during Functional access [ 1149.505131] Modules linked in: bc_example(O) xhci_plat_hcd xhci_hcd pru_rproc pruss_intc usbcore dwc3 pruss udc_core usb_common sha512_generic sha512_arm sha256_gener ic rpmsg_proto sha1_generic sha1_arm_neon sha1_arm md5 cbc xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo rpmsg_rpc bluetooth snd_soc_simple_card snd_soc_simple_card_utils snd_soc_omap_hdmi_audio pvrsrvkm(O) omap_aes_driver ahci_platform libahci_platf orm libahci pruss_soc_bus omap_sham libata omap_wdt scsi_mod ti_vpe ti_sc ti_csc ti_vpdma dwc3_omap rtc_omap extcon_palmas extcon_core r tc_ds1307 rtc_palmas omap_des snd_soc_tlv320aic3x des_generic crypto_engine omap_remoteproc virtio_rpmsg_bus rpmsg_core remoteproc sch_f q_codel uio_module_drv(O) uio gdbserverproxy(O) cryptodev(O) cmemk(O) App_exec: message received, sending message 13 [ 1149.573758] CPU: 1 PID: 27 Comm: irq/23-l3-app-i Tainted: G W O 4.9.28-rt16-g786e64041b #23 [ 1149.573760] Hardware name: Generic DRA74X (Flattened Device Tree) [ 1149.573764] Backtrace: [ 1149.573778] [<c020b2a8>] (dump_backtrace) from [<c020b564>] (show_stack+0x18/0x1c) [ 1149.573783] r7:00000009 r6:60000113 r5:00000000 r4:c1024a40 [ 1149.573793] [<c020b54c>] (show_stack) from [<c04d141c>] (dump_stack+0x8c/0xa0) [ 1149.573801] [<c04d1390>] (dump_stack) from [<c022d880>] (__warn+0xec/0x104) [ 1149.573806] r7:00000009 r6:c0bbb9c4 r5:00000000 r4:ee625e20 [ 1149.573811] [<c022d794>] (__warn) from [<c022d8d8>] (warn_slowpath_fmt+0x40/0x48) [ 1149.573817] r9:00000006 r8:ee604b10 r7:c0bbbcb8 r6:00000000 r5:c0bbb8f0 r4:c0bbb994 [ 1149.573826] [<c022d89c>] (warn_slowpath_fmt) from [<c05013ec>] (l3_interrupt_handler+0x25c/0x36c) [ 1149.573829] r3:ee604980 r2:c0bbb994 [ 1149.573831] r4:80080003 [ 1149.573840] [<c0501190>] (l3_interrupt_handler) from [<c0281c48>] (irq_forced_thread_fn+0x28/0x7c) [ 1149.573846] r10:c0281c20 r9:ee604e80 r8:ee609000 r7:00000001 r6:00000000 r5:ee609000 [ 1149.573848] r4:ee604e80 [ 1149.573854] [<c0281c20>] (irq_forced_thread_fn) from [<c0281fb0>] (irq_thread+0x124/0x1f8) [ 1149.573858] r7:00000001 r6:00000000 r5:ee624000 r4:ee604ea4 [ 1149.573865] [<c0281e8c>] (irq_thread) from [<c024ad18>] (kthread+0x100/0x118) [ 1149.573870] r10:00000000 r9:00000000 r8:c0281e8c r7:ee604e80 r6:ee624000 r5:ee604ec0 [ 1149.573872] r4:00000000 [ 1149.573880] [<c024ac18>] (kthread) from [<c0207c90>] (ret_from_fork+0x14/0x24) [ 1149.573885] r8:00000000 r7:00000000 r6:00000000 r5:c024ac18 r4:ee604ec0 [ 1149.573887] ---[ end trace 000000000000002c ]---
3 When I try to control these gpio 3-29, 4-29, 7-29..., the printed address is incorrect and the value is always changing.
Whether it is 3-29,4-29, the print value is 9514****.
What causes these problems to arise.
Is there a relationship between decimal and hexadecimal conversions?
Or dsp can not control some gpio.
Thanks!
Hi,
I didn't build this example project because I didn't use CCS.
My code is for reference to this example.
This example does not have Makefile, what if I want to compile?
This and dsp can't control part of gpio What is the relationship?
I would like to know that I use dsp operation gpio method is correct? dsp and ARM can control all the gpio?
Thanks!
Hi all,
Can someone help me with my question?
Can the DSP control all GPIOs?
Thanks!
Hi,
DSP can control GPIOs if the pins are multiplexed properly. You may need check if those GPIO pins are configured as GPIO by looking into control module registers. These pins are multiplexed and may have been configured for other purpose.
Regards, Garrett