forked from Imagelibrary/rtems
bsp/gen5200: Move source files to bsps
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -72,14 +72,14 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/ata/ata-dma-pio-
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/irq/irq.c
|
||||
|
||||
# mscan
|
||||
librtemsbsp_a_SOURCES += mscan/mscan.c
|
||||
librtemsbsp_a_SOURCES += mscan/mscan-base.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/mscan/mscan.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/mscan/mscan-base.c
|
||||
|
||||
# nvram
|
||||
librtemsbsp_a_SOURCES += nvram/nvram.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/nvram/nvram.c
|
||||
|
||||
# slicetimer
|
||||
librtemsbsp_a_SOURCES += slicetimer/slicetimer.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/slicetimer/slicetimer.c
|
||||
|
||||
# tod
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/rtc/todcfg.c
|
||||
|
||||
@@ -1,546 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup m
|
||||
*
|
||||
* @brief MSCAN support functions code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/mscan-base.h>
|
||||
|
||||
#define MIN_NO_OF_TQ 7
|
||||
#define TSEG_1 1
|
||||
#define TSEG_2 2
|
||||
#define NO_OF_TABLE_ENTRIES 4
|
||||
#define SJW 3
|
||||
|
||||
#define CAN_MAX_NO_OF_TQ 25
|
||||
#define CAN_MAX_NO_OF_TQ_TSEG1 15
|
||||
#define CAN_MAX_NO_OF_TQ_TSEG2 7
|
||||
#define CAN_MAX_NO_OF_TQ_SJW 2
|
||||
|
||||
/**
|
||||
* Time segmant table.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>Number of time quantas</th>
|
||||
* <td>Time Segment 1</th>
|
||||
* <td>Time Segment 2</th>
|
||||
* <td>Sync: Jump width</th>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
static uint8_t can_time_segment_table
|
||||
[CAN_MAX_NO_OF_TQ - MIN_NO_OF_TQ + 1] [NO_OF_TABLE_ENTRIES] = {
|
||||
{7, 4, 2, 1},
|
||||
{8, 5, 2, 1},
|
||||
{9, 6, 2, 2},
|
||||
{10, 6, 3, 2},
|
||||
{11, 7, 3, 2},
|
||||
{12, 8, 3, 2},
|
||||
{13, 8, 4, 2},
|
||||
{14, 9, 4, 2},
|
||||
{15, 10, 4, 2},
|
||||
{16, 10, 5, 2},
|
||||
{17, 11, 5, 2},
|
||||
{18, 12, 5, 2},
|
||||
{19, 12, 6, 2},
|
||||
{20, 13, 6, 2},
|
||||
{21, 14, 6, 2},
|
||||
{22, 14, 7, 2},
|
||||
{23, 15, 7, 2},
|
||||
{24, 15, 8, 2},
|
||||
{25, 16, 8, 2}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Calculates the MSCAN clock prescaler value.
|
||||
*/
|
||||
static uint8_t prescaler_calculation(
|
||||
unsigned can_bit_rate,
|
||||
unsigned can_clock_frq,
|
||||
uint8_t *tq_no
|
||||
)
|
||||
{
|
||||
|
||||
/* local variables */
|
||||
uint8_t presc_val,
|
||||
tq_no_dev_min = 0;
|
||||
uint32_t bit_rate,
|
||||
bit_rate_dev,
|
||||
frq_tq,
|
||||
bit_rate_dev_min = 0xFFFFFFFF;
|
||||
|
||||
/* loop through all values of time quantas */
|
||||
for (*tq_no = CAN_MAX_NO_OF_TQ; *tq_no >= MIN_NO_OF_TQ; (*tq_no)--) {
|
||||
|
||||
/* calculate time quanta freq. */
|
||||
frq_tq = *tq_no * can_bit_rate;
|
||||
|
||||
/* calculate the optimized prescal. val. */
|
||||
presc_val = (can_clock_frq + frq_tq / 2) / frq_tq;
|
||||
|
||||
/* calculate the bitrate */
|
||||
bit_rate = can_clock_frq / (*tq_no * presc_val);
|
||||
|
||||
/* calculate the bitrate deviation */
|
||||
if (can_bit_rate >= bit_rate) {
|
||||
/* calculate the bitrate deviation */
|
||||
bit_rate_dev = can_bit_rate - bit_rate;
|
||||
} else {
|
||||
/* calculate the bitrate deviation */
|
||||
bit_rate_dev = bit_rate - can_bit_rate;
|
||||
}
|
||||
|
||||
/* check the deviation freq. */
|
||||
if (bit_rate_dev == 0) {
|
||||
|
||||
/* return if best match (zero deviation) */
|
||||
return (uint8_t) (presc_val);
|
||||
} else {
|
||||
|
||||
/* check for minimum of bit rate deviation */
|
||||
if (bit_rate_dev < bit_rate_dev_min) {
|
||||
|
||||
/* recognize the minimum freq. deviation */
|
||||
bit_rate_dev_min = bit_rate_dev;
|
||||
|
||||
/* recognize the no. of time quantas */
|
||||
tq_no_dev_min = *tq_no;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get the no of tq's */
|
||||
*tq_no = tq_no_dev_min;
|
||||
|
||||
/* calculate time quanta freq. */
|
||||
frq_tq = *tq_no * can_bit_rate;
|
||||
|
||||
/* return the optimized prescaler value */
|
||||
return (uint8_t) ((can_clock_frq + frq_tq / 2) / frq_tq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the bit rate for the MSCAN module @a m to @a can_bit_rate
|
||||
* in [bits/s].
|
||||
*/
|
||||
bool mscan_set_bit_rate( volatile mscan *m, unsigned can_bit_rate)
|
||||
{
|
||||
mscan_context context;
|
||||
unsigned prescale_val = 0;
|
||||
uint8_t tq_no,
|
||||
tseg_1,
|
||||
tseg_2,
|
||||
sseg;
|
||||
|
||||
if (can_bit_rate < MSCAN_BIT_RATE_MIN || can_bit_rate > MSCAN_BIT_RATE_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Enter initialization mode */
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
/* get optimized prescaler value */
|
||||
prescale_val = prescaler_calculation(can_bit_rate, IPB_CLOCK, &tq_no);
|
||||
|
||||
/* Check prescaler value */
|
||||
if (prescale_val > 64) {
|
||||
/* Leave initialization mode */
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* get time segment length from time segment table */
|
||||
tseg_1 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_1];
|
||||
tseg_2 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_2];
|
||||
sseg = can_time_segment_table[tq_no - MIN_NO_OF_TQ][SJW];
|
||||
|
||||
/* Bus Timing Register 0 MSCAN_A/_B ------------------------------ */
|
||||
/* [07]:SJW1 1 : Synchronization jump width, Bit1 */
|
||||
/* [06]:SJW0 0 : Synchronization jump width, Bit0 */
|
||||
/* SJW = 2 -> 3 Tq clock cycles */
|
||||
/* [05]:BRP5 0 : Baud Rate Prescaler, Bit 5 */
|
||||
/* [04]:BRP4 0 : Baud Rate Prescaler, Bit 4 */
|
||||
/* [03]:BRP3 0 : Baud Rate Prescaler, Bit 3 */
|
||||
/* [02]:BRP2 1 : Baud Rate Prescaler, Bit 2 */
|
||||
/* [01]:BRP1 0 : Baud Rate Prescaler, Bit 1 */
|
||||
/* [00]:BRP0 1 : Baud Rate Prescaler, Bit 0 */
|
||||
m->btr0 = (BTR0_SJW(sseg - 1) | BTR0_BRP(prescale_val - 1));
|
||||
|
||||
/* Bus Timing Register 1 MSCAN_A/_B ------------------------------ */
|
||||
/* [07]:SAMP 0 : One Sample per bit */
|
||||
/* [06]:TSEG22 0 : Time Segment 2, Bit 2 */
|
||||
/* [05]:TSEG21 1 : Time Segment 2, Bit 1 */
|
||||
/* [04]:TSEG20 0 : Time Segment 2, Bit 0 */
|
||||
/* -> PHASE_SEG2 = 3 Tq */
|
||||
/* [03]:TSEG13 0 : Time Segment 1, Bit 3 */
|
||||
/* [02]:TSEG12 1 : Time Segment 1, Bit 2 */
|
||||
/* [01]:TSEG11 1 : Time Segment 1, Bit 1 */
|
||||
/* [00]:TSEG10 0 : Time Segment 1, Bit 0 */
|
||||
m->btr1 = (BTR1_TSEG2(tseg_2 - 1) | BTR1_TSEG1(tseg_1 - 1));
|
||||
|
||||
/* Leave initialization mode */
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables all interrupts for the MSCAN module @a m.
|
||||
*/
|
||||
void mscan_interrupts_disable( volatile mscan *m)
|
||||
{
|
||||
m->rier = 0;
|
||||
m->tier = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enter initialization mode for the MSCAN module @a m.
|
||||
*
|
||||
* Saves the current MSCAN context in @a context.
|
||||
*/
|
||||
void mscan_initialization_mode_enter( volatile mscan *m, mscan_context *context)
|
||||
{
|
||||
/* Save context */
|
||||
context->ctl0 = m->ctl0 & CTL0_TIME;
|
||||
context->rier = m->rier;
|
||||
context->tier = m->tier;
|
||||
|
||||
/* Request initialization mode */
|
||||
m->ctl0 |= CTL0_INITRQ;
|
||||
|
||||
/* Wait for initialization mode acknowledge */
|
||||
while ((m->ctl1 & CTL1_INITAK) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Leave initialization mode for the MSCAN module @a m.
|
||||
*
|
||||
* Saves the previous MSCAN context saved in @a context.
|
||||
*/
|
||||
void mscan_initialization_mode_leave( volatile mscan *m, const mscan_context *context)
|
||||
{
|
||||
/* Clear initialization mode request */
|
||||
m->ctl0 &= ~CTL0_INITRQ;
|
||||
|
||||
/* Wait for clearing of initialization mode acknowledge */
|
||||
while ((m->ctl1 & CTL1_INITAK) != 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
/* Leave sleep mode */
|
||||
mscan_sleep_mode_leave( m);
|
||||
|
||||
/* Restore context */
|
||||
m->ctl0 |= context->ctl0;
|
||||
m->rier |= context->rier;
|
||||
m->tier |= context->tier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enter sleep mode for the MSCAN module @a m.
|
||||
*/
|
||||
void mscan_sleep_mode_enter( volatile mscan *m)
|
||||
{
|
||||
/* Request sleep mode */
|
||||
m->ctl0 |= CTL0_SLPRQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Leave sleep mode for the MSCAN module @a m.
|
||||
*/
|
||||
void mscan_sleep_mode_leave( volatile mscan *m)
|
||||
{
|
||||
/* Clear sleep mode request */
|
||||
m->ctl0 &= ~CTL0_SLPRQ;
|
||||
|
||||
/* Wait for clearing of sleep mode acknowledge */
|
||||
while ((m->ctl1 & CTL1_SLPAK) != 0) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables and initializes the MSCAN module @a m.
|
||||
*
|
||||
* The module is set to listen only mode.
|
||||
*/
|
||||
bool mscan_enable( volatile mscan *m, unsigned bit_rate)
|
||||
{
|
||||
bool s = true;
|
||||
|
||||
/* Disable the module */
|
||||
mscan_disable( m);
|
||||
|
||||
/* Enable module in listen only */
|
||||
m->ctl1 = CTL1_CANE | CTL1_LISTEN;
|
||||
|
||||
/* Close acceptance filters */
|
||||
m->idac = IDAC_IDAM1 | IDAC_IDAM0;
|
||||
|
||||
/* Clear filter */
|
||||
mscan_filter_clear( m);
|
||||
|
||||
/* Set bit rate and leave initialization mode */
|
||||
s = mscan_set_bit_rate( m, bit_rate);
|
||||
|
||||
/* Clear all flags */
|
||||
m->ctl0 = CTL0_RXFRM;
|
||||
|
||||
/* Disable interrupts */
|
||||
mscan_interrupts_disable( m);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the MSCAN module @a m.
|
||||
*
|
||||
* The module is set to sleep mode and disabled afterwards.
|
||||
*/
|
||||
void mscan_disable( volatile mscan *m)
|
||||
{
|
||||
mscan_context context;
|
||||
|
||||
/* Disable interrupts */
|
||||
mscan_interrupts_disable( m);
|
||||
|
||||
/* Enter initialization mode */
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
/* Disable module */
|
||||
m->ctl1 &= ~CTL1_CANE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the filter ID and mask registers of the MSCAN module @a m to
|
||||
* default values.
|
||||
*/
|
||||
void mscan_filter_clear( volatile mscan *m)
|
||||
{
|
||||
mscan_context context;
|
||||
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
/* Setup ID acceptance registers */
|
||||
m->idar0 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar1 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar2 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar3 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar4 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar5 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar6 = MSCAN_FILTER_ID_DEFAULT;
|
||||
m->idar7 = MSCAN_FILTER_ID_DEFAULT;
|
||||
|
||||
/* Setup ID mask registers */
|
||||
m->idmr0 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr1 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr2 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr3 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr4 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr5 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr6 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
m->idmr7 = (uint8_t) MSCAN_FILTER_MASK_DEFAULT;
|
||||
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of active filters of the MSCAN module @a m.
|
||||
*
|
||||
* @see MSCAN_FILTER_NUMBER_MIN, MSCAN_FILTER_NUMBER_2, MSCAN_FILTER_NUMBER_4
|
||||
* and MSCAN_FILTER_NUMBER_MAX.
|
||||
*/
|
||||
unsigned mscan_filter_number( volatile mscan *m)
|
||||
{
|
||||
uint8_t idam = m->idac & IDAC_IDAM;
|
||||
|
||||
switch (idam) {
|
||||
case 0:
|
||||
return MSCAN_FILTER_NUMBER_2;
|
||||
case IDAC_IDAM0:
|
||||
return MSCAN_FILTER_NUMBER_4;
|
||||
case IDAC_IDAM1:
|
||||
return MSCAN_FILTER_NUMBER_MAX;
|
||||
default:
|
||||
return MSCAN_FILTER_NUMBER_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of active filters of the MSCAN module @a m to @a
|
||||
* number and returns true if @a number is valid.
|
||||
*
|
||||
* @see MSCAN_FILTER_NUMBER_MIN, MSCAN_FILTER_NUMBER_2, MSCAN_FILTER_NUMBER_4
|
||||
* and MSCAN_FILTER_NUMBER_MAX.
|
||||
*/
|
||||
bool mscan_set_filter_number( volatile mscan *m, unsigned number)
|
||||
{
|
||||
mscan_context context;
|
||||
uint8_t idac = IDAC_IDAM1 | IDAC_IDAM0;
|
||||
|
||||
switch (number) {
|
||||
case MSCAN_FILTER_NUMBER_MIN:
|
||||
break;
|
||||
case MSCAN_FILTER_NUMBER_2:
|
||||
idac = 0;
|
||||
break;
|
||||
case MSCAN_FILTER_NUMBER_4:
|
||||
idac = IDAC_IDAM0;
|
||||
break;
|
||||
case MSCAN_FILTER_NUMBER_MAX:
|
||||
idac = IDAC_IDAM1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
m->idac = idac;
|
||||
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
|
||||
/* Clear filter */
|
||||
mscan_filter_clear( m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the address of the CANIDAR register with index @a i of the
|
||||
* MSCAN module @a m.
|
||||
*
|
||||
* @warning The index @a i is not checked if it is in range.
|
||||
*/
|
||||
volatile uint8_t *mscan_id_acceptance_register( volatile mscan *m, unsigned i)
|
||||
{
|
||||
volatile uint8_t *const idar [8] = {
|
||||
&m->idar0,
|
||||
&m->idar1,
|
||||
&m->idar2,
|
||||
&m->idar3,
|
||||
&m->idar4,
|
||||
&m->idar5,
|
||||
&m->idar6,
|
||||
&m->idar7
|
||||
};
|
||||
|
||||
return idar [i];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the address of the CANIDMR register with index @a i of the
|
||||
* MSCAN module @a m.
|
||||
*
|
||||
* @warning The index @a i is not checked if it is in range.
|
||||
*/
|
||||
volatile uint8_t *mscan_id_mask_register( volatile mscan *m, unsigned i)
|
||||
{
|
||||
volatile uint8_t *const idmr [8] = {
|
||||
&m->idmr0,
|
||||
&m->idmr1,
|
||||
&m->idmr2,
|
||||
&m->idmr3,
|
||||
&m->idmr4,
|
||||
&m->idmr5,
|
||||
&m->idmr6,
|
||||
&m->idmr7
|
||||
};
|
||||
|
||||
return idmr [i];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets or gets the filter ID and mask in @a id and @a mask depending on
|
||||
* @a set of MSCAN module @a m. The filter is selected by the value of @a
|
||||
* index.
|
||||
*
|
||||
* Returns true if the operation was successful.
|
||||
*/
|
||||
bool mscan_filter_operation(
|
||||
volatile mscan *m,
|
||||
bool set,
|
||||
unsigned index,
|
||||
uint32_t *id,
|
||||
uint32_t *mask
|
||||
)
|
||||
{
|
||||
unsigned number = mscan_filter_number( m);
|
||||
unsigned offset = MSCAN_FILTER_NUMBER_MAX / number;
|
||||
unsigned shift = 24;
|
||||
|
||||
volatile uint8_t *idar = NULL;
|
||||
volatile uint8_t *idmr = NULL;
|
||||
|
||||
if (!set) {
|
||||
*id = MSCAN_FILTER_ID_DEFAULT;
|
||||
*mask = MSCAN_FILTER_MASK_DEFAULT;
|
||||
}
|
||||
|
||||
if (index < number) {
|
||||
mscan_context context;
|
||||
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
index *= offset;
|
||||
offset += index;
|
||||
while (index < offset) {
|
||||
idar = mscan_id_acceptance_register( m, index);
|
||||
idmr = mscan_id_mask_register( m, index);
|
||||
|
||||
if (set) {
|
||||
*idar = (uint8_t) (*id >> shift);
|
||||
*idmr = (uint8_t) (*mask >> shift);
|
||||
} else {
|
||||
*id = (*id & ~(0xffU << shift)) | (*idar << shift);
|
||||
*mask = (*mask & ~(0xffU << shift)) | (*idmr << shift);
|
||||
}
|
||||
|
||||
shift -= 8;
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the receiver and transmitter error counter values in @a rec
|
||||
* and @a tec of MSCAN module @a m.
|
||||
*/
|
||||
void mscan_get_error_counters( volatile mscan *m, unsigned *rec, unsigned *tec)
|
||||
{
|
||||
mscan_context context;
|
||||
|
||||
mscan_initialization_mode_enter( m, &context);
|
||||
|
||||
*rec = m->rxerr;
|
||||
*tec = m->txerr;
|
||||
|
||||
mscan_initialization_mode_leave( m, &context);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,185 +0,0 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic MPC5200 BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Partially based on the code references which are named below. |
|
||||
| Adaptions, modifications, enhancements and any recent parts of |
|
||||
| the code are: |
|
||||
| Copyright (c) 2005 |
|
||||
| Embedded Brains GmbH |
|
||||
| Obere Lagerstr. 30 |
|
||||
| D-82178 Puchheim |
|
||||
| Germany |
|
||||
| rtems@embedded-brains.de |
|
||||
+-----------------------------------------------------------------+
|
||||
| The license and distribution terms for this file may be |
|
||||
| found in the file LICENSE in this distribution or at |
|
||||
| |
|
||||
| http://www.rtems.org/license/LICENSE. |
|
||||
| |
|
||||
+-----------------------------------------------------------------+
|
||||
| this file has to be included by the m driver |
|
||||
\*===============================================================*/
|
||||
#ifndef __MSCAN_INT_H__
|
||||
#define __MSCAN_INT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <bsp/mscan-base.h>
|
||||
|
||||
#include <bsp/mscan.h>
|
||||
|
||||
#define MSCAN_RX_BUFF_NUM 4
|
||||
#define MSCAN_TX_BUFF_NUM 3
|
||||
|
||||
#define MSCAN_NON_INITIALIZED_MODE 0
|
||||
#define MSCAN_INITIALIZED_MODE 1
|
||||
#define MSCAN_INIT_NORMAL_MODE 2
|
||||
#define MSCAN_NORMAL_MODE 4
|
||||
#define MSCAN_SLEEP_MODE 8
|
||||
|
||||
#define MSCAN_RX_BUFF_NOACTIVE (0 << 4)
|
||||
#define MSCAN_RX_BUFF_EMPTY (1 << 6)
|
||||
#define MSCAN_RX_BUFF_FULL (1 << 5)
|
||||
#define MSCAN_RX_BUFF_OVERRUN ((MSCAN_RX_BUFF_EMPTY) | (MSCAN_RX_BUFF_FULL))
|
||||
#define MSCAN_RX_BUFF_BUSY (1 << 4)
|
||||
|
||||
#define MSCAN_MBUFF_MASK 0x07
|
||||
|
||||
#define MSCAN_TX_BUFF0 (1 << 0)
|
||||
#define MSCAN_TX_BUFF1 (1 << 1)
|
||||
#define MSCAN_TX_BUFF2 (1 << 2)
|
||||
|
||||
#define MSCAN_IDE (1 << 0)
|
||||
#define MSCAN_RTR (1 << 1)
|
||||
#define MSCAN_READ_RXBUFF_0 (1 << 2)
|
||||
#define MSCAN_READ_RXBUFF_1 (1 << 2)
|
||||
#define MSCAN_READ_RXBUFF_2 (1 << 2)
|
||||
#define MSCAN_READ_RXBUFF_3 (1 << 2)
|
||||
|
||||
#define MSCAN_STATE_OK 0
|
||||
#define MSCAN_STATE_ERR 1
|
||||
#define MSCAN_STATE_WRN 2
|
||||
#define MSCAN_STATE_BUSOFF 3
|
||||
|
||||
#define TX_MBUF_SEL(buf_no) (1 << (buf_no))
|
||||
#define TX_DATA_LEN(len) ((len) & 0x0F)
|
||||
|
||||
#define TX_MBUF_EMPTY(val) (1 << (val))
|
||||
|
||||
#define ID_RTR (1 << 4)
|
||||
|
||||
#define SET_IDR0(u16) ((uint8_t)((u16) >> 3))
|
||||
#define SET_IDR1(u16) (MSCAN_MESS_ID_HAS_RTR(u16) ? ((uint8_t)(((u16) & 0x0007) << 5))|((uint8_t)(ID_RTR)) : ((uint8_t)(((u16) & 0x0007) << 5)))
|
||||
|
||||
#define SET_IDR2(u16) SET_IDR0(u16)
|
||||
#define SET_IDR3(u16) SET_IDR1(u16)
|
||||
|
||||
#define SET_IDR4(u16) SET_IDR0(u16)
|
||||
#define SET_IDR5(u16) SET_IDR1(u16)
|
||||
|
||||
#define SET_IDR6(u16) SET_IDR0(u16)
|
||||
#define SET_IDR7(u16) SET_IDR1(u16)
|
||||
|
||||
#define GET_IDR0(u16) ((uint16_t) ((u16) << 3))
|
||||
#define GET_IDR1(u16) ((((u16)&(ID_RTR))==(ID_RTR)) ? (uint16_t) ((((u16) >> 5)&0x0007)|MSCAN_MESS_ID_RTR) : (uint16_t)(((u16) >> 5)&0x0007))
|
||||
|
||||
#define GET_IDR2(u16) GET_IDR0(u16)
|
||||
#define GET_IDR3(u16) GET_IDR1(u16)
|
||||
|
||||
#define GET_IDR4(u16) GET_IDR0(u16)
|
||||
#define GET_IDR5(u16) GET_IDR1(u16)
|
||||
|
||||
#define GET_IDR6(u16) GET_IDR0(u16)
|
||||
#define GET_IDR7(u16) GET_IDR1(u16)
|
||||
|
||||
#define SET_IDMR0(u16) ((uint8_t)((u16) >> 3))
|
||||
#define SET_IDMR1(u16) (MSCAN_MESS_ID_HAS_RTR(u16) ? ((uint8_t) (((((u16) & 0x0007) << 5)|((uint8_t)(ID_RTR)))|0x0007)) : ((uint8_t)((((u16) & 0x0007) << 5))|0x0007))
|
||||
|
||||
#define SET_IDMR2(u16) SET_IDMR0(u16)
|
||||
#define SET_IDMR3(u16) SET_IDMR1(u16)
|
||||
|
||||
#define SET_IDMR4(u16) SET_IDMR0(u16)
|
||||
#define SET_IDMR5(u16) SET_IDMR1(u16)
|
||||
|
||||
#define SET_IDMR6(u16) SET_IDMR0(u16)
|
||||
#define SET_IDMR7(u16) SET_IDMR1(u16)
|
||||
|
||||
#define GET_IDMR0(u16) ((uint16_t)((u16) << 3))
|
||||
#define GET_IDMR1(u16) ((((u16)&(ID_RTR))==(ID_RTR)) ? (uint16_t) ((((u16) >> 5)&0x0007)|MSCAN_MESS_ID_RTR) : (uint16_t)(((u16) >> 5)&0x0007))
|
||||
|
||||
#define GET_IDMR2(u16) GET_IDMR0(u16)
|
||||
#define GET_IDMR3(u16) GET_IDMR1(u16)
|
||||
|
||||
#define GET_IDMR4(u16) GET_IDMR0(u16)
|
||||
#define GET_IDMR5(u16) GET_IDMR1(u16)
|
||||
|
||||
#define GET_IDMR6(u16) GET_IDMR0(u16)
|
||||
#define GET_IDMR7(u16) GET_IDMR1(u16)
|
||||
|
||||
#define NO_OF_MSCAN_RX_BUFF 20
|
||||
#define MSCAN_MESSAGE_SIZE(size) (((size)%CPU_ALIGNMENT) ? (((size) + CPU_ALIGNMENT)-((size) + CPU_ALIGNMENT)%CPU_ALIGNMENT) : (size))
|
||||
|
||||
#define TX_BUFFER_0 0
|
||||
#define TX_BUFFER_1 1
|
||||
#define TX_BUFFER_2 2
|
||||
|
||||
#define RX_BUFFER_0 0
|
||||
#define RX_BUFFER_1 1
|
||||
#define RX_BUFFER_2 2
|
||||
#define RX_BUFFER_3 3
|
||||
|
||||
#define NO_OF_MSCAN_TX_BUFF 20
|
||||
#define RING_BUFFER_EMPTY(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE)
|
||||
#define RING_BUFFER_FULL(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE)
|
||||
|
||||
|
||||
typedef struct _mscan_handle
|
||||
{
|
||||
uint8_t mscan_channel;
|
||||
void (*toucan_callback)(int16_t);
|
||||
} mscan_handle;
|
||||
|
||||
struct ring_buf
|
||||
{
|
||||
struct can_message * volatile buf_ptr;
|
||||
struct can_message * volatile head_ptr;
|
||||
struct can_message * volatile tail_ptr;
|
||||
};
|
||||
|
||||
struct mpc5200_rx_cntrl
|
||||
{
|
||||
struct can_message can_rx_message[MSCAN_RX_BUFF_NUM];
|
||||
};
|
||||
|
||||
struct mscan_channel_info
|
||||
{
|
||||
mscan *regs;
|
||||
uint32_t int_rx_err;
|
||||
rtems_id rx_qid;
|
||||
uint32_t rx_qname;
|
||||
rtems_id tx_rb_sid;
|
||||
uint32_t tx_rb_sname;
|
||||
uint8_t id_extended;
|
||||
uint8_t mode;
|
||||
uint8_t tx_buf_no;
|
||||
struct ring_buf tx_ring_buf;
|
||||
};
|
||||
|
||||
extern void CanInterrupt_A(int16_t);
|
||||
extern void CanInterrupt_B(int16_t);
|
||||
|
||||
/*MSCAN driver internal functions */
|
||||
void mscan_hardware_initialize(rtems_device_major_number, uint32_t, void *);
|
||||
void mpc5200_mscan_wait_sync(mscan *);
|
||||
void mpc5200_mscan_perform_init_mode_settings(mscan *);
|
||||
void mpc5200_mscan_perform_normal_mode_settings(mscan *);
|
||||
rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number, uint8_t);
|
||||
rtems_status_code mscan_channel_initialize(rtems_device_major_number, rtems_device_minor_number);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSCAN_H__ */
|
||||
@@ -1,163 +0,0 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic MPC5200 BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Partially based on the code references which are named below. |
|
||||
| Adaptions, modifications, enhancements and any recent parts of |
|
||||
| the code are: |
|
||||
| Copyright (c) 2005 |
|
||||
| Embedded Brains GmbH |
|
||||
| Obere Lagerstr. 30 |
|
||||
| D-82178 Puchheim |
|
||||
| Germany |
|
||||
| rtems@embedded-brains.de |
|
||||
+-----------------------------------------------------------------+
|
||||
| The license and distribution terms for this file may be |
|
||||
| found in the file LICENSE in this distribution or at |
|
||||
| |
|
||||
| http://www.rtems.org/license/LICENSE. |
|
||||
| |
|
||||
+-----------------------------------------------------------------+
|
||||
| this file contains definitions for the M93Cxx EEPROM devices |
|
||||
\*===============================================================*/
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Module: m93cxx.h */
|
||||
/* Date: 07/17/2003 */
|
||||
/* Purpose: RTEMS M93C64-based header file */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Description: M93C46 is a serial microwire EEPROM which contains */
|
||||
/* 1Kbit (128 bytes/64 words) of non-volatile memory. */
|
||||
/* The device can be configured for byte- or word- */
|
||||
/* access. The driver provides a file-like interface */
|
||||
/* to this memory. */
|
||||
/* */
|
||||
/* MPC5x00 PIN settings: */
|
||||
/* */
|
||||
/* PSC3_6 (output) -> MC93C46 serial data in (D) */
|
||||
/* PSC3_7 (input) -> MC93C46 serial data out (Q) */
|
||||
/* PSC3_8 (output) -> MC93C46 chip select input (S) */
|
||||
/* PSC3_9 (output) -> MC93C46 serial clock (C) */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Code */
|
||||
/* References: none */
|
||||
/* Module: */
|
||||
/* Project: */
|
||||
/* Version */
|
||||
/* Date: */
|
||||
/* Author: */
|
||||
/* Copyright: */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Partially based on the code references which are named above. */
|
||||
/* Adaptions, modifications, enhancements and any recent parts of */
|
||||
/* the code are under the right of */
|
||||
/* */
|
||||
/* IPR Engineering, Dachauer Straße 38, D-80335 München */
|
||||
/* Copyright(C) 2003 */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* IPR Engineering makes no representation or warranties with */
|
||||
/* respect to the performance of this computer program, and */
|
||||
/* specifically disclaims any responsibility for any damages, */
|
||||
/* special or consequential, connected with the use of this program. */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Version history: 1.0 */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
#ifndef __M93CXX_H__
|
||||
#define __M93CXX_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static void m93cxx_enable_write(void);
|
||||
static void m93cxx_disable_write(void);
|
||||
static void m93cxx_write_byte(uint32_t, uint8_t);
|
||||
static uint8_t m93cxx_read_byte(uint32_t);
|
||||
void wait_usec(unsigned long);
|
||||
|
||||
#define M93CXX_MODE_WORD
|
||||
/*#define M93C46_MODE_BYTE*/
|
||||
#define M93C46
|
||||
#define M93C46_NVRAM_SIZE 128
|
||||
|
||||
#define GPIO_PSC3_6 (1 << 12)
|
||||
#define GPIO_PSC3_7 (1 << 13)
|
||||
#define GPIO_PSC3_8 (1 << 26)
|
||||
#define GPIO_PSC3_9 (1 << 26)
|
||||
|
||||
#define START_BIT 0x1
|
||||
#define EWDS_OPCODE 0x0
|
||||
#define WRAL_OPCODE 0x1
|
||||
#define ERAL_OPCODE 0x2
|
||||
#define EWEN_OPCODE 0x3
|
||||
#define WRITE_OPCODE 0x4
|
||||
#define READ_OPCODE 0x8
|
||||
#define ERASE_OPCODE 0xC
|
||||
|
||||
#define WAIT(i) wait_usec(i)
|
||||
|
||||
#define ENABLE_CHIP_SELECT mpc5200.gpiosido |= GPIO_PSC3_8
|
||||
#define DISABLE_CHIP_SELECT mpc5200.gpiosido &= ~GPIO_PSC3_8
|
||||
#define SET_DATA_BIT_HIGH mpc5200.gpiosdo |= GPIO_PSC3_6
|
||||
#define SET_DATA_BIT_LOW mpc5200.gpiosdo &= ~GPIO_PSC3_6
|
||||
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
#define GET_DATA_BYTE_SHIFT(val) ((val) |= ((mpc5200.gpiosdi & GPIO_PSC3_7) >> 13)); \
|
||||
((val) <<= 1)
|
||||
#define SET_DATA_BYTE_SHIFT(val) (((val) & 0x80) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \
|
||||
((val) <<= 1)
|
||||
#else
|
||||
#define GET_DATA_WORD_SHIFT(val) ((val) |= ((mpc5200.gpiosdi & GPIO_PSC3_7) >> 13)); \
|
||||
((val) <<= 1)
|
||||
#define SET_DATA_WORD_SHIFT(val) (((val) & 0x8000) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \
|
||||
((val) <<= 1)
|
||||
#endif
|
||||
|
||||
#define MASK_HEAD_SHIFT(head) ((((head) & 0x80000000) >> 31) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \
|
||||
((head) <<= 1)
|
||||
#define DO_CLOCK_CYCLE mpc5200.gpiowdo |= GPIO_PSC3_9; \
|
||||
WAIT(1000); \
|
||||
mpc5200.gpiowdo &= ~GPIO_PSC3_9
|
||||
#define CHECK_WRITE_BUSY while(!(mpc5200.gpiosdi & GPIO_PSC3_7))
|
||||
|
||||
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
#ifdef M93C46
|
||||
#define M93C46_EWDS ((START_BIT << 31) | (EWDS_OPCODE << 27))
|
||||
#define M93C46_WRAL ((START_BIT << 31) | (WRAL_OPCODE << 27))
|
||||
#define M93C46_ERAL ((START_BIT << 31) | (ERAL_OPCODE << 27))
|
||||
#define M93C46_EWEN ((START_BIT << 31) | (EWEN_OPCODE << 27))
|
||||
#define M93C46_READ(addr) ((START_BIT << 31) | (READ_OPCODE << 27) | ((addr) << 22))
|
||||
#define M93C46_WRITE(addr) ((START_BIT << 31) | (WRITE_OPCODE << 27) | ((addr) << 22))
|
||||
#define M93C46_ERASE(addr) ((START_BIT << 31) | (ERASE_OPCODE << 27) | ((addr) << 22))
|
||||
#define M93C46_CLOCK_CYCLES 10
|
||||
#endif
|
||||
#else
|
||||
#ifdef M93C46
|
||||
#define M93C46_EWDS ((START_BIT << 31) | (EWDS_OPCODE << 27))
|
||||
#define M93C46_WRAL ((START_BIT << 31) | (WRAL_OPCODE << 27))
|
||||
#define M93C46_ERAL ((START_BIT << 31) | (ERAL_OPCODE << 27))
|
||||
#define M93C46_EWEN ((START_BIT << 31) | (EWEN_OPCODE << 27))
|
||||
#define M93C46_READ(addr) ((START_BIT << 31) | (READ_OPCODE << 27) | ((addr) << 23))
|
||||
#define M93C46_WRITE(addr) ((START_BIT << 31) | (WRITE_OPCODE << 27) | ((addr) << 23))
|
||||
#define M93C46_ERASE(addr) ((START_BIT << 31) | (ERASE_OPCODE << 27) | ((addr) << 23))
|
||||
#define M93C46_CLOCK_CYCLES 9
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __M93CXX_H__ */
|
||||
@@ -1,603 +0,0 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic MPC5200 BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Partially based on the code references which are named below. |
|
||||
| Adaptions, modifications, enhancements and any recent parts of |
|
||||
| the code are: |
|
||||
| Copyright (c) 2005 |
|
||||
| Embedded Brains GmbH |
|
||||
| Obere Lagerstr. 30 |
|
||||
| D-82178 Puchheim |
|
||||
| Germany |
|
||||
| rtems@embedded-brains.de |
|
||||
+-----------------------------------------------------------------+
|
||||
| The license and distribution terms for this file may be |
|
||||
| found in the file LICENSE in this distribution or at |
|
||||
| |
|
||||
| http://www.rtems.org/license/LICENSE. |
|
||||
| |
|
||||
+-----------------------------------------------------------------+
|
||||
| this file contains the nvram functions |
|
||||
\*===============================================================*/
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Module: nvram.c */
|
||||
/* Date: 07/17/2003 */
|
||||
/* Purpose: RTEMS M93C64-based NV memory device driver */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Description: M93C46 is a serial microwire EEPROM which contains */
|
||||
/* 1Kbit (128 bytes/64 words) of non-volatile memory. */
|
||||
/* The device can be coigured for byte- or word- */
|
||||
/* access. The driver provides a file-like interface */
|
||||
/* to this memory. */
|
||||
/* */
|
||||
/* MPC5x00 PIN settings: */
|
||||
/* */
|
||||
/* PSC3_6 (output) -> MC93C46 serial data in (D) */
|
||||
/* PSC3_7 (input) -> MC93C46 serial data out (Q) */
|
||||
/* PSC3_8 (output) -> MC93C46 chip select input (S) */
|
||||
/* PSC3_9 (output) -> MC93C46 serial clock (C) */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Code */
|
||||
/* References: DS1307-based Non-Volatile memory device driver */
|
||||
/* Module: nvram.c */
|
||||
/* Project: RTEMS 4.6.0pre1 / MCF5206Elite BSP */
|
||||
/* Version 1.2 */
|
||||
/* Date: 11/04/2002 */
|
||||
/* Author: Victor V. Vengerov */
|
||||
/* Copyright: Copyright (C) 2000 OKTET Ltd.,St.-Petersburg,Russia */
|
||||
/* */
|
||||
/* The license and distribution terms for this file may be */
|
||||
/* found in the file LICENSE in this distribution or at */
|
||||
/* http://www.rtems.org/license/LICENSE. */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Partially based on the code references which are named above. */
|
||||
/* Adaptions, modifications, enhancements and any recent parts of */
|
||||
/* the code are under the right of */
|
||||
/* */
|
||||
/* IPR Engineering, Dachauer Straße 38, D-80335 München */
|
||||
/* Copyright(C) 2003 */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* IPR Engineering makes no representation or warranties with */
|
||||
/* respect to the performance of this computer program, and */
|
||||
/* specifically disclaims any responsibility for any damages, */
|
||||
/* special or consequential, connected with the use of this program. */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Version history: 1.0 */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/mpc5200.h>
|
||||
#include <bsp/nvram.h>
|
||||
#include "m93cxx.h"
|
||||
|
||||
/*
|
||||
* Simple usec delay function using lower half of HARPO Time Base Register
|
||||
*/
|
||||
void wait_usec(unsigned long usec)
|
||||
{
|
||||
unsigned long start_count = 0, update_count;
|
||||
unsigned long delay_count;
|
||||
|
||||
if(TMBASE_CLOCK < 1000000)
|
||||
delay_count = (TMBASE_CLOCK * usec )/1000000;
|
||||
else
|
||||
delay_count = (TMBASE_CLOCK / 1000000) * usec;
|
||||
|
||||
TBL_READ(start_count);
|
||||
|
||||
update_count = start_count;
|
||||
|
||||
while((update_count - start_count) < delay_count)
|
||||
TBL_READ(update_count);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable M93Cxx chip-write
|
||||
*/
|
||||
static void m93cxx_enable_write()
|
||||
{
|
||||
uint32_t header, i;
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
header = M93C46_EWEN;
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
DISABLE_CHIP_SELECT;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable M93Cxx chip-write
|
||||
*/
|
||||
static void m93cxx_disable_write()
|
||||
{
|
||||
uint32_t header, i;
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
header = M93C46_EWDS;
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
DISABLE_CHIP_SELECT;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one byte from specified offset
|
||||
*/
|
||||
static uint8_t m93cxx_read_byte(uint32_t offset)
|
||||
{
|
||||
uint8_t byte2read;
|
||||
uint32_t header, tmp_offset, i;
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
uint8_t byte_recv = 0;
|
||||
#else
|
||||
uint32_t word_recv = 0;
|
||||
#endif
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
|
||||
header = M93C46_READ(offset);
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
GET_DATA_BYTE_SHIFT(byte_recv);
|
||||
|
||||
}
|
||||
|
||||
byte_recv >>= 1;
|
||||
|
||||
byte2read = byte_recv;
|
||||
|
||||
#else
|
||||
tmp_offset = offset/2;
|
||||
|
||||
header = M93C46_READ(tmp_offset);
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
GET_DATA_WORD_SHIFT(word_recv);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
word_recv >>= 1;
|
||||
|
||||
if(offset%2)
|
||||
{
|
||||
|
||||
byte2read = (uint8_t)((word_recv & 0xFF00) >> 8);
|
||||
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nbyte_read(o) = %x", byte2read);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
byte2read = (uint8_t)(word_recv & 0x00FF);
|
||||
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nbyte_read(e) = %x", byte2read);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DISABLE_CHIP_SELECT;
|
||||
|
||||
return byte2read;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write one byte to specified offset
|
||||
*/
|
||||
void m93cxx_write_byte(uint32_t offset, uint8_t byte2write)
|
||||
{
|
||||
uint32_t header, tmp_offset, i;
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
uint8_t byte_send;
|
||||
#else
|
||||
uint16_t word_send;
|
||||
#endif
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
#ifdef M93CXX_MODE_BYTE
|
||||
header = M93C46_WRITE(offset);
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
byte_send = byte2write;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
SET_DATA_BYTE_SHIFT(byte_send);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
if(offset%2)
|
||||
{
|
||||
|
||||
word_send = (uint16_t)m93cxx_read_byte(offset-1);
|
||||
word_send |= (uint16_t)(m93cxx_read_byte(offset) << 8);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
word_send = (uint16_t)m93cxx_read_byte(offset);
|
||||
word_send |= (uint16_t)(m93cxx_read_byte(offset + 1) << 8);
|
||||
|
||||
}
|
||||
|
||||
tmp_offset = offset/2;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
header = M93C46_WRITE(tmp_offset);
|
||||
|
||||
for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
|
||||
{
|
||||
|
||||
MASK_HEAD_SHIFT(header);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
if(offset%2)
|
||||
{
|
||||
|
||||
word_send = (word_send & 0x00FF) | ((uint16_t)(byte2write << 8));
|
||||
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nword_send = %x", word_send);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
word_send = (word_send & 0xFF00) | (uint16_t)byte2write;
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nword_send = %x", word_send);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
|
||||
SET_DATA_WORD_SHIFT(word_send);
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DO_CLOCK_CYCLE;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
}
|
||||
|
||||
DISABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
ENABLE_CHIP_SELECT;
|
||||
|
||||
WAIT(1);
|
||||
|
||||
CHECK_WRITE_BUSY;
|
||||
|
||||
#endif
|
||||
|
||||
WAIT(1);
|
||||
|
||||
DISABLE_CHIP_SELECT;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* nvram_driver_initialize --
|
||||
* Non-volatile memory device driver initialization.
|
||||
*/
|
||||
rtems_device_driver nvram_driver_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
/* enable PSC3_6/PSC3_7 as general purpose pins */
|
||||
mpc5200.gpiosen |= (GPIO_PSC3_6 | GPIO_PSC3_7);
|
||||
|
||||
/* PSC3_6/PSC3_7 has normal CMOS output */
|
||||
mpc5200.gpiosod &= ~(GPIO_PSC3_6 | GPIO_PSC3_7);
|
||||
|
||||
/* switch PSC3_6 (MC93C46 serial data in (D)) to low */
|
||||
mpc5200.gpiosdo &= ~GPIO_PSC3_6;
|
||||
|
||||
/* PSC3_6 is an output (MC93C46 serial data in (D)) and PSC3_7 (MC93C46 serial data out (Q)) is an input pin */
|
||||
mpc5200.gpiosdd |= GPIO_PSC3_6;
|
||||
mpc5200.gpiosdd &= ~GPIO_PSC3_7;
|
||||
|
||||
/* disable PSC3_8 interrupt capabilities */
|
||||
mpc5200.gpiosiie &= ~GPIO_PSC3_8;
|
||||
|
||||
/* enable PSC3_8 as general purpose pin */
|
||||
mpc5200.gpiosie |= GPIO_PSC3_8;
|
||||
|
||||
/* PSC3_8 has normal CMOS output */
|
||||
mpc5200.gpiosiod &= ~GPIO_PSC3_8;
|
||||
|
||||
/* switch PSC3_8 (MC93C46 chip select input (S)) to low (high activ) */
|
||||
mpc5200.gpiosido &= ~GPIO_PSC3_8;
|
||||
|
||||
/* PSC3_8 is an output (MC93C46 chip select input (S)) pin */
|
||||
mpc5200.gpiosidd |= GPIO_PSC3_8;
|
||||
|
||||
/* disable PSC3_9 interrupt capabilities */
|
||||
mpc5200.gpiowue &= ~GPIO_PSC3_9;
|
||||
|
||||
/* enable PSC3_9 as general purpose pins */
|
||||
mpc5200.gpiowe |= GPIO_PSC3_9;
|
||||
|
||||
/* PSC3_9 has normal CMOS output */
|
||||
mpc5200.gpiowod &= ~GPIO_PSC3_9;
|
||||
|
||||
/* switch PSC3_9 (MC93C46 serial clock (C)) to low */
|
||||
mpc5200.gpiowdo &= ~GPIO_PSC3_9;
|
||||
|
||||
/* PSC3_9 is an output (MC93C46 serial clock (C)) pin */
|
||||
mpc5200.gpiowdd |= GPIO_PSC3_9;
|
||||
|
||||
sc = rtems_io_register_name("/dev/nvram", major, 0);
|
||||
|
||||
if(sc != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
|
||||
errno = EIO;
|
||||
/*errno = ENODEV;*/
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
}
|
||||
else
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* nvram_driver_open --
|
||||
* Non-volatile memory device driver open primitive.
|
||||
*/
|
||||
rtems_device_driver nvram_driver_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* nvram_driver_close --
|
||||
* Non-volatile memory device driver close primitive.
|
||||
*/
|
||||
rtems_device_driver nvram_driver_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* nvram_driver_read --
|
||||
* Non-volatile memory device driver read primitive.
|
||||
*/
|
||||
rtems_device_driver nvram_driver_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
rtems_libio_rw_args_t *args = arg;
|
||||
uint32_t count, i;
|
||||
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nread count = %2x", (int)(args->count));
|
||||
printf("\nread offset = %2x", (int)(args->offset));
|
||||
#endif
|
||||
|
||||
if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE))
|
||||
{
|
||||
|
||||
args->bytes_moved = 0;
|
||||
errno = EINVAL;
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
}
|
||||
else
|
||||
count = args->count;
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
(args->buffer)[i] = m93cxx_read_byte((args->offset) + i);
|
||||
(args->bytes_moved) += 1;
|
||||
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* nvram_driver_write --
|
||||
* Non-volatile memory device driver write primitive.
|
||||
*/
|
||||
rtems_device_driver nvram_driver_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
rtems_libio_rw_args_t *args = arg;
|
||||
uint32_t count, i;
|
||||
|
||||
#ifdef NVRAM_DEBUG
|
||||
printf("\nwrite count = %2x", (int)(args->count));
|
||||
printf("\nwrite offset = %2x", (int)(args->offset));
|
||||
#endif
|
||||
|
||||
if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE))
|
||||
{
|
||||
|
||||
args->bytes_moved = 0;
|
||||
errno = EINVAL;
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
}
|
||||
|
||||
count = args->count;
|
||||
|
||||
m93cxx_enable_write();
|
||||
|
||||
WAIT(1);
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
m93cxx_write_byte((args->offset) + i, (args->buffer)[i]);
|
||||
(args->bytes_moved) += 1;
|
||||
|
||||
}
|
||||
|
||||
WAIT(1);
|
||||
|
||||
m93cxx_disable_write();
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
/*===============================================================*\
|
||||
| Project: RTEMS generic MPC5200 BSP |
|
||||
+-----------------------------------------------------------------+
|
||||
| Partially based on the code references which are named below. |
|
||||
| Adaptions, modifications, enhancements and any recent parts of |
|
||||
| the code are: |
|
||||
| Copyright (c) 2005 |
|
||||
| Embedded Brains GmbH |
|
||||
| Obere Lagerstr. 30 |
|
||||
| D-82178 Puchheim |
|
||||
| Germany |
|
||||
| rtems@embedded-brains.de |
|
||||
+-----------------------------------------------------------------+
|
||||
| The license and distribution terms for this file may be |
|
||||
| found in the file LICENSE in this distribution or at |
|
||||
| |
|
||||
| http://www.rtems.org/license/LICENSE. |
|
||||
| |
|
||||
+-----------------------------------------------------------------+
|
||||
| this file contains functions to implement a slice timer |
|
||||
\*===============================================================*/
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Module: slicetimer.c */
|
||||
/* Date: 07/17/2003 */
|
||||
/* Purpose: RTEMS MPC5x00 slicetimer driver */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Description: MPC5x00 slice timer routines for cyclic short time */
|
||||
/* trigger */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Code */
|
||||
/* References: Clock driver for PPC403 */
|
||||
/* Module: clock.c */
|
||||
/* Project: RTEMS 4.6.0pre1 / PPC403 BSP */
|
||||
/* Version 1.16 */
|
||||
/* Date: 2002/11/01 */
|
||||
/* Author(s) / Copyright(s): */
|
||||
/* */
|
||||
/* Author: Jay Monkman (jmonkman@frasca.com) */
|
||||
/* Copyright (C) 1998 by Frasca International, Inc. */
|
||||
/* */
|
||||
/* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c: */
|
||||
/* */
|
||||
/* Author: Andrew Bray <andy@i-cubed.co.uk> */
|
||||
/* */
|
||||
/* COPYRIGHT (c) 1995 by i-cubed ltd. */
|
||||
/* */
|
||||
/* To anyone who acknowledges that this file is provided "AS IS" */
|
||||
/* without any express or implied warranty: */
|
||||
/* permission to use, copy, modify, and distribute this file */
|
||||
/* for any purpose is hereby granted without fee, provided that */
|
||||
/* the above copyright notice and this notice appears in all */
|
||||
/* copies, and that the name of i-cubed limited not be used in */
|
||||
/* advertising or publicity pertaining to distribution of the */
|
||||
/* software without specific, written prior permission. */
|
||||
/* i-cubed limited makes no representations about the suitability */
|
||||
/* of this software for any purpose. */
|
||||
/* */
|
||||
/* Derived from c/src/lib/libcpu/hppa1.1/clock/clock.c: */
|
||||
/* */
|
||||
/* Modifications for deriving timer clock from cpu system clock by */
|
||||
/* Thomas Doerfler <td@imd.m.isar.de> */
|
||||
/* for these modifications: */
|
||||
/* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany. */
|
||||
/* */
|
||||
/* COPYRIGHT (c) 1989-1999. */
|
||||
/* On-Line Applications Research Corporation (OAR). */
|
||||
/* */
|
||||
/* The license and distribution terms for this file may be */
|
||||
/* found in the file LICENSE in this distribution or at */
|
||||
/* http://www.rtems.org/license/LICENSE. */
|
||||
/* */
|
||||
/* Modifications for PPC405GP by Dennis Ehlin */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Partially based on the code references which are named above. */
|
||||
/* Adaptions, modifications, enhancements and any recent parts of */
|
||||
/* the code are under the right of */
|
||||
/* */
|
||||
/* IPR Engineering, Dachauer Straße 38, D-80335 München */
|
||||
/* Copyright(C) 2003 */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* IPR Engineering makes no representation or warranties with */
|
||||
/* respect to the performance of this computer program, and */
|
||||
/* specifically disclaims any responsibility for any damages, */
|
||||
/* special or consequential, connected with the use of this program. */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Version history: 1.0 */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/clockdrv.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/mpc5200.h>
|
||||
#include <bsp/slicetimer.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint32_t value0 = 0;
|
||||
uint32_t value1 = 0;
|
||||
|
||||
/*
|
||||
* ISR Handlers
|
||||
*/
|
||||
void mpc5200_slt_isr(uint32_t slt_no)
|
||||
{
|
||||
uint32_t status;
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
status = slt->tsr;
|
||||
|
||||
if(status & SLT_TSR_ST)
|
||||
{
|
||||
|
||||
slt->tsr |= SLT_TSR_ST;
|
||||
|
||||
/*if(slt_no == SLT0)
|
||||
slt0_user_defined_handler */
|
||||
|
||||
/*if(slt_no == SLT1)
|
||||
slt1_user_defined_handler */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
rtems_isr mpc5200_slt0_isr(rtems_irq_hdl_param unused)
|
||||
{
|
||||
|
||||
mpc5200_slt_isr(SLT0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
rtems_isr mpc5200_slt1_isr(rtems_irq_hdl_param unused)
|
||||
{
|
||||
|
||||
mpc5200_slt_isr(SLT1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize MPC5x00 slt
|
||||
*/
|
||||
void mpc5200_init_slt(uint32_t slt_no)
|
||||
{
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
slt->tsr = SLT_TSR_ST;
|
||||
slt->cntrl = SLT_CNTRL_RW;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set MPC5x00 slt counter
|
||||
*/
|
||||
void mpc5200_set_slt_count(uint32_t slt_no)
|
||||
{
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
if(slt_no == SLT0)
|
||||
/* Calculate counter value 24 bit (must be greater than 255) => IPB_Clock=33MHz -> Int. every 7,75us - 508ms */
|
||||
if((SLT_TSR_COUNT(SLT0_INT_FREQUENCY) > 0xFF) && (SLT_TSR_COUNT(SLT0_INT_FREQUENCY) < 0x1000000))
|
||||
slt->tcr = SLT_TSR_COUNT(SLT0_INT_FREQUENCY);
|
||||
|
||||
if(slt_no == SLT1)
|
||||
/* Calculate counter value 24 bit (must be greater than 255) => IPB_Clock=33MHz -> Int. every 7,75us - 508ms */
|
||||
if((SLT_TSR_COUNT(SLT1_INT_FREQUENCY) > 0xFF) && (SLT_TSR_COUNT(SLT1_INT_FREQUENCY) < 0x1000000))
|
||||
slt->tcr = SLT_TSR_COUNT(SLT1_INT_FREQUENCY);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable MPC5x00 slt interrupt
|
||||
*/
|
||||
void mpc5200_enable_slt_int(uint32_t slt_no)
|
||||
{
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
slt->cntrl |= SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable MPC5x00 slt interrupt
|
||||
*/
|
||||
void mpc5200_disable_slt_int(uint32_t slt_no)
|
||||
{
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
slt->cntrl &= ~(SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check MPC5x00 slt status
|
||||
*/
|
||||
uint32_t mpc5200_check_slt_status(uint32_t slt_no)
|
||||
{
|
||||
struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]);
|
||||
|
||||
if(((slt->cntrl) & (SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN)) == (SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* switch MPC5x00 slt on
|
||||
*/
|
||||
static void sltOn(const rtems_irq_connect_data* irq)
|
||||
{
|
||||
uint32_t slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER0)
|
||||
slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER1)
|
||||
slt_no = 1;
|
||||
|
||||
mpc5200_set_slt_count((uint32_t)slt_no);
|
||||
mpc5200_enable_slt_int((uint32_t)slt_no);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* switch MPC5x00 slt off
|
||||
*/
|
||||
static void sltOff(const rtems_irq_connect_data* irq)
|
||||
{
|
||||
uint32_t slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER0)
|
||||
slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER1)
|
||||
slt_no = 1;
|
||||
|
||||
mpc5200_disable_slt_int((uint32_t)slt_no);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* get status of MPC5x00 slt
|
||||
*/
|
||||
static int sltIsOn(const rtems_irq_connect_data* irq)
|
||||
{
|
||||
uint32_t slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER0)
|
||||
slt_no = 0;
|
||||
|
||||
if((irq->name) == BSP_SIU_IRQ_SL_TIMER1)
|
||||
slt_no = 1;
|
||||
|
||||
if(mpc5200_check_slt_status(slt_no))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MPC5x00 slt0 irq connect data
|
||||
*/
|
||||
static rtems_irq_connect_data slt0_IrqData =
|
||||
{
|
||||
BSP_SIU_IRQ_SL_TIMER0,
|
||||
mpc5200_slt0_isr,
|
||||
(rtems_irq_hdl_param) NULL,
|
||||
(rtems_irq_enable)sltOn,
|
||||
(rtems_irq_disable)sltOff,
|
||||
(rtems_irq_is_enabled)sltIsOn
|
||||
};
|
||||
|
||||
/*
|
||||
* MPC5x00 slt1 irq connect data
|
||||
*/
|
||||
static rtems_irq_connect_data slt1_IrqData =
|
||||
{
|
||||
BSP_SIU_IRQ_SL_TIMER1,
|
||||
mpc5200_slt1_isr,
|
||||
(rtems_irq_hdl_param) NULL,
|
||||
(rtems_irq_enable)sltOn,
|
||||
(rtems_irq_disable)sltOff,
|
||||
(rtems_irq_is_enabled)sltIsOn
|
||||
};
|
||||
|
||||
/*
|
||||
* call MPC5x00 slt install routines
|
||||
*/
|
||||
void Install_slt(rtems_device_minor_number slt_no)
|
||||
{
|
||||
|
||||
mpc5200_init_slt((uint32_t)slt_no);
|
||||
mpc5200_set_slt_count((uint32_t)slt_no);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* MPC5x00 slt device driver initialize
|
||||
*/
|
||||
rtems_device_driver slt_initialize
|
||||
(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
|
||||
/* force minor according to definitions in bsp.h */
|
||||
if(USE_SLICETIMER_0)
|
||||
{
|
||||
|
||||
Install_slt(0);
|
||||
|
||||
if(!BSP_install_rtems_irq_handler(&slt0_IrqData))
|
||||
{
|
||||
|
||||
printk("Unable to connect PSC Irq handler\n");
|
||||
bsp_fatal(MPC5200_FATAL_SLICETIMER_0_IRQ_INSTALL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(USE_SLICETIMER_1)
|
||||
{
|
||||
|
||||
Install_slt(1);
|
||||
|
||||
if(!BSP_install_rtems_irq_handler(&slt1_IrqData))
|
||||
{
|
||||
|
||||
printk("Unable to connect PSC Irq handler\n");
|
||||
bsp_fatal(MPC5200_FATAL_SLICETIMER_1_IRQ_INSTALL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user