Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers syscon.c Source File

syscon.c

00001 /**
00002  * @file    syscon.c
00003  * @brief   System Controller serial interface
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2008-2019, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include <ctype.h>                                // character functions
00023 #include <string.h>                               // string and memory functions
00024 
00025 #include "IO_Config_Override.h"                   // I/O pin definitions
00026 
00027 #include "syscon.h"                               // SCC interface
00028 
00029 // SYSCON timing
00030 #define TSUH            2                         // Clock setup and hold
00031 #define TCLK            2                         // Clock high time
00032 
00033 // Misc defines
00034 #define GPIOIMSK        0x003F                    // GPIOI SCC bit mask
00035 
00036 /*----------------------------------------------------------------------------
00037   System Controller serial interface
00038  *----------------------------------------------------------------------------*/
00039 static void Sleepns(uint32_t cycles)
00040 {
00041     volatile uint32_t i = cycles;        // fudge factor to give approximate 1 ns
00042 
00043     while (i > 0) {
00044         i--;
00045     }
00046 }
00047 /*----------------------------------------------------------------------------
00048   System Controller 32bit register read (16uS)
00049  *----------------------------------------------------------------------------*/
00050 void syscon_readreg(unsigned int addr, unsigned int *din)
00051 {
00052     volatile unsigned int loop, data;
00053 
00054     // Write the 12bit address value
00055     for(loop = 0; loop < 12; loop++)
00056     {
00057         if (addr & 0x800)
00058         {
00059             LPC_GPIO->SET[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00060         }
00061         else
00062         {
00063             LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00064         }
00065         Sleepns(TCLK);
00066         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00067         Sleepns(TCLK);
00068         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00069         // Set next address bit
00070         addr = (addr << 1) & 0xFFF;
00071     }
00072 
00073     LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00074     Sleepns(TCLK);
00075 
00076     // Config load
00077     LPC_GPIO->SET[PIN_SCC_LOAD_PORT] = PIN_SCC_LOAD;
00078     Sleepns(TCLK * 2);
00079     LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00080     Sleepns(TCLK * 3);
00081     LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00082     LPC_GPIO->CLR[PIN_SCC_LOAD_PORT] = PIN_SCC_LOAD;
00083     Sleepns(TCLK * 2);
00084 
00085     // Read the 32bit data value
00086     data = 0;
00087 
00088     for (loop = 0; loop < 4; loop++)
00089     {
00090         data = (data >> 8) & 0x00FFFFFF;
00091         Sleepns(TCLK);
00092         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00093         Sleepns(TCLK * 2);
00094         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00095         Sleepns(TCLK);
00096         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (24 - PIN_SCC_DATAOUT_BIT));
00097         Sleepns(TCLK);
00098         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00099         Sleepns(TCLK * 2);
00100         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00101         Sleepns(TCLK);
00102         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (25 - PIN_SCC_DATAOUT_BIT));
00103         Sleepns(TCLK);
00104         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00105         Sleepns(TCLK * 2);
00106         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00107         Sleepns(TCLK);
00108         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (26 - PIN_SCC_DATAOUT_BIT));
00109         Sleepns(TCLK);
00110         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00111         Sleepns(TCLK * 2);
00112         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00113         Sleepns(TCLK);
00114         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (27 - PIN_SCC_DATAOUT_BIT));
00115         Sleepns(TCLK);
00116         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00117         Sleepns(TCLK * 2);
00118         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00119         Sleepns(TCLK);
00120         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (28 - PIN_SCC_DATAOUT_BIT));
00121         Sleepns(TCLK);
00122         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00123         Sleepns(TCLK * 2);
00124         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00125         Sleepns(TCLK);
00126         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (29 - PIN_SCC_DATAOUT_BIT));
00127         Sleepns(TCLK);
00128         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00129         Sleepns(TCLK * 2);
00130         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00131         Sleepns(TCLK);
00132         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (30 - PIN_SCC_DATAOUT_BIT));
00133         Sleepns(TCLK);
00134         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00135         Sleepns(TCLK * 2);
00136         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00137         Sleepns(TCLK);
00138         data |= ((LPC_GPIO->PIN[PIN_SCC_DATAOUT_PORT] & PIN_SCC_DATAOUT) << (31 - PIN_SCC_DATAOUT_BIT));
00139         Sleepns(TCLK);
00140     }
00141 
00142     // Return the 32bit data value
00143     *din = data;
00144 }
00145 
00146 /*----------------------------------------------------------------------------
00147   System Controller 32bit register write (20uS)
00148  *----------------------------------------------------------------------------*/
00149 void syscon_writereg(unsigned int addr, unsigned int dout)
00150 {
00151     volatile unsigned int loop, data;
00152 
00153     // Set write enable
00154     LPC_GPIO->SET[PIN_SCC_WNR_PORT] = PIN_SCC_WNR;
00155 
00156     // Write the 12bit address value
00157     for(loop = 0; loop < 12; loop++)
00158     {
00159         if (addr & 0x800)
00160         {
00161             LPC_GPIO->SET[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00162         }
00163         else
00164         {
00165             LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00166         }
00167         Sleepns(TCLK);
00168         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00169         Sleepns(TCLK);
00170         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00171         // Set next address bit
00172         addr = (addr << 1) & 0xFFF;
00173     }
00174 
00175     LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00176     Sleepns(TCLK);
00177 
00178     // Write the 32bit data value
00179     data  = dout;
00180     for (loop = 0; loop < 32; loop++)
00181     {
00182         if (data & 0x80000000)
00183         {
00184             LPC_GPIO->SET[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00185         }
00186         else
00187         {
00188             LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00189         }
00190         Sleepns(TCLK);
00191         LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00192         Sleepns(TCLK);
00193         LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00194         // Set next address bit
00195         data = (data << 1);
00196         Sleepns(TCLK);
00197     }
00198 
00199     LPC_GPIO->CLR[PIN_SCC_DATAIN_PORT] = PIN_SCC_DATAIN;
00200     Sleepns(TCLK);
00201 
00202     // Config load
00203     LPC_GPIO->SET[PIN_SCC_LOAD_PORT] = PIN_SCC_LOAD;
00204     Sleepns(TCLK * 2);
00205     LPC_GPIO->SET[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00206     Sleepns(TCLK * 3);
00207     LPC_GPIO->CLR[PIN_SCC_CLK_PORT] = PIN_SCC_CLK;
00208     LPC_GPIO->CLR[PIN_SCC_LOAD_PORT] = PIN_SCC_LOAD;
00209     Sleepns(TCLK * 2);
00210 
00211     // Set to read
00212     LPC_GPIO->CLR[PIN_SCC_WNR_PORT] = PIN_SCC_WNR;
00213 }
00214 
00215 // end of syscon.c