Part Number: AM5728
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!
