Skip to content

Commit

Permalink
more debug and fixups
Browse files Browse the repository at this point in the history
Signed-off-by: Jukka Laitinen <[email protected]>
  • Loading branch information
jlaitine committed Oct 7, 2024
1 parent b6d6f44 commit d97355d
Showing 1 changed file with 50 additions and 52 deletions.
102 changes: 50 additions & 52 deletions arch/arm64/src/imx9/imx9_flexcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@
#define CANRCVWORK HPWORK

#define RXMBCOUNT CONFIG_IMX9_FLEXCAN_RXMB
#define TXMBCOUNT (CONFIG_IMX9_FLEXCAN_TXMB + 1)
#define TOTALMBCOUNT RXMBCOUNT + TXMBCOUNT
#define TXMBCOUNT CONFIG_IMX9_FLEXCAN_TXMB
#define TOTALMBCOUNT (RXMBCOUNT + TXMBCOUNT)

#define IFLAG1_RX ((1 << RXMBCOUNT)-1)
#define IFLAG1_TX (((1 << TXMBCOUNT)-2) << RXMBCOUNT)
#define IFLAG1_TX (((1 << TXMBCOUNT)-1) << RXMBCOUNT)

#define CAN_FIFO_NE (1 << 5)
#define CAN_FIFO_OV (1 << 6)
Expand Down Expand Up @@ -160,8 +160,8 @@ struct imx9_driver_s

const uintptr_t base; /* FLEXCAN base address */
const int irq; /* irq number */
const uint32_t clk_freq; /* Peripheral clock frequency */
const bool canfd_capable;
uint32_t clk_freq; /* Peripheral clock frequency */
bool bifup; /* true:ifup false:ifdown */
#ifdef TX_TIMEOUT_WQ
struct wdog_s txtimeout[TXMBCOUNT]; /* TX timeout timer */
Expand Down Expand Up @@ -479,7 +479,7 @@ static void imx9_reset(struct imx9_driver_s *priv);

static bool imx9_txringfull(struct imx9_driver_s *priv)
{
uint32_t mbi = RXMBCOUNT + 1;
uint32_t mbi = RXMBCOUNT;
struct mb_s *mb;

while (mbi < TOTALMBCOUNT)
Expand Down Expand Up @@ -536,6 +536,8 @@ static int imx9_transmit(struct imx9_driver_s *priv)

struct mb_s *mb = flexcan_get_mb(priv, mbi);
_alert("mbi %d cs %x\n", mbi, CAN_MB_CS_CODE(mb->cs));
_alert("MCR: %x\n", getreg32(priv->base + IMX9_CAN_MCR_OFFSET));
_alert("ESR1: %x\n", getreg32(priv->base + IMX9_CAN_ESR1_OFFSET));
if (CAN_MB_CS_CODE(mb->cs) != CAN_TXMB_DATAORREMOTE)
{
break;
Expand Down Expand Up @@ -641,17 +643,21 @@ static int imx9_transmit(struct imx9_driver_s *priv)
}

cs |= (frame->can_id & CAN_RTR_FLAG) ? CAN_MB_CS_RTR : 0;
cs |= ((g_len_to_can_dlc[frame->len] << CAN_MB_CS_DLC_SHIFT) &
cs |= ((((uint32_t)g_len_to_can_dlc[frame->len]) << CAN_MB_CS_DLC_SHIFT) &
CAN_MB_CS_DLC_MASK);

frame_data_word = (uint32_t *)&frame->data[0];
for (i = 0; i < (frame->len + 4 - 1) / 4; i++)
{
mb->data[i] = __builtin_bswap32(frame_data_word[i]);
}


_alert("payload sz %d\n", frame->len);
_alert("GO: %x\n", (cs | (CAN_TXMB_DATAORREMOTE << CAN_MB_CS_CODE_SHIFT)));
}
#endif

mb->cs = (cs | (CAN_TXMB_DATAORREMOTE << CAN_MB_CS_CODE_SHIFT)); /* Go */

/* Enable interrupt */
Expand Down Expand Up @@ -939,7 +945,7 @@ static void imx9_txdone(struct imx9_driver_s *priv)

/* Process TX completions */

mbi = RXMBCOUNT + 1;
mbi = RXMBCOUNT;
mb_bit = 1 << mbi;
#ifdef TX_TIMEOUT_WQ
txmb = 0;
Expand Down Expand Up @@ -1066,29 +1072,21 @@ static int imx9_flexcan_interrupt(int irq, void *context,
void *arg)
{
struct imx9_driver_s *priv = (struct imx9_driver_s *)arg;

_alert("IRQ\n");
if (irq == priv->irq)
{
uint32_t flags;
flags = getreg32(priv->base + IMX9_CAN_IFLAG1_OFFSET);
flags &= IFLAG1_RX;

if (flags)
if (flags & IFLAG1_RX)
{
modifyreg32(priv->base + IMX9_CAN_IMASK1_OFFSET, IFLAG1_RX, 0);
work_queue(CANRCVWORK, &priv->rcvwork,
imx9_flexcan_interrupt_work, priv, 0);
}

flags = getreg32(priv->base + IMX9_CAN_IFLAG1_OFFSET);
flags &= IFLAG1_TX;

if (flags)
if (flags & IFLAG1_TX)
{
/* Disable further TX MB CAN interrupts. here can be no race
* condition here.
*/

modifyreg32(priv->base + IMX9_CAN_IMASK1_OFFSET, IFLAG1_TX, 0);
work_queue(CANWORK, &priv->irqwork, imx9_txdone_work, priv, 0);
}
Expand Down Expand Up @@ -1516,7 +1514,7 @@ static int imx9_ioctl(struct net_driver_s *dev, int cmd,
#endif /* CONFIG_NETDEV_IOCTL */

/****************************************************************************
* Function: imx9_init_eccram
* Function: imx9_init_mbram
*
* Description:
* Initialize FLEXCAN ECC RAM
Expand All @@ -1531,7 +1529,7 @@ static int imx9_ioctl(struct net_driver_s *dev, int cmd,
*
****************************************************************************/

static int imx9_init_eccram(struct imx9_driver_s *priv)
static int imx9_init_mbram(struct imx9_driver_s *priv)
{
volatile uint32_t *data = (uint32_t *)(priv->base + IMX9_CAN_MB_OFFSET);
const uint32_t *data_end = (uint32_t *)(priv->base + IMX9_CAN_MB_END);
Expand Down Expand Up @@ -1603,8 +1601,6 @@ static int imx9_initialize(struct imx9_driver_s *priv)
{
uint32_t i;

imx9_init_eccram(priv);

/* Enable module */

if (!imx9_setenable(priv->base, true))
Expand All @@ -1625,6 +1621,21 @@ static int imx9_initialize(struct imx9_driver_s *priv)
return ERROR;
}

/* Initialize memory buffers */

imx9_init_mbram(priv);

/* Configure MCR */

modifyreg32(priv->base + IMX9_CAN_MCR_OFFSET, CAN_MCR_MAXMB_MASK,
CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
CAN_MCR_IRMQ | CAN_MCR_AEN |
((TOTALMBCOUNT << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK));

/* Exit supervisor mode */

modifyreg32(priv->base + IMX9_CAN_MCR_OFFSET, CAN_MCR_SUPV, 0);

if (!priv->canfd_capable)
{
modifyreg32(priv->base + IMX9_CAN_CTRL1_OFFSET,
Expand Down Expand Up @@ -1681,6 +1692,12 @@ static int imx9_initialize(struct imx9_driver_s *priv)
CAN_CTRL2_ISOCANFDEN);
}


/* Filtering catchall */

putreg32(0x3fffffff, priv->base + IMX9_CAN_RX14MASK_OFFSET);
putreg32(0x3fffffff, priv->base + IMX9_CAN_RX15MASK_OFFSET);
putreg32(0x3fffffff, priv->base + IMX9_CAN_RXMGMASK_OFFSET);
putreg32(0x0, priv->base + IMX9_CAN_RXFGMASK_OFFSET);

for (i = 0; i < TOTALMBCOUNT; i++)
Expand All @@ -1692,7 +1709,7 @@ static int imx9_initialize(struct imx9_driver_s *priv)
{
struct mb_s *rx = flexcan_get_mb(priv, i);
ninfo("Set MB%" PRIi32 " to receive %p\n", i, rx);
rx->cs = CAN_RXMB_EMPTY << CAN_MB_CS_CODE_SHIFT;
rx->cs = (CAN_RXMB_EMPTY << CAN_MB_CS_CODE_SHIFT) | CAN_MB_CS_IDE;
}

putreg32(IFLAG1_RX, priv->base + IMX9_CAN_IFLAG1_OFFSET);
Expand Down Expand Up @@ -1727,41 +1744,13 @@ static int imx9_initialize(struct imx9_driver_s *priv)

static void imx9_reset(struct imx9_driver_s *priv)
{
uint32_t regval;
uint32_t i;

modifyreg32(priv->base + IMX9_CAN_MCR_OFFSET, 0, CAN_MCR_SOFTRST);

if (!imx9_waitmcr_change(priv->base, CAN_MCR_SOFTRST, false))
{
nerr("Reset failed");
return;
}

modifyreg32(priv->base + IMX9_CAN_MCR_OFFSET, CAN_MCR_SUPV, 0);

imx9_init_eccram(priv);

modifyreg32(priv->base + IMX9_CAN_MCR_OFFSET, 0,
CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
CAN_MCR_IRMQ | CAN_MCR_AEN |
(((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) &
CAN_MCR_MAXMB_MASK));

regval = CAN_CTRL2_RRS | CAN_CTRL2_EACEN;
putreg32(regval, priv->base + IMX9_CAN_CTRL2_OFFSET);

for (i = 0; i < TOTALMBCOUNT; i++)
{
putreg32(0, priv->base + IMX9_CAN_RXIMR_OFFSET(i));
}

/* Filtering catchall */

putreg32(0x3fffffff, priv->base + IMX9_CAN_RX14MASK_OFFSET);
putreg32(0x3fffffff, priv->base + IMX9_CAN_RX15MASK_OFFSET);
putreg32(0x3fffffff, priv->base + IMX9_CAN_RXMGMASK_OFFSET);
putreg32(0x0, priv->base + IMX9_CAN_RXFGMASK_OFFSET);
}

/****************************************************************************
Expand Down Expand Up @@ -1879,6 +1868,15 @@ int imx9_caninitialize(int intf)
return -EAGAIN;
}

if (irq_attach(priv->irq + 1, imx9_flexcan_interrupt, priv))
{
/* We could not attach the ISR to the interrupt */

nerr("ERROR: Failed to attach CAN bus error IRQ\n");
irq_detach(priv->irq);
return -EAGAIN;
}

/* Initialize the driver structure */

priv->dev.d_ifup = imx9_ifup; /* I/F up (new IP address) callback */
Expand Down

0 comments on commit d97355d

Please sign in to comment.