mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
170:19eb464bc2be
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /* mbed Microcontroller Library
<> 149:156823d33999 2 * Copyright (c) 2013 Nordic Semiconductor
<> 149:156823d33999 3 *
<> 149:156823d33999 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 149:156823d33999 5 * you may not use this file except in compliance with the License.
<> 149:156823d33999 6 * You may obtain a copy of the License at
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 149:156823d33999 9 *
<> 149:156823d33999 10 * Unless required by applicable law or agreed to in writing, software
<> 149:156823d33999 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 149:156823d33999 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 149:156823d33999 13 * See the License for the specific language governing permissions and
<> 149:156823d33999 14 * limitations under the License.
<> 149:156823d33999 15 */
<> 149:156823d33999 16 //#include <math.h>
<> 149:156823d33999 17 #include "mbed_assert.h"
<> 149:156823d33999 18 #include "spi_api.h"
<> 149:156823d33999 19 #include "cmsis.h"
<> 149:156823d33999 20 #include "pinmap.h"
<> 149:156823d33999 21 #include "mbed_error.h"
<> 149:156823d33999 22
<> 149:156823d33999 23 #define SPIS_MESSAGE_SIZE 1
<> 149:156823d33999 24 volatile uint8_t m_tx_buf[SPIS_MESSAGE_SIZE] = {0};
<> 149:156823d33999 25 volatile uint8_t m_rx_buf[SPIS_MESSAGE_SIZE] = {0};
<> 149:156823d33999 26
<> 149:156823d33999 27 // nRF51822's I2C_0 and SPI_0 (I2C_1, SPI_1 and SPIS1) share the same address.
<> 149:156823d33999 28 // They can't be used at the same time. So we use two global variable to track the usage.
<> 149:156823d33999 29 // See nRF51822 address information at nRF51822_PS v2.0.pdf - Table 15 Peripheral instance reference
<> 149:156823d33999 30 extern volatile i2c_spi_peripheral_t i2c0_spi0_peripheral; // from i2c_api.c
<> 149:156823d33999 31 extern volatile i2c_spi_peripheral_t i2c1_spi1_peripheral;
<> 149:156823d33999 32
<> 149:156823d33999 33 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
<> 149:156823d33999 34 {
<> 149:156823d33999 35 SPIName spi = SPI_0;
<> 149:156823d33999 36
<> 149:156823d33999 37 if (ssel == NC && i2c0_spi0_peripheral.usage == I2C_SPI_PERIPHERAL_FOR_SPI &&
<> 149:156823d33999 38 i2c0_spi0_peripheral.sda_mosi == (uint8_t)mosi &&
<> 149:156823d33999 39 i2c0_spi0_peripheral.scl_miso == (uint8_t)miso &&
<> 149:156823d33999 40 i2c0_spi0_peripheral.sclk == (uint8_t)sclk) {
<> 149:156823d33999 41 // The SPI with the same pins is already initialized
<> 149:156823d33999 42 spi = SPI_0;
<> 149:156823d33999 43 obj->peripheral = 0x1;
<> 149:156823d33999 44 } else if (ssel == NC && i2c1_spi1_peripheral.usage == I2C_SPI_PERIPHERAL_FOR_SPI &&
<> 149:156823d33999 45 i2c1_spi1_peripheral.sda_mosi == (uint8_t)mosi &&
<> 149:156823d33999 46 i2c1_spi1_peripheral.scl_miso == (uint8_t)miso &&
<> 149:156823d33999 47 i2c1_spi1_peripheral.sclk == (uint8_t)sclk) {
<> 149:156823d33999 48 // The SPI with the same pins is already initialized
<> 149:156823d33999 49 spi = SPI_1;
<> 149:156823d33999 50 obj->peripheral = 0x2;
<> 149:156823d33999 51 } else if (i2c1_spi1_peripheral.usage == 0) {
<> 149:156823d33999 52 i2c1_spi1_peripheral.usage = I2C_SPI_PERIPHERAL_FOR_SPI;
<> 149:156823d33999 53 i2c1_spi1_peripheral.sda_mosi = (uint8_t)mosi;
<> 149:156823d33999 54 i2c1_spi1_peripheral.scl_miso = (uint8_t)miso;
<> 149:156823d33999 55 i2c1_spi1_peripheral.sclk = (uint8_t)sclk;
<> 149:156823d33999 56
<> 149:156823d33999 57 spi = SPI_1;
<> 149:156823d33999 58 obj->peripheral = 0x2;
<> 149:156823d33999 59 } else if (i2c0_spi0_peripheral.usage == 0) {
<> 149:156823d33999 60 i2c0_spi0_peripheral.usage = I2C_SPI_PERIPHERAL_FOR_SPI;
<> 149:156823d33999 61 i2c0_spi0_peripheral.sda_mosi = (uint8_t)mosi;
<> 149:156823d33999 62 i2c0_spi0_peripheral.scl_miso = (uint8_t)miso;
<> 149:156823d33999 63 i2c0_spi0_peripheral.sclk = (uint8_t)sclk;
<> 149:156823d33999 64
<> 149:156823d33999 65 spi = SPI_0;
<> 149:156823d33999 66 obj->peripheral = 0x1;
<> 149:156823d33999 67 } else {
<> 149:156823d33999 68 // No available peripheral
<> 149:156823d33999 69 error("No available SPI");
<> 149:156823d33999 70 }
<> 149:156823d33999 71
<> 149:156823d33999 72 if (ssel==NC) {
<> 149:156823d33999 73 obj->spi = (NRF_SPI_Type *)spi;
<> 149:156823d33999 74 obj->spis = (NRF_SPIS_Type *)NC;
<> 149:156823d33999 75 } else {
<> 149:156823d33999 76 obj->spi = (NRF_SPI_Type *)NC;
<> 149:156823d33999 77 obj->spis = (NRF_SPIS_Type *)spi;
<> 149:156823d33999 78 }
<> 149:156823d33999 79
<> 149:156823d33999 80 // pin out the spi pins
<> 149:156823d33999 81 if (ssel != NC) { //slave
<> 149:156823d33999 82 obj->spis->POWER = 0;
<> 149:156823d33999 83 obj->spis->POWER = 1;
<> 149:156823d33999 84
<> 149:156823d33999 85 NRF_GPIO->PIN_CNF[mosi] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 86 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 87 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 88 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 89 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 90 NRF_GPIO->PIN_CNF[miso] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 91 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 92 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 93 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 94 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 95 NRF_GPIO->PIN_CNF[sclk] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 96 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 97 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 98 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 99 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 100 NRF_GPIO->PIN_CNF[ssel] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 101 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 102 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 103 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 104 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 105
<> 149:156823d33999 106 obj->spis->PSELMOSI = mosi;
<> 149:156823d33999 107 obj->spis->PSELMISO = miso;
<> 149:156823d33999 108 obj->spis->PSELSCK = sclk;
<> 149:156823d33999 109 obj->spis->PSELCSN = ssel;
<> 149:156823d33999 110
<> 149:156823d33999 111 obj->spis->EVENTS_END = 0;
<> 149:156823d33999 112 obj->spis->EVENTS_ACQUIRED = 0;
<> 149:156823d33999 113 obj->spis->MAXRX = SPIS_MESSAGE_SIZE;
<> 149:156823d33999 114 obj->spis->MAXTX = SPIS_MESSAGE_SIZE;
<> 149:156823d33999 115 obj->spis->TXDPTR = (uint32_t)&m_tx_buf[0];
<> 149:156823d33999 116 obj->spis->RXDPTR = (uint32_t)&m_rx_buf[0];
<> 149:156823d33999 117 obj->spis->SHORTS = (SPIS_SHORTS_END_ACQUIRE_Enabled << SPIS_SHORTS_END_ACQUIRE_Pos);
<> 149:156823d33999 118
<> 149:156823d33999 119 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
<> 149:156823d33999 120 } else { //master
<> 149:156823d33999 121 obj->spi->POWER = 0;
<> 149:156823d33999 122 obj->spi->POWER = 1;
<> 149:156823d33999 123
<> 149:156823d33999 124 //NRF_GPIO->DIR |= (1<<mosi);
<> 149:156823d33999 125 NRF_GPIO->PIN_CNF[mosi] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 126 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 127 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 128 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 129 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 130 obj->spi->PSELMOSI = mosi;
<> 149:156823d33999 131
<> 149:156823d33999 132 NRF_GPIO->PIN_CNF[sclk] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 133 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 134 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 135 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 136 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 137 obj->spi->PSELSCK = sclk;
<> 149:156823d33999 138
<> 149:156823d33999 139 //NRF_GPIO->DIR &= ~(1<<miso);
<> 149:156823d33999 140 NRF_GPIO->PIN_CNF[miso] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
<> 149:156823d33999 141 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 149:156823d33999 142 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 149:156823d33999 143 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 149:156823d33999 144 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
<> 149:156823d33999 145
<> 149:156823d33999 146 obj->spi->PSELMISO = miso;
<> 149:156823d33999 147
<> 149:156823d33999 148 obj->spi->EVENTS_READY = 0U;
<> 149:156823d33999 149
<> 149:156823d33999 150 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
<> 149:156823d33999 151 spi_frequency(obj, 1000000);
<> 149:156823d33999 152 }
<> 149:156823d33999 153 }
<> 149:156823d33999 154
<> 149:156823d33999 155 void spi_free(spi_t *obj)
<> 149:156823d33999 156 {
<> 149:156823d33999 157 }
<> 149:156823d33999 158
<> 149:156823d33999 159 static inline void spi_disable(spi_t *obj, int slave)
<> 149:156823d33999 160 {
<> 149:156823d33999 161 if (slave) {
<> 149:156823d33999 162 obj->spis->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos);
<> 149:156823d33999 163 } else {
<> 149:156823d33999 164 obj->spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
<> 149:156823d33999 165 }
<> 149:156823d33999 166 }
<> 149:156823d33999 167
<> 149:156823d33999 168 static inline void spi_enable(spi_t *obj, int slave)
<> 149:156823d33999 169 {
<> 149:156823d33999 170 if (slave) {
<> 149:156823d33999 171 obj->spis->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);
<> 149:156823d33999 172 } else {
<> 149:156823d33999 173 obj->spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
<> 149:156823d33999 174 }
<> 149:156823d33999 175 }
<> 149:156823d33999 176
<> 149:156823d33999 177 void spi_format(spi_t *obj, int bits, int mode, int slave)
<> 149:156823d33999 178 {
<> 149:156823d33999 179 uint32_t config_mode = 0;
<> 149:156823d33999 180 spi_disable(obj, slave);
<> 149:156823d33999 181
<> 149:156823d33999 182 if (bits != 8) {
<> 149:156823d33999 183 error("Only 8bits SPI supported");
<> 149:156823d33999 184 }
<> 149:156823d33999 185
<> 149:156823d33999 186 switch (mode) {
<> 149:156823d33999 187 case 0:
<> 149:156823d33999 188 config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
<> 149:156823d33999 189 break;
<> 149:156823d33999 190 case 1:
<> 149:156823d33999 191 config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
<> 149:156823d33999 192 break;
<> 149:156823d33999 193 case 2:
<> 149:156823d33999 194 config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
<> 149:156823d33999 195 break;
<> 149:156823d33999 196 case 3:
<> 149:156823d33999 197 config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
<> 149:156823d33999 198 break;
<> 149:156823d33999 199 default:
<> 149:156823d33999 200 error("SPI format error");
<> 149:156823d33999 201 break;
<> 149:156823d33999 202 }
<> 149:156823d33999 203 //default to msb first
<> 149:156823d33999 204 if (slave) {
<> 149:156823d33999 205 obj->spis->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos));
<> 149:156823d33999 206 } else {
<> 149:156823d33999 207 obj->spi->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos));
<> 149:156823d33999 208 }
<> 149:156823d33999 209
<> 149:156823d33999 210 spi_enable(obj, slave);
<> 149:156823d33999 211 }
<> 149:156823d33999 212
<> 149:156823d33999 213 void spi_frequency(spi_t *obj, int hz)
<> 149:156823d33999 214 {
<> 149:156823d33999 215 if ((int)obj->spi==NC) {
<> 149:156823d33999 216 return;
<> 149:156823d33999 217 }
<> 149:156823d33999 218 spi_disable(obj, 0);
<> 149:156823d33999 219
<> 149:156823d33999 220 if (hz<250000) { //125Kbps
<> 149:156823d33999 221 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K125;
<> 149:156823d33999 222 } else if (hz<500000) { //250Kbps
<> 149:156823d33999 223 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K250;
<> 149:156823d33999 224 } else if (hz<1000000) { //500Kbps
<> 149:156823d33999 225 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K500;
<> 149:156823d33999 226 } else if (hz<2000000) { //1Mbps
<> 149:156823d33999 227 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M1;
<> 149:156823d33999 228 } else if (hz<4000000) { //2Mbps
<> 149:156823d33999 229 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M2;
<> 149:156823d33999 230 } else if (hz<8000000) { //4Mbps
<> 149:156823d33999 231 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M4;
<> 149:156823d33999 232 } else { //8Mbps
<> 149:156823d33999 233 obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M8;
<> 149:156823d33999 234 }
<> 149:156823d33999 235
<> 149:156823d33999 236 spi_enable(obj, 0);
<> 149:156823d33999 237 }
<> 149:156823d33999 238
<> 149:156823d33999 239 static inline int spi_readable(spi_t *obj)
<> 149:156823d33999 240 {
<> 149:156823d33999 241 return (obj->spi->EVENTS_READY == 1);
<> 149:156823d33999 242 }
<> 149:156823d33999 243
<> 149:156823d33999 244 static inline int spi_writeable(spi_t *obj)
<> 149:156823d33999 245 {
<> 149:156823d33999 246 return (obj->spi->EVENTS_READY == 0);
<> 149:156823d33999 247 }
<> 149:156823d33999 248
<> 149:156823d33999 249 static inline int spi_read(spi_t *obj)
<> 149:156823d33999 250 {
<> 149:156823d33999 251 while (!spi_readable(obj)) {
<> 149:156823d33999 252 }
<> 149:156823d33999 253
<> 149:156823d33999 254 obj->spi->EVENTS_READY = 0;
<> 149:156823d33999 255 return (int)obj->spi->RXD;
<> 149:156823d33999 256 }
<> 149:156823d33999 257
<> 149:156823d33999 258 int spi_master_write(spi_t *obj, int value)
<> 149:156823d33999 259 {
<> 149:156823d33999 260 while (!spi_writeable(obj)) {
<> 149:156823d33999 261 }
<> 149:156823d33999 262 obj->spi->TXD = (uint32_t)value;
<> 149:156823d33999 263 return spi_read(obj);
<> 149:156823d33999 264 }
<> 149:156823d33999 265
Kojto 170:19eb464bc2be 266 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
Kojto 170:19eb464bc2be 267 char *rx_buffer, int rx_length, char write_fill) {
AnnaBridge 167:e84263d55307 268 int total = (tx_length > rx_length) ? tx_length : rx_length;
AnnaBridge 167:e84263d55307 269
AnnaBridge 167:e84263d55307 270 for (int i = 0; i < total; i++) {
Kojto 170:19eb464bc2be 271 char out = (i < tx_length) ? tx_buffer[i] : write_fill;
AnnaBridge 167:e84263d55307 272 char in = spi_master_write(obj, out);
AnnaBridge 167:e84263d55307 273 if (i < rx_length) {
AnnaBridge 167:e84263d55307 274 rx_buffer[i] = in;
AnnaBridge 167:e84263d55307 275 }
AnnaBridge 167:e84263d55307 276 }
AnnaBridge 167:e84263d55307 277
AnnaBridge 167:e84263d55307 278 return total;
AnnaBridge 167:e84263d55307 279 }
AnnaBridge 167:e84263d55307 280
<> 149:156823d33999 281 //static inline int spis_writeable(spi_t *obj) {
<> 149:156823d33999 282 // return (obj->spis->EVENTS_ACQUIRED==1);
<> 149:156823d33999 283 //}
<> 149:156823d33999 284
<> 149:156823d33999 285 int spi_slave_receive(spi_t *obj)
<> 149:156823d33999 286 {
<> 149:156823d33999 287 return obj->spis->EVENTS_END;
<> 149:156823d33999 288 }
<> 149:156823d33999 289
<> 149:156823d33999 290 int spi_slave_read(spi_t *obj)
<> 149:156823d33999 291 {
<> 149:156823d33999 292 return m_rx_buf[0];
<> 149:156823d33999 293 }
<> 149:156823d33999 294
<> 149:156823d33999 295 void spi_slave_write(spi_t *obj, int value)
<> 149:156823d33999 296 {
<> 149:156823d33999 297 m_tx_buf[0] = value & 0xFF;
<> 149:156823d33999 298 obj->spis->TASKS_RELEASE = 1;
<> 149:156823d33999 299 obj->spis->EVENTS_ACQUIRED = 0;
<> 149:156823d33999 300 obj->spis->EVENTS_END = 0;
<> 149:156823d33999 301 }