1 /*
2  * Copyright (c) 2014 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <lk/err.h>
9 #include <lk/debug.h>
10 #include <target.h>
11 #include <lk/compiler.h>
12 #include <dev/gpio.h>
13 #include <platform/gpio.h>
14 
15 #include <platform/lpc.h>
16 
17 /* needs to be defined for the lpcopen drivers */
18 const uint32_t OscRateIn = 12000000;
19 const uint32_t RTCOscRateIn = 32768;
20 
21 /* The System initialization code is called prior to the application and
22    initializes the board for run-time operation. Board initialization
23    includes clock setup and default pin muxing configuration. */
24 
25 /*****************************************************************************
26  * Private types/enumerations/variables
27  ****************************************************************************/
28 
29 /* IOCON setup table, only items that need changing from their default pin
30    state are in this table. */
31 STATIC const PINMUX_GRP_T ioconSetup[] = {
32     /* LEDs */
33     {0, 25,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_25-BREAK_CTRL-RED (low enable) */
34     {0, 3,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_3-SCT1_OUT4-GRN */
35     {1, 1,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_1-BREAK_STS1-BLUE */
36 
37     /* QEI, motor controller, I2C, CAN */
38     {0, 2,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_2-QEI-SCT0_IN */
39     {0, 30,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_30-QEI-SCT0_IN */
40     {0, 17,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_17-QEI-SCT0_IN */
41     {0, 25,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_25-BREAK_CTRL-RED */
42     {1, 1,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_1-BREAK_STS1-BLUE */
43     {0, 23,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_23-I2C_SDA */
44     {0, 22,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_22-I2C_SCL */
45     {0, 11,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_11-CAN_RD */
46     {0, 31,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_31-CAN_TD */
47 
48     /* ADC */
49     {1, 3,   (IOCON_MODE_INACT)},                           /* PIO1_3-ADC1_5 */
50     {0, 4,   (IOCON_MODE_INACT)},                           /* PIO0_4-ADC0_4 */
51     {0, 5,   (IOCON_MODE_INACT)},                           /* PIO0_5-ADC0_3 */
52     {0, 7,   (IOCON_MODE_INACT)},                           /* PIO0_7-ADC0_1 */
53     {0, 8,   (IOCON_MODE_INACT)},                           /* PIO0_8-ADC0_0 */
54     {0, 9,   (IOCON_MODE_INACT)},                           /* PIO0_9-ADC1_1 */
55     {0, 10,  (IOCON_MODE_INACT)},                           /* PIO0_10-ADC1_2 */
56 
57     /* Joystick */
58     {1, 4,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_4-JOY_U */
59     {1, 5,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_5-JOY_C */
60     {1, 6,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_6-JOY_D */
61     {1, 7,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_7-JOY_R */
62     {1, 8,   (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO1_8-JOY_L */
63 
64     /* UART */
65     {0, 13,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_13-ISP_RX */
66     {0, 18,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},        /* PIO0_18-ISP_TX */
67     {0, 11,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},
68     {0, 31,  (IOCON_MODE_INACT | IOCON_DIGMODE_EN)},
69 
70     /* USB related */
71     {1, 11,  (IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN)}, /* PIO1_11-ISP_1 (VBUS) */
72 };
73 
74 /* SWIM pin assignment definitions for pin assignment/muxing */
75 typedef struct {
76     uint16_t assignedpin : 9;       /* Function and mode */
77     uint16_t port : 2;              /* Pin port */
78     uint16_t pin : 5;               /* Pin number */
79 } SWM_GRP_T;
80 
81 /* Pin muxing table, only items that need changing from their default pin
82    state are in this table. */
83 STATIC const SWM_GRP_T swmSetup[] = {
84     /* USB related */
85     {(uint16_t) SWM_USB_VBUS_I, 1, 11},     /* PIO1_11-ISP_1-AIN_CTRL */
86 
87     /* UART */
88     {(uint16_t) SWM_UART0_RXD_I, 0, 13},        /* PIO0_13-ISP_RX */
89     {(uint16_t) SWM_UART0_TXD_O, 0, 18},        /* PIO0_18-ISP_TX */
90 };
91 
92 /* Setup fixed pin functions (GPIOs are fixed) */
93 /* No fixed pins except GPIOs */
94 #define PINENABLE0_VAL 0xFFFFFFFF
95 
96 /* No fixed pins except GPIOs */
97 #define PINENABLE1_VAL 0x00FFFFFF
98 
99 /* Sets up system pin muxing */
Board_SetupMuxing(void)100 void Board_SetupMuxing(void) {
101     /* Enable SWM and IOCON clocks */
102     Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
103     Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
104     Chip_SYSCTL_PeriphReset(RESET_IOCON);
105 
106     /* IOCON setup */
107     Chip_IOCON_SetPinMuxing(LPC_IOCON, ioconSetup, sizeof(ioconSetup) / sizeof(PINMUX_GRP_T));
108 
109     /* SWM assignable pin setup */
110     for (uint i = 0; i < (sizeof(swmSetup) / sizeof(SWM_GRP_T)); i++) {
111         Chip_SWM_MovablePortPinAssign((CHIP_SWM_PIN_MOVABLE_T) swmSetup[i].assignedpin,
112                                       swmSetup[i].port, swmSetup[i].pin);
113     }
114 
115     /* SWM fixed pin setup */
116     //  LPC_SWM->PINENABLE[0] = PINENABLE0_VAL;
117     //  LPC_SWM->PINENABLE[1] = PINENABLE1_VAL;
118 
119     /* Note SWM and IOCON clocks are left on */
120 }
121 
122 /* Initialize debug output via UART for board */
Board_Debug_Init(void)123 void Board_Debug_Init(void) {
124     /* Disables pullups/pulldowns and enable digital mode */
125     Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 13, (IOCON_MODE_INACT | IOCON_DIGMODE_EN));
126     Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_MODE_INACT | IOCON_DIGMODE_EN));
127 
128     /* UART signal muxing via SWM */
129     Chip_SWM_MovablePortPinAssign(SWM_UART0_RXD_I, 0, 13);
130     Chip_SWM_MovablePortPinAssign(SWM_UART0_TXD_O, 0, 18);
131 }
132 
133 #define MAXLEDS 3
134 static const uint8_t ledpins[MAXLEDS] = {25, 3, 1};
135 static const uint8_t ledports[MAXLEDS] = {0, 0, 1};
136 
137 /* Initializes board LED(s) */
Board_LED_Init(void)138 static void Board_LED_Init(void) {
139     int idx;
140 
141     Chip_GPIO_Init(LPC_GPIO);
142 
143     for (idx = 0; idx < MAXLEDS; idx++) {
144         /* Set the GPIO as output with initial state off (high) */
145         Chip_GPIO_SetPinDIROutput(LPC_GPIO, ledports[idx], ledpins[idx]);
146         Chip_GPIO_SetPinState(LPC_GPIO, ledports[idx], ledpins[idx], true);
147     }
148 }
149 
150 /* Sets the state of a board LED to on or off */
Board_LED_Set(uint8_t LEDNumber,bool On)151 void Board_LED_Set(uint8_t LEDNumber, bool On) {
152     if (LEDNumber < MAXLEDS) {
153         /* Toggle state, low is on, high is off */
154         Chip_GPIO_SetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber], !On);
155     }
156 }
157 
158 /* Returns the current state of a board LED */
Board_LED_Test(uint8_t LEDNumber)159 bool Board_LED_Test(uint8_t LEDNumber) {
160     bool state = false;
161 
162     if (LEDNumber < MAXLEDS) {
163         state = !Chip_GPIO_GetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]);
164     }
165 
166     return state;
167 }
168 
169 /* Toggles the current state of a board LED */
Board_LED_Toggle(uint8_t LEDNumber)170 void Board_LED_Toggle(uint8_t LEDNumber) {
171     Chip_GPIO_SetPinToggle(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]);
172 }
173 
174 
target_early_init(void)175 void target_early_init(void) {
176     Board_SetupMuxing();
177 
178     Board_Debug_Init();
179     Board_LED_Init();
180 }
181 
target_init(void)182 void target_init(void) {
183 }
184 
target_set_debug_led(unsigned int led,bool on)185 void target_set_debug_led(unsigned int led, bool on) {
186     if (led < 3)
187         Board_LED_Set(led, on);
188 }
189 
190 // vim: set ts=4 sw=4 expandtab:
191