1 /***************************************************************************/ /**
2 * @file sl_si91x_bus.c
3 *******************************************************************************
4 * # License
5 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6 *******************************************************************************
7 *
8 * SPDX-License-Identifier: Zlib
9 *
10 * The licensor of this software is Silicon Laboratories Inc.
11 *
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software
22 * in a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 * 2. Altered source versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *
28 ******************************************************************************/
29 #include "sl_status.h"
30 #include "sl_si91x_types.h"
31 #include "system_si91x.h"
32 #include "rsi_m4.h"
33 #include "sl_constants.h"
34 #include "cmsis_os2.h"
35 #include "rsi_power_save.h"
36 #include "sl_si91x_host_interface.h"
37 #include <stddef.h>
38 #include <stdlib.h>
39 #include "sl_rsi_utility.h"
40
41 rsi_m4ta_desc_t tx_desc[2];
42 rsi_m4ta_desc_t rx_desc[2];
43 sl_si91x_buffer_queue_t sli_ahb_bus_rx_queue;
44
45 /******************************************************
46 * * Function Declarations
47 * ******************************************************/
48 sl_status_t sli_si91x_submit_rx_pkt(void);
49 void sli_submit_rx_buffer(void);
50 void sli_si91x_raise_pkt_pending_interrupt_to_ta(void);
51
sl_si91x_bus_init(void)52 sl_status_t sl_si91x_bus_init(void)
53 {
54 sli_ahb_bus_rx_queue.head = NULL;
55 sli_ahb_bus_rx_queue.tail = NULL;
56 mask_ta_interrupt(TA_RSI_BUFFER_FULL_CLEAR_EVENT);
57 return RSI_SUCCESS;
58 }
59
60 /**
61 * @fn sl_status_t sli_si91x_submit_rx_pkt(void)
62 * @brief Submit receiver packets
63 * @param[in] None
64 * @return 0 - Success \n
65 * Non-Zero - Failure
66 */
67 sl_wifi_buffer_t *rx_pkt_buffer;
sli_si91x_submit_rx_pkt(void)68 sl_status_t sli_si91x_submit_rx_pkt(void)
69 {
70 sl_status_t status;
71 uint16_t data_length = 0;
72 sl_si91x_packet_t *packet;
73 int8_t *pkt_buffer = NULL;
74
75 if (M4SS_P2P_INTR_SET_REG & RX_BUFFER_VALID) {
76 return -2;
77 }
78
79 // Allocate packet to receive packet from module
80 status = sl_si91x_host_allocate_buffer(&rx_pkt_buffer, SL_WIFI_RX_FRAME_BUFFER, 1616, 1000);
81 if (status != SL_STATUS_OK) {
82 SL_DEBUG_LOG("\r\n HEAP EXHAUSTED DURING ALLOCATION \r\n");
83 BREAKPOINT();
84 }
85
86 packet = sl_si91x_host_get_buffer_data(rx_pkt_buffer, 0, &data_length);
87 pkt_buffer = (int8_t *)&packet->desc[0];
88
89 // Fill source address in the TX descriptors
90 rx_desc[0].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)pkt_buffer);
91
92 // Fill source address in the TX descriptors
93 rx_desc[0].length = 16;
94
95 // Fill source address in the TX descriptors
96 rx_desc[1].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)(pkt_buffer + 16));
97
98 // Fill source address in the TX descriptors
99 rx_desc[1].length = 1600;
100
101 raise_m4_to_ta_interrupt(RX_BUFFER_VALID);
102
103 return SL_STATUS_OK;
104 }
105
sl_si91x_bus_read_frame(sl_wifi_buffer_t ** buffer)106 sl_status_t sl_si91x_bus_read_frame(sl_wifi_buffer_t **buffer)
107 {
108 sl_status_t status = sli_si91x_remove_from_queue(&sli_ahb_bus_rx_queue, buffer);
109 VERIFY_STATUS_AND_RETURN(status);
110
111 return SL_STATUS_OK;
112 }
113
114 /**
115 * @fn sl_status_t sl_si91x_bus_write_frame(sl_si91x_packet_t *packet,
116 * uint8_t *payloadparam, uint16_t size_param)
117 * @brief writing a command to the module.
118 * @param[in] payloadparam - pointer to the command payload parameter structure
119 * @param[in] size_param - size of the payload for the command
120 * @return 0 - Success \n
121 * Negative Value - Failure
122 */
123
sl_si91x_bus_write_frame(sl_si91x_packet_t * packet,const uint8_t * payloadparam,uint16_t size_param)124 sl_status_t sl_si91x_bus_write_frame(sl_si91x_packet_t *packet, const uint8_t *payloadparam, uint16_t size_param)
125 {
126
127 // Fill source address in the TX descriptors
128 tx_desc[0].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)&packet->desc[0]);
129
130 // Fill source address in the TX descriptors
131 tx_desc[0].length = 16;
132
133 // Fill source address in the TX descriptors
134 tx_desc[1].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)payloadparam);
135
136 // Fill source address in the TX descriptors
137 tx_desc[1].length = size_param;
138
139 sli_si91x_raise_pkt_pending_interrupt_to_ta();
140
141 return SL_STATUS_OK;
142 }
143
sli_submit_rx_buffer(void)144 void sli_submit_rx_buffer(void)
145 {
146 mask_ta_interrupt(RX_PKT_TRANSFER_DONE_INTERRUPT);
147
148 //! submit to NWP submit packet
149 sli_si91x_submit_rx_pkt();
150
151 unmask_ta_interrupt(RX_PKT_TRANSFER_DONE_INTERRUPT);
152 }
153
154 /**
155 * @fn void rsi_update_tx_dma_desc(uint8 skip_dma_valid)
156 * @brief This function updates the TX DMA descriptor address
157 * @param[in] skip_dma_valid
158 * @param[out] none
159 * @return none
160 * @section description
161 * This function updates the TX DMA descriptor address
162 *
163 *
164 */
165
rsi_update_tx_dma_desc(uint8_t skip_dma_valid)166 void rsi_update_tx_dma_desc(uint8_t skip_dma_valid)
167 {
168 if (!skip_dma_valid
169 #ifdef SLI_SI91X_MCU_COMMON_FLASH_MODE
170 && !(M4_ULP_SLP_STATUS_REG & MCU_ULP_WAKEUP)
171 #endif
172 ) {
173 while (M4_TX_DMA_DESC_REG & DMA_DESC_REG_VALID)
174 ;
175 }
176 M4_TX_DMA_DESC_REG = (uint32_t)&tx_desc;
177 }
178
179 /*==============================================*/
180 /**
181 * @fn void rsi_update_rx_dma_desc()
182 * @brief This function updates the RX DMA descriptor address
183 * @param[in] none
184 * @param[out] none
185 * @return none
186 * @section description
187 * This function updates the RX DMA descriptor address
188 *
189 *
190 */
rsi_update_rx_dma_desc(void)191 void rsi_update_rx_dma_desc(void)
192 {
193 M4_RX_DMA_DESC_REG = (uint32_t)&rx_desc;
194 }
195
sli_si91x_config_m4_dma_desc_on_reset(void)196 void sli_si91x_config_m4_dma_desc_on_reset(void)
197 {
198
199 //! Wait for NWP to wakeup and should be in bootloader
200 while (!(P2P_STATUS_REG & TA_is_active))
201 ;
202 SL_DEBUG_LOG("\r\nTA is in active state\r\n");
203 //! TBD Need to address why soft reset expecting delay
204 osDelay(100);
205 //! Update M4 Tx and Rx DMA descriptors
206 M4_TX_DMA_DESC_REG = (uint32_t)&tx_desc;
207 M4_RX_DMA_DESC_REG = (uint32_t)&rx_desc;
208 }
209