mirror of
https://github.com/dimoniche/Moyka.git
synced 2026-01-30 01:43:30 +03:00
221 lines
9.3 KiB
C
221 lines
9.3 KiB
C
/*
|
|
*********************************************************************************************************
|
|
* uC/OS-II
|
|
* The Real-Time Kernel
|
|
*
|
|
*
|
|
* (c) Copyright 1992-2007, Micrium, Weston, FL
|
|
* All Rights Reserved
|
|
*
|
|
* Generic ARM Port
|
|
* DCC Communication
|
|
*
|
|
* File : OS_DCC.C
|
|
* Version : V1.82
|
|
*
|
|
* For : ARM7 or ARM9
|
|
* Mode : ARM or Thumb
|
|
* Toolchain : IAR's EWARM V4.40a and higher
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#include <ucos_ii.h>
|
|
/* This directive suppresses warnings for non-... */
|
|
#pragma diag_suppress=Pe940 /* ...void functions with no return values. */
|
|
|
|
#if OS_CPU_ARM_DCC_EN > 0
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* CONSTANTS
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
#define OS_DCC_OP_READ_U32 0x01000000
|
|
#define OS_DCC_OP_READ_U16 0x02000000
|
|
#define OS_DCC_OP_READ_U8 0x04000000
|
|
#define OS_DCC_OP_GET_CAPS 0x08000000
|
|
#define OS_DCC_OP_WRITE_U32 0x10000000
|
|
#define OS_DCC_OP_WRITE_U16 0x20000000
|
|
#define OS_DCC_OP_WRITE_U8 0x40000000
|
|
#define OS_DCC_OP_ODD_ADDR 0x80000000
|
|
#define OS_DCC_OP_COMMAND 0x00000001
|
|
|
|
#define OS_DCC_COMM_CTRL_RD 0x00000001
|
|
#define OS_DCC_COMM_CTRL_WR 0x00000002
|
|
|
|
#define OS_DCC_SIGNATURE 0x91CA0000
|
|
#define OS_DCC_CONFIG 0x00000077
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* LOCAL VARIABLES
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static INT32U OSDCC_Cmd;
|
|
static INT32U OSDCC_Addr;
|
|
static INT32U OSDCC_ItemCnt;
|
|
static INT32U OSDCC_Data;
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* OSDCC_ReadCtrl()
|
|
*
|
|
* Description: This function retrieves data from the comms control register.
|
|
*
|
|
* Arguments : none
|
|
*
|
|
* Returns : The contents of the comms control register
|
|
*
|
|
* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents
|
|
* of the comms control register in R0. Thus, the function does not contain an
|
|
* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the
|
|
* top of this file, is used to suppress the warning that normally results from non-
|
|
* void functions lacking return statements.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static __arm INT32U OSDCC_ReadCtrl (void)
|
|
{
|
|
__asm("mrc P14,0,R0,C0,C0");
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* OSDCC_Read()
|
|
*
|
|
* Description: This function retrieves data from the comms data read register.
|
|
*
|
|
* Arguments : none
|
|
*
|
|
* Returns : The contents of the comms data read register
|
|
*
|
|
* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents
|
|
* of the comms data read register in R0. Thus, the function does not contain an
|
|
* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the
|
|
* top of this file, is used to suppress the warning that normally results from non-
|
|
* void functions lacking return statements.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static __arm INT32U OSDCC_Read (void)
|
|
{
|
|
__asm("mrc P14,0,R0,C1,C0");
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* OSDCC_Write()
|
|
*
|
|
* Description: This function places data in the comms data write register.
|
|
*
|
|
* Arguments : none
|
|
*
|
|
* Returns : none
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
static __arm void OSDCC_Write (INT32U data)
|
|
{
|
|
__asm("mcr P14,0,R0,C1,C0");
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* OSDCC_Handler()
|
|
*
|
|
* Description: This function reads commands from the DCC comms data read register. Data may be
|
|
* transferred to or from memory based on those commands.
|
|
*
|
|
* Arguments : none
|
|
*
|
|
* Returns : none
|
|
*
|
|
* Notes : 1) This function should be called periodically. If OS_CPU_ARM_DCC_EN is '1', this
|
|
* function will be called from both the idle task hook and the tick interrupt hook.
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
void OSDCC_Handler (void)
|
|
{
|
|
INT32U reg_val;
|
|
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
|
|
OS_CPU_SR cpu_sr = 0;
|
|
#endif
|
|
|
|
|
|
OS_ENTER_CRITICAL(); /* Disable interrupts */
|
|
|
|
/* Check for the presence of new data */
|
|
if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_RD) != 0) {
|
|
reg_val = OSDCC_Read(); /* Read the new data */
|
|
|
|
if ((reg_val & OS_DCC_OP_COMMAND) != 0) { /* Determine whether a command has been received */
|
|
OSDCC_Cmd = reg_val;
|
|
/* Check for an odd address in the next operation */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_ODD_ADDR) != 0) {
|
|
OSDCC_Addr |= 1;
|
|
}
|
|
/* If data will be read, adjust OSDCC_ItemCnt */
|
|
if ((OSDCC_Cmd & (OS_DCC_OP_READ_U32 | OS_DCC_OP_READ_U16 | OS_DCC_OP_READ_U8
|
|
| OS_DCC_OP_GET_CAPS)) != 0) {
|
|
OSDCC_ItemCnt = (OSDCC_Cmd >> 2) & 0xffff;
|
|
} else { /* Data will be written; initialize OSDCC_Data */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) {
|
|
OSDCC_Data |= (OSDCC_Cmd << 14) & 0xffff0000;
|
|
} else {
|
|
OSDCC_Data = (OSDCC_Cmd >> 2) & 0xffff;
|
|
}
|
|
/* Write a single byte */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U8) != 0) {
|
|
*(INT8U *)OSDCC_Addr = OSDCC_Data;
|
|
OSDCC_Addr += 1;
|
|
}
|
|
/* Write two bytes */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U16) != 0) {
|
|
*(INT16U *)OSDCC_Addr = OSDCC_Data;
|
|
OSDCC_Addr += 2;
|
|
}
|
|
/* Write four bytes */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) {
|
|
*(INT32U *)OSDCC_Addr =OSDCC_Data;
|
|
OSDCC_Addr += 4;
|
|
}
|
|
}
|
|
OS_EXIT_CRITICAL();
|
|
return;
|
|
}
|
|
OSDCC_Addr = reg_val; /* An address was received; OSDCC_Addr is updated */
|
|
}
|
|
/* Determine whether data must be read */
|
|
if (OSDCC_ItemCnt != 0) {
|
|
/* Confirm that the comms data write register... */
|
|
/* ...is free from the processor point of view */
|
|
if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_WR) == 0) {
|
|
reg_val = (OS_DCC_CONFIG | OS_DCC_SIGNATURE);
|
|
/* Read a single byte */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_READ_U8) != 0) {
|
|
reg_val = *(INT8U *)OSDCC_Addr;
|
|
OSDCC_Addr += 1;
|
|
}
|
|
/* Read two bytes */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_READ_U16) != 0) {
|
|
reg_val = *(INT16U *)OSDCC_Addr;
|
|
OSDCC_Addr += 2;
|
|
}
|
|
/* Read four bytes */
|
|
if ((OSDCC_Cmd & OS_DCC_OP_READ_U32) != 0) {
|
|
reg_val = *(INT32U *)OSDCC_Addr;
|
|
OSDCC_Addr += 4;
|
|
}
|
|
|
|
OSDCC_Write(reg_val); /* Place data in the comms data write register */
|
|
OSDCC_ItemCnt--; /* Decrement the number of items to be read */
|
|
}
|
|
}
|
|
OS_EXIT_CRITICAL();
|
|
}
|
|
|
|
#endif
|