1 /*
2 * Copyright (c) 2020, Texas Instruments Incorporated
3 * Copyright (c) 2020 Linaro Ltd.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/kernel.h>
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/gpio.h>
11
12 #include <driverlib/cpu.h>
13
14 #define GPIO_PORT DT_NODELABEL(gpio0)
15 #define DIO8_PIN 8
16 #define DIO9_PIN 9
17 #define DIO10_PIN 10
18 #define DIO20_PIN 20
19
20
21 /*
22 * ======== CC1352R1_LAUNCHXL_sendExtFlashByte ========
23 */
CC1352R1_LAUNCHXL_sendExtFlashByte(const struct device * dev,uint8_t byte)24 void CC1352R1_LAUNCHXL_sendExtFlashByte(const struct device *dev,
25 uint8_t byte)
26 {
27 uint8_t i;
28
29 /* SPI Flash CS */
30 gpio_pin_set(dev, DIO20_PIN, 0);
31
32 for (i = 0; i < 8; i++) {
33 gpio_pin_set(dev, DIO10_PIN, 0); /* SPI Flash CLK */
34
35 /* SPI Flash MOSI */
36 gpio_pin_set(dev, DIO9_PIN, (byte >> (7 - i)) & 0x01);
37 gpio_pin_set(dev, DIO10_PIN, 1); /* SPI Flash CLK */
38
39 /*
40 * Waste a few cycles to keep the CLK high for at
41 * least 45% of the period.
42 * 3 cycles per loop: 8 loops @ 48 Mhz = 0.5 us.
43 */
44 CPUdelay(8);
45 }
46
47 gpio_pin_set(dev, DIO10_PIN, 0); /* CLK */
48 gpio_pin_set(dev, DIO20_PIN, 1); /* CS */
49
50 /*
51 * Keep CS high at least 40 us
52 * 3 cycles per loop: 700 loops @ 48 Mhz ~= 44 us
53 */
54 CPUdelay(700);
55 }
56
57 /*
58 * ======== CC1352R1_LAUNCHXL_wakeUpExtFlash ========
59 */
CC1352R1_LAUNCHXL_wakeUpExtFlash(const struct device * dev)60 void CC1352R1_LAUNCHXL_wakeUpExtFlash(const struct device *dev)
61 {
62 /*
63 * To wake up we need to toggle the chip select at
64 * least 20 ns and ten wait at least 35 us.
65 */
66
67 /* Toggle chip select for ~20ns to wake ext. flash */
68 gpio_pin_set(dev, DIO20_PIN, 0);
69 /* 3 cycles per loop: 1 loop @ 48 Mhz ~= 62 ns */
70 CPUdelay(1);
71 gpio_pin_set(dev, DIO20_PIN, 1);
72 /* 3 cycles per loop: 560 loops @ 48 Mhz ~= 35 us */
73 CPUdelay(560);
74 }
75
76 /*
77 * ======== CC1352R1_LAUNCHXL_shutDownExtFlash ========
78 */
CC1352R1_LAUNCHXL_shutDownExtFlash(void)79 void CC1352R1_LAUNCHXL_shutDownExtFlash(void)
80 {
81 const struct device *dev;
82 uint8_t extFlashShutdown = 0xB9;
83
84 dev = DEVICE_DT_GET(GPIO_PORT);
85
86 if (!device_is_ready(dev)) {
87 printk("%s: device not ready.\n", dev->name);
88 return;
89 }
90
91 /* Set SPI Flash CS pin as output */
92 gpio_pin_configure(dev, DIO20_PIN, GPIO_OUTPUT);
93 /* Set SPI Flash CLK pin as output */
94 gpio_pin_configure(dev, DIO10_PIN, GPIO_OUTPUT);
95 /* Set SPI Flash MOSI pin as output */
96 gpio_pin_configure(dev, DIO9_PIN, GPIO_OUTPUT);
97 /* Set SPI Flash MISO pin as input */
98 gpio_pin_configure(dev, DIO8_PIN, GPIO_INPUT | GPIO_PULL_DOWN);
99
100 /*
101 * To be sure we are putting the flash into sleep and not waking it,
102 * we first have to make a wake up call
103 */
104 CC1352R1_LAUNCHXL_wakeUpExtFlash(dev);
105
106 CC1352R1_LAUNCHXL_sendExtFlashByte(dev, extFlashShutdown);
107 }
108