forked from Imagelibrary/rtems
leon, grcan: consistent indentation
This commit does not contain any change of functionality.
This commit is contained in:
committed by
Daniel Hellstrom
parent
ad203e5887
commit
bc40b4def8
@@ -389,14 +389,14 @@ static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
|
|||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
/* Check that memory has been allocated successfully */
|
/* Check that memory has been allocated successfully */
|
||||||
if ( !pDev->tx || !pDev->rx )
|
if (!pDev->tx || !pDev->rx)
|
||||||
return RTEMS_NO_MEMORY;
|
return RTEMS_NO_MEMORY;
|
||||||
|
|
||||||
/* Configure FIFO configuration register
|
/* Configure FIFO configuration register
|
||||||
* and Setup timing
|
* and Setup timing
|
||||||
*/
|
*/
|
||||||
if ( pDev->config_changed ){
|
if (pDev->config_changed) {
|
||||||
grcan_hw_config(pDev->regs,&pDev->config);
|
grcan_hw_config(pDev->regs, &pDev->config);
|
||||||
pDev->config_changed = 0;
|
pDev->config_changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,10 +409,10 @@ static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
|
|||||||
pDev->regs->tx0size = pDev->txbuf_size;
|
pDev->regs->tx0size = pDev->txbuf_size;
|
||||||
|
|
||||||
/* Setup acceptance filters */
|
/* Setup acceptance filters */
|
||||||
grcan_hw_accept(pDev->regs,&pDev->afilter);
|
grcan_hw_accept(pDev->regs, &pDev->afilter);
|
||||||
|
|
||||||
/* Sync filters */
|
/* Sync filters */
|
||||||
grcan_hw_sync(pDev->regs,&pDev->sfilter);
|
grcan_hw_sync(pDev->regs, &pDev->sfilter);
|
||||||
|
|
||||||
/* Clear status bits */
|
/* Clear status bits */
|
||||||
tmp = READ_REG(&pDev->regs->stat);
|
tmp = READ_REG(&pDev->regs->stat);
|
||||||
@@ -429,14 +429,14 @@ static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
|
|||||||
|
|
||||||
/* Enable routing of the IRQs */
|
/* Enable routing of the IRQs */
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
IRQ_GLOBAL_DISABLE(oldLevel);
|
||||||
IRQ_UNMASK(pDev->irq+GRCAN_IRQ_TXSYNC);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_TXSYNC);
|
||||||
IRQ_UNMASK(pDev->irq+GRCAN_IRQ_RXSYNC);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_RXSYNC);
|
||||||
IRQ_UNMASK(pDev->irq+GRCAN_IRQ_IRQ);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_IRQ);
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
IRQ_GLOBAL_ENABLE(oldLevel);
|
||||||
|
|
||||||
/* Reset some software data */
|
/* Reset some software data */
|
||||||
/*pDev->txerror = 0;
|
/*pDev->txerror = 0;
|
||||||
pDev->rxerror = 0;*/
|
pDev->rxerror = 0; */
|
||||||
|
|
||||||
/* Enable receiver/transmitter */
|
/* Enable receiver/transmitter */
|
||||||
pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
|
pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
|
||||||
@@ -457,9 +457,9 @@ static void grcan_hw_stop(struct grcan_priv *pDev)
|
|||||||
|
|
||||||
/* Mask all IRQs */
|
/* Mask all IRQs */
|
||||||
pDev->regs->imr = 0;
|
pDev->regs->imr = 0;
|
||||||
IRQ_MASK(pDev->irq+GRCAN_IRQ_TXSYNC);
|
IRQ_MASK(pDev->irq + GRCAN_IRQ_TXSYNC);
|
||||||
IRQ_MASK(pDev->irq+GRCAN_IRQ_RXSYNC);
|
IRQ_MASK(pDev->irq + GRCAN_IRQ_RXSYNC);
|
||||||
IRQ_MASK(pDev->irq+GRCAN_IRQ_IRQ);
|
IRQ_MASK(pDev->irq + GRCAN_IRQ_IRQ);
|
||||||
|
|
||||||
/* Disable receiver & transmitter */
|
/* Disable receiver & transmitter */
|
||||||
pDev->regs->rx0ctrl = 0;
|
pDev->regs->rx0ctrl = 0;
|
||||||
@@ -476,37 +476,35 @@ static void grcan_hw_stop(struct grcan_priv *pDev)
|
|||||||
rtems_semaphore_flush(pDev->txempty_sem);
|
rtems_semaphore_flush(pDev->txempty_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grcan_hw_config(
|
static void grcan_hw_config(struct grcan_regs *regs, struct grcan_config *conf)
|
||||||
struct grcan_regs *regs,
|
|
||||||
struct grcan_config *conf
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
unsigned int config=0;
|
unsigned int config = 0;
|
||||||
|
|
||||||
/* Reset HurriCANe Core */
|
/* Reset HurriCANe Core */
|
||||||
regs->ctrl = 0;
|
regs->ctrl = 0;
|
||||||
|
|
||||||
if ( conf->silent )
|
if (conf->silent)
|
||||||
config |= GRCAN_CFG_SILENT;
|
config |= GRCAN_CFG_SILENT;
|
||||||
|
|
||||||
if ( conf->abort )
|
if (conf->abort)
|
||||||
config |= GRCAN_CFG_ABORT;
|
config |= GRCAN_CFG_ABORT;
|
||||||
|
|
||||||
if ( conf->selection.selection )
|
if (conf->selection.selection)
|
||||||
config |= GRCAN_CFG_SELECTION;
|
config |= GRCAN_CFG_SELECTION;
|
||||||
|
|
||||||
if ( conf->selection.enable0 )
|
if (conf->selection.enable0)
|
||||||
config |= GRCAN_CFG_ENABLE0;
|
config |= GRCAN_CFG_ENABLE0;
|
||||||
|
|
||||||
if ( conf->selection.enable1 )
|
if (conf->selection.enable1)
|
||||||
config |= GRCAN_CFG_ENABLE1;
|
config |= GRCAN_CFG_ENABLE1;
|
||||||
|
|
||||||
/* Timing */
|
/* Timing */
|
||||||
config |= (conf->timing.bpr<<GRCAN_CFG_BPR_BIT) & GRCAN_CFG_BPR;
|
config |= (conf->timing.bpr << GRCAN_CFG_BPR_BIT) & GRCAN_CFG_BPR;
|
||||||
config |= (conf->timing.rsj<<GRCAN_CFG_RSJ_BIT) & GRCAN_CFG_RSJ;
|
config |= (conf->timing.rsj << GRCAN_CFG_RSJ_BIT) & GRCAN_CFG_RSJ;
|
||||||
config |= (conf->timing.ps1<<GRCAN_CFG_PS1_BIT) & GRCAN_CFG_PS1;
|
config |= (conf->timing.ps1 << GRCAN_CFG_PS1_BIT) & GRCAN_CFG_PS1;
|
||||||
config |= (conf->timing.ps2<<GRCAN_CFG_PS2_BIT) & GRCAN_CFG_PS2;
|
config |= (conf->timing.ps2 << GRCAN_CFG_PS2_BIT) & GRCAN_CFG_PS2;
|
||||||
config |= (conf->timing.scaler<<GRCAN_CFG_SCALER_BIT) & GRCAN_CFG_SCALER;
|
config |=
|
||||||
|
(conf->timing.scaler << GRCAN_CFG_SCALER_BIT) & GRCAN_CFG_SCALER;
|
||||||
|
|
||||||
/* Write configuration */
|
/* Write configuration */
|
||||||
regs->conf = config;
|
regs->conf = config;
|
||||||
@@ -518,7 +516,7 @@ static void grcan_hw_config(
|
|||||||
static void grcan_hw_accept(
|
static void grcan_hw_accept(
|
||||||
struct grcan_regs *regs,
|
struct grcan_regs *regs,
|
||||||
struct grcan_filter *afilter
|
struct grcan_filter *afilter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Disable Sync mask totaly (if we change scode or smask
|
/* Disable Sync mask totaly (if we change scode or smask
|
||||||
* in an unfortunate way we may trigger a sync match)
|
* in an unfortunate way we may trigger a sync match)
|
||||||
@@ -530,10 +528,7 @@ static void grcan_hw_accept(
|
|||||||
regs->rx0mask = afilter->mask;
|
regs->rx0mask = afilter->mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grcan_hw_sync(
|
static void grcan_hw_sync(struct grcan_regs *regs, struct grcan_filter *sfilter)
|
||||||
struct grcan_regs *regs,
|
|
||||||
struct grcan_filter *sfilter
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Disable Sync mask totaly (if we change scode or smask
|
/* Disable Sync mask totaly (if we change scode or smask
|
||||||
* in an unfortunate way we may trigger a sync match)
|
* in an unfortunate way we may trigger a sync match)
|
||||||
@@ -547,21 +542,20 @@ static void grcan_hw_sync(
|
|||||||
|
|
||||||
static unsigned int grcan_hw_rxavail(
|
static unsigned int grcan_hw_rxavail(
|
||||||
unsigned int rp,
|
unsigned int rp,
|
||||||
unsigned int wp,
|
unsigned int wp, unsigned int size
|
||||||
unsigned int size
|
)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if ( rp == wp ) {
|
if (rp == wp) {
|
||||||
/* read pointer and write pointer is equal only
|
/* read pointer and write pointer is equal only
|
||||||
* when RX buffer is empty.
|
* when RX buffer is empty.
|
||||||
*/
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wp > rp ) {
|
if (wp > rp) {
|
||||||
return (wp-rp)/GRCAN_MSG_SIZE;
|
return (wp - rp) / GRCAN_MSG_SIZE;
|
||||||
}else{
|
} else {
|
||||||
return (size-(rp-wp))/GRCAN_MSG_SIZE;
|
return (size - (rp - wp)) / GRCAN_MSG_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,36 +563,36 @@ static unsigned int grcan_hw_txspace(
|
|||||||
unsigned int rp,
|
unsigned int rp,
|
||||||
unsigned int wp,
|
unsigned int wp,
|
||||||
unsigned int size
|
unsigned int size
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned int left;
|
unsigned int left;
|
||||||
|
|
||||||
if ( rp == wp ) {
|
if (rp == wp) {
|
||||||
/* read pointer and write pointer is equal only
|
/* read pointer and write pointer is equal only
|
||||||
* when TX buffer is empty.
|
* when TX buffer is empty.
|
||||||
*/
|
*/
|
||||||
return size/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
|
return size / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* size - 4 - abs(read-write) */
|
/* size - 4 - abs(read-write) */
|
||||||
if ( wp > rp ) {
|
if (wp > rp) {
|
||||||
left = size-(wp-rp);
|
left = size - (wp - rp);
|
||||||
}else{
|
} else {
|
||||||
left = rp-wp;
|
left = rp - wp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return left/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
|
return left / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grcan_hw_rx_ongoing(struct grcan_regs *regs)
|
static int grcan_hw_rx_ongoing(struct grcan_regs *regs)
|
||||||
{
|
{
|
||||||
return READ_REG(®s->rx0ctrl) & GRCAN_RXCTRL_ONGOING;
|
return READ_REG(®s->rx0ctrl) & GRCAN_RXCTRL_ONGOING;
|
||||||
};
|
}
|
||||||
|
|
||||||
static int grcan_hw_tx_ongoing(struct grcan_regs *regs)
|
static int grcan_hw_tx_ongoing(struct grcan_regs *regs)
|
||||||
{
|
{
|
||||||
return READ_REG(®s->tx0ctrl) & GRCAN_TXCTRL_ONGOING;
|
return READ_REG(®s->tx0ctrl) & GRCAN_TXCTRL_ONGOING;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
#define MIN_TSEG1 1
|
#define MIN_TSEG1 1
|
||||||
@@ -611,20 +605,20 @@ static int grcan_calc_timing(
|
|||||||
unsigned int core_hz, /* Frequency in Hz of GRCAN Core */
|
unsigned int core_hz, /* Frequency in Hz of GRCAN Core */
|
||||||
unsigned int sampl_pt,
|
unsigned int sampl_pt,
|
||||||
struct grcan_timing *timing /* result is placed here */
|
struct grcan_timing *timing /* result is placed here */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int best_error = 1000000000;
|
int best_error = 1000000000;
|
||||||
int error;
|
int error;
|
||||||
int best_tseg=0, best_brp=0, brp=0;
|
int best_tseg = 0, best_brp = 0, brp = 0;
|
||||||
int tseg=0, tseg1=0, tseg2=0;
|
int tseg = 0, tseg1 = 0, tseg2 = 0;
|
||||||
int sjw = 1;
|
int sjw = 1;
|
||||||
|
|
||||||
/* Default to 90% */
|
/* Default to 90% */
|
||||||
if ( (sampl_pt < 50) || (sampl_pt>99) ){
|
if ((sampl_pt < 50) || (sampl_pt > 99)) {
|
||||||
sampl_pt = GRCAN_SAMPLING_POINT;
|
sampl_pt = GRCAN_SAMPLING_POINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (baud<5000) || (baud>1000000) ){
|
if ((baud < 5000) || (baud > 1000000)) {
|
||||||
/* invalid speed mode */
|
/* invalid speed mode */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -641,75 +635,71 @@ static int grcan_calc_timing(
|
|||||||
sampl_pt = 75;
|
sampl_pt = 75;
|
||||||
|
|
||||||
/* tseg even = round down, odd = round up */
|
/* tseg even = round down, odd = round up */
|
||||||
for (tseg = (MIN_TSEG1 + MIN_TSEG2 + 2) * 2;
|
for (
|
||||||
|
tseg = (MIN_TSEG1 + MIN_TSEG2 + 2) * 2;
|
||||||
tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
|
tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
|
||||||
tseg++)
|
tseg++
|
||||||
{
|
) {
|
||||||
brp = core_hz / ((1 + tseg / 2) * baud) + tseg % 2;
|
brp = core_hz / ((1 + tseg / 2) * baud) + tseg % 2;
|
||||||
if ((brp <= 0) ||
|
if (
|
||||||
( (brp > 256*1) && (brp <= 256*2) && (brp&0x1) ) ||
|
(brp <= 0) ||
|
||||||
( (brp > 256*2) && (brp <= 256*4) && (brp&0x3) ) ||
|
((brp > 256 * 1) && (brp <= 256 * 2) && (brp & 0x1)) ||
|
||||||
( (brp > 256*4) && (brp <= 256*8) && (brp&0x7) ) ||
|
((brp > 256 * 2) && (brp <= 256 * 4) && (brp & 0x3)) ||
|
||||||
(brp > 256*8)
|
((brp > 256 * 4) && (brp <= 256 * 8) && (brp & 0x7)) ||
|
||||||
|
(brp > 256 * 8)
|
||||||
)
|
)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
error = baud - core_hz / (brp * (1 + tseg / 2));
|
error = baud - core_hz / (brp * (1 + tseg / 2));
|
||||||
if (error < 0)
|
if (error < 0) {
|
||||||
{
|
|
||||||
error = -error;
|
error = -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error <= best_error)
|
if (error <= best_error) {
|
||||||
{
|
|
||||||
best_error = error;
|
best_error = error;
|
||||||
best_tseg = tseg/2;
|
best_tseg = tseg / 2;
|
||||||
best_brp = brp-1;
|
best_brp = brp - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_error && (baud / best_error < 10))
|
if (best_error && (baud / best_error < 10)) {
|
||||||
{
|
|
||||||
return -2;
|
return -2;
|
||||||
}else if ( !timing )
|
} else if (!timing)
|
||||||
return 0; /* nothing to store result in, but a valid bitrate can be calculated */
|
return 0; /* nothing to store result in, but a valid bitrate can be calculated */
|
||||||
|
|
||||||
tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
|
tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
|
||||||
|
|
||||||
if (tseg2 < MIN_TSEG2)
|
if (tseg2 < MIN_TSEG2) {
|
||||||
{
|
|
||||||
tseg2 = MIN_TSEG2;
|
tseg2 = MIN_TSEG2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tseg2 > MAX_TSEG2)
|
if (tseg2 > MAX_TSEG2) {
|
||||||
{
|
|
||||||
tseg2 = MAX_TSEG2;
|
tseg2 = MAX_TSEG2;
|
||||||
}
|
}
|
||||||
|
|
||||||
tseg1 = best_tseg - tseg2 - 2;
|
tseg1 = best_tseg - tseg2 - 2;
|
||||||
|
|
||||||
if (tseg1 > MAX_TSEG1)
|
if (tseg1 > MAX_TSEG1) {
|
||||||
{
|
|
||||||
tseg1 = MAX_TSEG1;
|
tseg1 = MAX_TSEG1;
|
||||||
tseg2 = best_tseg - tseg1 - 2;
|
tseg2 = best_tseg - tseg1 - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get scaler and BRP from pseudo BRP */
|
/* Get scaler and BRP from pseudo BRP */
|
||||||
if ( best_brp <= 256 ){
|
if (best_brp <= 256) {
|
||||||
timing->scaler = best_brp;
|
timing->scaler = best_brp;
|
||||||
timing->bpr = 0;
|
timing->bpr = 0;
|
||||||
}else if ( best_brp <= 256*2 ){
|
} else if (best_brp <= 256 * 2) {
|
||||||
timing->scaler = ((best_brp+1)>>1) -1;
|
timing->scaler = ((best_brp + 1) >> 1) - 1;
|
||||||
timing->bpr = 1;
|
timing->bpr = 1;
|
||||||
}else if ( best_brp <= 256*4 ){
|
} else if (best_brp <= 256 * 4) {
|
||||||
timing->scaler = ((best_brp+1)>>2) -1;
|
timing->scaler = ((best_brp + 1) >> 2) - 1;
|
||||||
timing->bpr = 2;
|
timing->bpr = 2;
|
||||||
}else{
|
} else {
|
||||||
timing->scaler = ((best_brp+1)>>3) -1;
|
timing->scaler = ((best_brp + 1) >> 3) - 1;
|
||||||
timing->bpr = 3;
|
timing->bpr = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
timing->ps1 = tseg1+1;
|
timing->ps1 = tseg1 + 1;
|
||||||
timing->ps2 = tseg2;
|
timing->ps2 = tseg2;
|
||||||
timing->rsj = sjw;
|
timing->rsj = sjw;
|
||||||
|
|
||||||
@@ -719,14 +709,14 @@ static int grcan_calc_timing(
|
|||||||
static unsigned int grcan_hw_read_try(
|
static unsigned int grcan_hw_read_try(
|
||||||
struct grcan_priv *pDev,
|
struct grcan_priv *pDev,
|
||||||
struct grcan_regs *regs,
|
struct grcan_regs *regs,
|
||||||
CANMsg *buffer,
|
CANMsg * buffer,
|
||||||
int max
|
int max
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i, j;
|
||||||
CANMsg *dest;
|
CANMsg *dest;
|
||||||
struct grcan_msg *source,tmp;
|
struct grcan_msg *source, tmp;
|
||||||
unsigned int wp,rp,size,rxmax,addr,trunk_msg_cnt;
|
unsigned int wp, rp, size, rxmax, addr, trunk_msg_cnt;
|
||||||
|
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
@@ -740,48 +730,50 @@ static unsigned int grcan_hw_read_try(
|
|||||||
* reached the write pointer (empty buffer)
|
* reached the write pointer (empty buffer)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if ( wp != rp ){
|
if (wp != rp) {
|
||||||
/* Not empty, we have received chars...
|
/* Not empty, we have received chars...
|
||||||
* Read as much as possible from DMA buffer
|
* Read as much as possible from DMA buffer
|
||||||
*/
|
*/
|
||||||
size = READ_REG(®s->rx0size);
|
size = READ_REG(®s->rx0size);
|
||||||
|
|
||||||
/* Get number of bytes available in RX buffer */
|
/* Get number of bytes available in RX buffer */
|
||||||
trunk_msg_cnt = grcan_hw_rxavail(rp,wp,size);
|
trunk_msg_cnt = grcan_hw_rxavail(rp, wp, size);
|
||||||
|
|
||||||
/* truncate size if user space buffer hasn't room for
|
/* truncate size if user space buffer hasn't room for
|
||||||
* all received chars.
|
* all received chars.
|
||||||
*/
|
*/
|
||||||
if ( trunk_msg_cnt > max )
|
if (trunk_msg_cnt > max)
|
||||||
trunk_msg_cnt = max;
|
trunk_msg_cnt = max;
|
||||||
|
|
||||||
/* Read until i is 0 */
|
/* Read until i is 0 */
|
||||||
i=trunk_msg_cnt;
|
i = trunk_msg_cnt;
|
||||||
|
|
||||||
addr = (unsigned int)pDev->rx;
|
addr = (unsigned int)pDev->rx;
|
||||||
source = (struct grcan_msg *)(addr + rp);
|
source = (struct grcan_msg *)(addr + rp);
|
||||||
dest = buffer;
|
dest = buffer;
|
||||||
rxmax = addr + (size-GRCAN_MSG_SIZE);
|
rxmax = addr + (size - GRCAN_MSG_SIZE);
|
||||||
|
|
||||||
/* Read as many can messages as possible */
|
/* Read as many can messages as possible */
|
||||||
while(i>0){
|
while (i > 0) {
|
||||||
/* Read CAN message from DMA buffer */
|
/* Read CAN message from DMA buffer */
|
||||||
tmp.head[0] = READ_DMA_WORD(&source->head[0]);
|
tmp.head[0] = READ_DMA_WORD(&source->head[0]);
|
||||||
tmp.head[1] = READ_DMA_WORD(&source->head[1]);
|
tmp.head[1] = READ_DMA_WORD(&source->head[1]);
|
||||||
/* Convert one grcan CAN message to one "software" CAN message */
|
/* Convert one grcan CAN message to one "software" CAN message */
|
||||||
dest->extended = tmp.head[0]>>31;
|
dest->extended = tmp.head[0] >> 31;
|
||||||
dest->rtr = (tmp.head[0] >>30) & 0x1;
|
dest->rtr = (tmp.head[0] >> 30) & 0x1;
|
||||||
if ( dest->extended ){
|
if (dest->extended) {
|
||||||
dest->id = tmp.head[0] & 0x3fffffff;
|
dest->id = tmp.head[0] & 0x3fffffff;
|
||||||
}else{
|
} else {
|
||||||
dest->id = (tmp.head[0] >>18) & 0xfff;
|
dest->id = (tmp.head[0] >> 18) & 0xfff;
|
||||||
}
|
}
|
||||||
dest->len = tmp.head[1] >> 28;
|
dest->len = tmp.head[1] >> 28;
|
||||||
for(j=0; j<dest->len; j++)
|
for (j = 0; j < dest->len; j++)
|
||||||
dest->data[j] = READ_DMA_BYTE(&source->data[j]);
|
dest->data[j] = READ_DMA_BYTE(&source->data[j]);
|
||||||
|
|
||||||
/* wrap around if neccessary */
|
/* wrap around if neccessary */
|
||||||
source = ( (unsigned int)source >= rxmax ) ? (struct grcan_msg *)addr : source+1;
|
source =
|
||||||
|
((unsigned int)source >= rxmax) ?
|
||||||
|
(struct grcan_msg *)addr : source + 1;
|
||||||
dest++; /* straight user buffer */
|
dest++; /* straight user buffer */
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -789,11 +781,11 @@ static unsigned int grcan_hw_read_try(
|
|||||||
* ! wait for registers to be safely re-configurable
|
* ! wait for registers to be safely re-configurable
|
||||||
*/
|
*/
|
||||||
regs->rx0ctrl = 0; /* DISABLE RX CHANNEL */
|
regs->rx0ctrl = 0; /* DISABLE RX CHANNEL */
|
||||||
i=0;
|
i = 0;
|
||||||
while( grcan_hw_rx_ongoing(regs) && (i<1000) ){
|
while (grcan_hw_rx_ongoing(regs) && (i < 1000)) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
regs->rx0rd = (unsigned int)source-addr;
|
regs->rx0rd = (unsigned int)source - addr;
|
||||||
regs->rx0ctrl = GRCAN_RXCTRL_ENABLE; /* ENABLE_RX_CHANNEL */
|
regs->rx0ctrl = GRCAN_RXCTRL_ENABLE; /* ENABLE_RX_CHANNEL */
|
||||||
return trunk_msg_cnt;
|
return trunk_msg_cnt;
|
||||||
}
|
}
|
||||||
@@ -803,9 +795,9 @@ static unsigned int grcan_hw_read_try(
|
|||||||
static unsigned int grcan_hw_write_try(
|
static unsigned int grcan_hw_write_try(
|
||||||
struct grcan_priv *pDev,
|
struct grcan_priv *pDev,
|
||||||
struct grcan_regs *regs,
|
struct grcan_regs *regs,
|
||||||
CANMsg *buffer,
|
CANMsg * buffer,
|
||||||
int count
|
int count
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned int rp, wp, size, txmax, addr, ret;
|
unsigned int rp, wp, size, txmax, addr, ret;
|
||||||
struct grcan_msg *dest;
|
struct grcan_msg *dest;
|
||||||
@@ -814,45 +806,47 @@ static unsigned int grcan_hw_write_try(
|
|||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DBGC(DBG_TX,"\n");
|
DBGC(DBG_TX, "\n");
|
||||||
/*FUNCDBG();*/
|
/*FUNCDBG(); */
|
||||||
|
|
||||||
rp = READ_REG(®s->tx0rd);
|
rp = READ_REG(®s->tx0rd);
|
||||||
wp = READ_REG(®s->tx0wr);
|
wp = READ_REG(®s->tx0wr);
|
||||||
size = READ_REG(®s->tx0size);
|
size = READ_REG(®s->tx0size);
|
||||||
|
|
||||||
space_left = grcan_hw_txspace(rp,wp,size);
|
space_left = grcan_hw_txspace(rp, wp, size);
|
||||||
|
|
||||||
/* is circular fifo full? */
|
/* is circular fifo full? */
|
||||||
if ( space_left < 1 )
|
if (space_left < 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Truncate size */
|
/* Truncate size */
|
||||||
if ( space_left > count )
|
if (space_left > count)
|
||||||
space_left = count;
|
space_left = count;
|
||||||
ret = space_left;
|
ret = space_left;
|
||||||
|
|
||||||
addr = (unsigned int)pDev->tx;
|
addr = (unsigned int)pDev->tx;
|
||||||
|
|
||||||
dest = (struct grcan_msg *)(addr + wp);
|
dest = (struct grcan_msg *)(addr + wp);
|
||||||
source = (CANMsg *)buffer;
|
source = (CANMsg *) buffer;
|
||||||
txmax = addr + (size-GRCAN_MSG_SIZE);
|
txmax = addr + (size - GRCAN_MSG_SIZE);
|
||||||
|
|
||||||
while ( space_left>0 ) {
|
while (space_left > 0) {
|
||||||
/* Convert and write CAN message to DMA buffer */
|
/* Convert and write CAN message to DMA buffer */
|
||||||
if ( source->extended ){
|
if (source->extended) {
|
||||||
tmp = (1<<31) | (source->id & 0x3fffffff);
|
tmp = (1 << 31) | (source->id & 0x3fffffff);
|
||||||
}else{
|
} else {
|
||||||
tmp = (source->id&0xfff)<<18;
|
tmp = (source->id & 0xfff) << 18;
|
||||||
}
|
}
|
||||||
if ( source->rtr )
|
if (source->rtr)
|
||||||
tmp|=(1<<30);
|
tmp |= (1 << 30);
|
||||||
dest->head[0] = tmp;
|
dest->head[0] = tmp;
|
||||||
dest->head[1] = source->len<<28;
|
dest->head[1] = source->len << 28;
|
||||||
for ( i=0; i<source->len; i++)
|
for (i = 0; i < source->len; i++)
|
||||||
dest->data[i] = source->data[i];
|
dest->data[i] = source->data[i];
|
||||||
source++; /* straight user buffer */
|
source++; /* straight user buffer */
|
||||||
dest = ((unsigned int)dest >= txmax) ? (struct grcan_msg *)addr : dest+1;
|
dest =
|
||||||
|
((unsigned int)dest >= txmax) ?
|
||||||
|
(struct grcan_msg *)addr : dest + 1;
|
||||||
space_left--;
|
space_left--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,8 +854,8 @@ static unsigned int grcan_hw_write_try(
|
|||||||
* ! wait for registers to be safely re-configurable
|
* ! wait for registers to be safely re-configurable
|
||||||
*/
|
*/
|
||||||
regs->tx0ctrl = 0; /* DISABLE TX CHANNEL */
|
regs->tx0ctrl = 0; /* DISABLE TX CHANNEL */
|
||||||
i=0;
|
i = 0;
|
||||||
while( (grcan_hw_tx_ongoing(regs)) && i<1000 ){
|
while ((grcan_hw_tx_ongoing(regs)) && i < 1000) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
regs->tx0wr = (unsigned int)dest - addr; /* Update write pointer */
|
regs->tx0wr = (unsigned int)dest - addr; /* Update write pointer */
|
||||||
@@ -869,10 +863,7 @@ static unsigned int grcan_hw_write_try(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grcan_wait_rxdata(
|
static int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
|
||||||
struct grcan_priv *pDev,
|
|
||||||
int min
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
unsigned int wp, rp, size, irq;
|
unsigned int wp, rp, size, irq;
|
||||||
unsigned int irq_trunk, dataavail;
|
unsigned int irq_trunk, dataavail;
|
||||||
@@ -892,11 +883,11 @@ static int grcan_wait_rxdata(
|
|||||||
wp = READ_REG(&pDev->regs->rx0wr);
|
wp = READ_REG(&pDev->regs->rx0wr);
|
||||||
|
|
||||||
/**** Calculate IRQ Pointer ****/
|
/**** Calculate IRQ Pointer ****/
|
||||||
irq = wp + min*GRCAN_MSG_SIZE;
|
irq = wp + min * GRCAN_MSG_SIZE;
|
||||||
/* wrap irq around */
|
/* wrap irq around */
|
||||||
if ( irq >= size ){
|
if (irq >= size) {
|
||||||
irq_trunk = irq-size;
|
irq_trunk = irq - size;
|
||||||
}else
|
} else
|
||||||
irq_trunk = irq;
|
irq_trunk = irq;
|
||||||
|
|
||||||
/* init IRQ HW */
|
/* init IRQ HW */
|
||||||
@@ -908,21 +899,27 @@ static int grcan_wait_rxdata(
|
|||||||
wp = READ_REG(&pDev->regs->rx0wr);
|
wp = READ_REG(&pDev->regs->rx0wr);
|
||||||
|
|
||||||
/* Calculate messages available */
|
/* Calculate messages available */
|
||||||
dataavail = grcan_hw_rxavail(rp,wp,size);
|
dataavail = grcan_hw_rxavail(rp, wp, size);
|
||||||
|
|
||||||
if ( dataavail < min ){
|
if (dataavail < min) {
|
||||||
/* Still empty, proceed with sleep - Turn on IRQ (unmask irq) */
|
/* Still empty, proceed with sleep - Turn on IRQ (unmask irq) */
|
||||||
pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
|
pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
|
||||||
wait=1;
|
wait = 1;
|
||||||
}else{
|
} else {
|
||||||
/* enough message has been received, abort sleep - don't unmask interrupt */
|
/* enough message has been received, abort sleep - don't unmask interrupt */
|
||||||
wait=0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
IRQ_GLOBAL_ENABLE(oldLevel);
|
||||||
|
|
||||||
/* Wait for IRQ to fire only if has been triggered */
|
/* Wait for IRQ to fire only if has been triggered */
|
||||||
if ( wait ){
|
if (wait) {
|
||||||
if ( rtems_semaphore_obtain(pDev->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_UNSATISFIED )
|
if (
|
||||||
|
rtems_semaphore_obtain(
|
||||||
|
pDev->rx_sem,
|
||||||
|
RTEMS_WAIT,
|
||||||
|
RTEMS_NO_TIMEOUT
|
||||||
|
) == RTEMS_UNSATISFIED
|
||||||
|
)
|
||||||
return -1; /* Device driver has been closed or stopped, return with error status */
|
return -1; /* Device driver has been closed or stopped, return with error status */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,18 +933,15 @@ static int grcan_wait_rxdata(
|
|||||||
* than max buffer for this algo to work.
|
* than max buffer for this algo to work.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int grcan_wait_txspace(
|
static int grcan_wait_txspace(struct grcan_priv *pDev, int min)
|
||||||
struct grcan_priv *pDev,
|
|
||||||
int min
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int wait;
|
int wait;
|
||||||
unsigned int irq, rp, wp, size, space_left;
|
unsigned int irq, rp, wp, size, space_left;
|
||||||
unsigned int irq_trunk;
|
unsigned int irq_trunk;
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
IRQ_GLOBAL_PREPARE(oldLevel);
|
||||||
|
|
||||||
DBGC(DBG_TX,"\n");
|
DBGC(DBG_TX, "\n");
|
||||||
/*FUNCDBG();*/
|
/*FUNCDBG(); */
|
||||||
|
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
IRQ_GLOBAL_DISABLE(oldLevel);
|
||||||
|
|
||||||
@@ -959,11 +953,11 @@ static int grcan_wait_txspace(
|
|||||||
rp = READ_REG(&pDev->regs->tx0rd);
|
rp = READ_REG(&pDev->regs->tx0rd);
|
||||||
|
|
||||||
/**** Calculate IRQ Pointer ****/
|
/**** Calculate IRQ Pointer ****/
|
||||||
irq = rp + min*GRCAN_MSG_SIZE;
|
irq = rp + min * GRCAN_MSG_SIZE;
|
||||||
/* wrap irq around */
|
/* wrap irq around */
|
||||||
if ( irq >= size ){
|
if (irq >= size) {
|
||||||
irq_trunk = irq - size;
|
irq_trunk = irq - size;
|
||||||
}else
|
} else
|
||||||
irq_trunk = irq;
|
irq_trunk = irq;
|
||||||
|
|
||||||
/* trigger HW to do a IRQ when enough room in buffer */
|
/* trigger HW to do a IRQ when enough room in buffer */
|
||||||
@@ -981,22 +975,22 @@ static int grcan_wait_txspace(
|
|||||||
*/
|
*/
|
||||||
rp = READ_REG(&pDev->regs->tx0rd);
|
rp = READ_REG(&pDev->regs->tx0rd);
|
||||||
|
|
||||||
space_left = grcan_hw_txspace(rp,wp,size);
|
space_left = grcan_hw_txspace(rp, wp, size);
|
||||||
|
|
||||||
if ( space_left < min ){
|
if (space_left < min) {
|
||||||
/* Still too full, proceed with sleep - Turn on IRQ (unmask irq) */
|
/* Still too full, proceed with sleep - Turn on IRQ (unmask irq) */
|
||||||
pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
|
pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
|
||||||
wait=1;
|
wait = 1;
|
||||||
}else{
|
} else {
|
||||||
/* There are enough room in buffer, abort wait - don't unmask interrupt */
|
/* There are enough room in buffer, abort wait - don't unmask interrupt */
|
||||||
wait=0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
IRQ_GLOBAL_ENABLE(oldLevel);
|
||||||
|
|
||||||
/* Wait for IRQ to fire only if it has been triggered */
|
/* Wait for IRQ to fire only if it has been triggered */
|
||||||
if ( wait ){
|
if (wait) {
|
||||||
if ( rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, 100) ==
|
if (rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, 100) ==
|
||||||
RTEMS_UNSATISFIED ){
|
RTEMS_UNSATISFIED) {
|
||||||
/* Device driver has flushed us, this may be due to another thread has
|
/* Device driver has flushed us, this may be due to another thread has
|
||||||
* closed the device, this is to avoid deadlock */
|
* closed the device, this is to avoid deadlock */
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1019,27 +1013,32 @@ static int grcan_tx_flush(struct grcan_priv *pDev)
|
|||||||
*
|
*
|
||||||
* Hardware doesn't update write pointer - we do
|
* Hardware doesn't update write pointer - we do
|
||||||
*/
|
*/
|
||||||
while ( (wp=READ_REG(&pDev->regs->tx0wr)) != (rp=READ_REG(&pDev->regs->tx0rd)) ) {
|
while (
|
||||||
|
(wp = READ_REG(&pDev->regs->tx0wr)) !=
|
||||||
|
(rp = READ_REG(&pDev->regs->tx0rd))
|
||||||
|
) {
|
||||||
/* Wait for TX empty IRQ */
|
/* Wait for TX empty IRQ */
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
IRQ_GLOBAL_DISABLE(oldLevel);
|
||||||
/* Clear pending TXEmpty IRQ */
|
/* Clear pending TXEmpty IRQ */
|
||||||
pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
|
pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
|
||||||
|
|
||||||
if ( wp != READ_REG(&pDev->regs->tx0rd) ) {
|
if (wp != READ_REG(&pDev->regs->tx0rd)) {
|
||||||
/* Still not empty, proceed with sleep - Turn on IRQ (unmask irq) */
|
/* Still not empty, proceed with sleep - Turn on IRQ (unmask irq) */
|
||||||
pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
|
pDev->regs->imr =
|
||||||
|
READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
|
||||||
wait = 1;
|
wait = 1;
|
||||||
}else{
|
} else {
|
||||||
/* TX fifo is empty */
|
/* TX fifo is empty */
|
||||||
wait = 0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
IRQ_GLOBAL_ENABLE(oldLevel);
|
||||||
if ( !wait )
|
if (!wait)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Wait for IRQ to wake us */
|
/* Wait for IRQ to wake us */
|
||||||
if ( rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ==
|
if (rtems_semaphore_obtain
|
||||||
RTEMS_UNSATISFIED ) {
|
(pDev->txempty_sem, RTEMS_WAIT,
|
||||||
|
RTEMS_NO_TIMEOUT) == RTEMS_UNSATISFIED) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1145,13 +1144,13 @@ static void grcan_free_buffers(struct grcan_priv *pDev, int rx, int tx)
|
|||||||
{
|
{
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
if ( tx && pDev->_tx ){
|
if (tx && pDev->_tx) {
|
||||||
free(pDev->_tx);
|
free(pDev->_tx);
|
||||||
pDev->_tx = NULL;
|
pDev->_tx = NULL;
|
||||||
pDev->tx = NULL;
|
pDev->tx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rx && pDev->_rx ){
|
if (rx && pDev->_rx) {
|
||||||
free(pDev->_rx);
|
free(pDev->_rx);
|
||||||
pDev->_rx = NULL;
|
pDev->_rx = NULL;
|
||||||
pDev->rx = NULL;
|
pDev->rx = NULL;
|
||||||
@@ -1306,11 +1305,10 @@ int grcan_read(void *d, CANMsg *msg, size_t ucount)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(count == 0 || (pDev->rxcomplete && (count!=req_cnt)) ){
|
while (count == 0 || (pDev->rxcomplete && (count!=req_cnt))) {
|
||||||
|
if (!pDev->rxcomplete) {
|
||||||
if ( !pDev->rxcomplete ){
|
|
||||||
left = 1; /* return as soon as there is one message available */
|
left = 1; /* return as soon as there is one message available */
|
||||||
}else{
|
} else {
|
||||||
left = req_cnt - count; /* return as soon as all data are available */
|
left = req_cnt - count; /* return as soon as all data are available */
|
||||||
|
|
||||||
/* never wait for more than the half the maximum size of the receive buffer
|
/* never wait for more than the half the maximum size of the receive buffer
|
||||||
@@ -1318,12 +1316,12 @@ int grcan_read(void *d, CANMsg *msg, size_t ucount)
|
|||||||
* otherwise we would have to copy everything when the data has been
|
* otherwise we would have to copy everything when the data has been
|
||||||
* received.
|
* received.
|
||||||
*/
|
*/
|
||||||
if ( left > ((pDev->rxbuf_size/GRCAN_MSG_SIZE)/2) ){
|
if (left > ((pDev->rxbuf_size/GRCAN_MSG_SIZE) / 2)){
|
||||||
left = (pDev->rxbuf_size/GRCAN_MSG_SIZE)/2;
|
left = (pDev->rxbuf_size/GRCAN_MSG_SIZE) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( grcan_wait_rxdata(pDev,left) ) {
|
if (grcan_wait_rxdata(pDev, left)) {
|
||||||
/* The wait has been aborted, probably due to
|
/* The wait has been aborted, probably due to
|
||||||
* the device driver has been closed by another
|
* the device driver has been closed by another
|
||||||
* thread.
|
* thread.
|
||||||
|
|||||||
Reference in New Issue
Block a user