mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
412 lines
10 KiB
C
412 lines
10 KiB
C
/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* @file HWSEM0_Baremetal.c
|
|
* @author Khushboo Singh
|
|
* @email khushboo.singh@alifsemi.com
|
|
* @version V1.0.0
|
|
* @date 27-June-2022
|
|
* @brief TestApp to verify HWSEM interface using baremetal, no operating system.
|
|
* It locks the HWSEM, sends the message through UART and then unlocks.
|
|
* This application will run on two cores
|
|
* to demonstrate the working of the Hardware Semaphore.
|
|
* @bug None.
|
|
* @Note None.
|
|
******************************************************************************/
|
|
|
|
#include <RTE_Components.h>
|
|
#include CMSIS_device_header
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "Driver_USART.h"
|
|
#include <pinconf.h>
|
|
#include "Driver_HWSEM.h"
|
|
|
|
#if defined(RTE_Compiler_IO_STDOUT)
|
|
#include "retarget_stdout.h"
|
|
#endif /* RTE_Compiler_IO_STDOUT */
|
|
|
|
#ifdef M55_HP
|
|
const char * msg = "\nPrinting from M55_HP";
|
|
const char * acq_msg = "\nM55_HP acquiring the semaphore, printing 10 messages\r\n";
|
|
const char * rel_msg = "\nM55_HP releasing the semaphore\r\n\n";
|
|
#else
|
|
const char * msg = "\nPrinting from M55_HE";
|
|
const char * acq_msg = "\nM55_HE acquiring the semaphore, printing 10 messages\r\n";
|
|
const char * rel_msg = "\nM55_HE releasing the semaphore\r\n\n";
|
|
#endif
|
|
|
|
/* HWSEM Driver instance (HWSEM0-HWSEM15) */
|
|
#define HWSEM 0
|
|
#define HWSEM_CB_EVENT 1U << 0
|
|
|
|
/* Uart driver instance */
|
|
#define UART 4
|
|
|
|
#define UART_CB_TX_EVENT 1U << 0
|
|
#define UART_CB_RX_EVENT 1U << 1
|
|
#define UART_CB_RX_TIMEOUT 1U << 2
|
|
|
|
volatile uint32_t event_flags_uart = 0;
|
|
volatile uint32_t event_flags_hwsem = 0;
|
|
|
|
/* UART Driver */
|
|
extern ARM_DRIVER_USART ARM_Driver_USART_(UART);
|
|
static ARM_DRIVER_USART *USARTdrv = &ARM_Driver_USART_(UART);
|
|
|
|
/* HWSEM Driver */
|
|
extern ARM_DRIVER_HWSEM ARM_Driver_HWSEM_(HWSEM);
|
|
static ARM_DRIVER_HWSEM *HWSEMdrv = &ARM_Driver_HWSEM_(HWSEM);
|
|
|
|
/**
|
|
* @function static void myUART_callback(uint32_t event)
|
|
* @brief UART isr callabck
|
|
* @note none
|
|
* @param event: USART Event
|
|
* @retval none
|
|
*/
|
|
static void myUART_callback(uint32_t event)
|
|
{
|
|
if (event & ARM_USART_EVENT_SEND_COMPLETE)
|
|
{
|
|
/* Send Success */
|
|
event_flags_uart |= UART_CB_TX_EVENT;
|
|
}
|
|
|
|
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE)
|
|
{
|
|
/* Receive Success */
|
|
event_flags_uart |= UART_CB_RX_EVENT;
|
|
}
|
|
|
|
if (event & ARM_USART_EVENT_RX_TIMEOUT)
|
|
{
|
|
/* Receive Success with rx timeout */
|
|
event_flags_uart |= UART_CB_RX_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @function static void myHWSEM_callback(int32_t event, uint8_t sem_id)
|
|
* @brief HWSEM isr callabck
|
|
* @note none
|
|
* @param event: HWSEM Available Event
|
|
* @retval none
|
|
*/
|
|
static void myHWSEM_callback(int32_t event, uint8_t sem_id)
|
|
{
|
|
(void) sem_id;
|
|
|
|
if (event & HWSEM_AVAILABLE_CB_EVENT)
|
|
{
|
|
/* HWSEM available */
|
|
event_flags_hwsem |= HWSEM_CB_EVENT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @function static int32_t pinmux_setup(void)
|
|
* @brief pinmux setup
|
|
* @note none
|
|
* @param void
|
|
* @retval execution status
|
|
*/
|
|
static int32_t pinmux_setup(void)
|
|
{
|
|
int32_t ret;
|
|
|
|
/* UART4_RX_B */
|
|
ret = pinconf_set(PORT_12, PIN_1, PINMUX_ALTERNATE_FUNCTION_2, PADCTRL_READ_ENABLE);
|
|
|
|
if (ret)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
/* UART4_TX_B */
|
|
ret = pinconf_set(PORT_12, PIN_2, PINMUX_ALTERNATE_FUNCTION_2, 0);
|
|
|
|
if (ret)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @function void uart_hwsem_demo()
|
|
* @brief TestApp to verify HWSEM interface
|
|
* Get the lock, send message through UART
|
|
* and then unlock
|
|
* @note none
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void uart_hwsem_demo()
|
|
{
|
|
int32_t ret, len;
|
|
char uart_msg[30];
|
|
|
|
/* Initialize the HWSEM driver */
|
|
ret = HWSEMdrv->Initialize(myHWSEM_callback);
|
|
|
|
if (ret == ARM_DRIVER_ERROR)
|
|
{
|
|
printf("\r\n HWSEM initialization failed\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
/* Try to get the lock */
|
|
ret = HWSEMdrv->TryLock();
|
|
|
|
if (ret == ARM_DRIVER_ERROR)
|
|
{
|
|
printf("\r\n HWSEM lock failed\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
/* Loop until the lock becomes available */
|
|
while (ret == ARM_DRIVER_ERROR_BUSY)
|
|
{
|
|
/* Wait for the interrupt callback event */
|
|
while (!(event_flags_hwsem & HWSEM_CB_EVENT));
|
|
|
|
/* Reset the flag */
|
|
event_flags_hwsem &= ~HWSEM_CB_EVENT;
|
|
|
|
/* Try to acquire the lock again */
|
|
ret = HWSEMdrv->TryLock();
|
|
}
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\n HWSEM lock failed\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
/* Initialize UART driver */
|
|
ret = USARTdrv->Initialize(myUART_callback);
|
|
|
|
if (ret)
|
|
{
|
|
printf("\r\n Error in UART Initialize.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* Power up UART peripheral */
|
|
ret = USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
|
if (ret)
|
|
{
|
|
printf("\r\n Error in UART Power Up.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* Configure UART */
|
|
ret = USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
ARM_USART_DATA_BITS_8 |
|
|
ARM_USART_PARITY_NONE |
|
|
ARM_USART_STOP_BITS_1 |
|
|
ARM_USART_FLOW_CONTROL_NONE,
|
|
115200);
|
|
|
|
if (ret)
|
|
{
|
|
printf("\r\n Error in UART Control.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* Enable UART tx */
|
|
ret = USARTdrv->Control(ARM_USART_CONTROL_TX, 1);
|
|
|
|
if (ret)
|
|
{
|
|
printf("\r\n Error in UART Control.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
event_flags_uart &= ~UART_CB_TX_EVENT;
|
|
|
|
ret = USARTdrv->Send(acq_msg, strlen(acq_msg));
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\nError in UART Send.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* wait for event flag after UART call */
|
|
while (!(event_flags_uart & (UART_CB_TX_EVENT)));
|
|
|
|
/* Print 10 messages */
|
|
for (int iter = 1; iter <= 10; iter++)
|
|
{
|
|
event_flags_uart &= ~UART_CB_TX_EVENT;
|
|
|
|
len = sprintf(uart_msg, "%s %d\r\n", msg, iter);
|
|
|
|
ret = USARTdrv->Send(uart_msg, len);
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\nError in UART Send.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* wait for event flag after UART call */
|
|
while (!(event_flags_uart & (UART_CB_TX_EVENT)));
|
|
|
|
for(uint32_t count = 0; count < 5; count++)
|
|
sys_busy_loop_us(100000);
|
|
}
|
|
|
|
event_flags_uart &= ~UART_CB_TX_EVENT;
|
|
|
|
ret = USARTdrv->Send(rel_msg, strlen(rel_msg));
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\nError in UART Send.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* wait for event flag after UART call */
|
|
while (!(event_flags_uart & (UART_CB_TX_EVENT)));
|
|
|
|
ret = USARTdrv->PowerControl(ARM_POWER_OFF);
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\n Error in UART Power OFF.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
ret = USARTdrv->Uninitialize();
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\n Error in UART Uninitialize.\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* Unlock the hw semaphore */
|
|
ret = HWSEMdrv->Unlock();
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\nError in HWSEM Unlock.\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
for(uint32_t count = 0; count < 5; count++)
|
|
sys_busy_loop_us(100000);
|
|
}
|
|
|
|
error_uninitialize:
|
|
/* Uninitialize the HWSEM Driver */
|
|
HWSEMdrv->Uninitialize();
|
|
error_exit:
|
|
while(1);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int32_t ret;
|
|
ARM_DRIVER_VERSION version;
|
|
|
|
#if defined(RTE_Compiler_IO_STDOUT_User)
|
|
ret = stdout_init();
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
while(1)
|
|
{
|
|
}
|
|
}
|
|
#endif
|
|
|
|
version = HWSEMdrv->GetVersion();
|
|
printf("\r\n HWSEM version api:%X driver:%X...\r\n",version.api, version.drv);
|
|
|
|
/* Initialize the HWSEM Driver */
|
|
ret = HWSEMdrv->Initialize(myHWSEM_callback);
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\n HWSEM initialization failed\r\n");
|
|
goto error_exit;
|
|
}
|
|
|
|
/* Try to get the lock */
|
|
ret = HWSEMdrv->TryLock();
|
|
|
|
if (ret == ARM_DRIVER_ERROR)
|
|
{
|
|
printf("\r\n HWSEM lock failed\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
/* Loop until the lock becomes available */
|
|
while (ret == ARM_DRIVER_ERROR_BUSY)
|
|
{
|
|
/* Wait for the interrupt callback event */
|
|
while (!(event_flags_hwsem & HWSEM_CB_EVENT));
|
|
|
|
/* Reset the flag */
|
|
event_flags_hwsem &= ~HWSEM_CB_EVENT;
|
|
|
|
/* Try to acquire the lock again */
|
|
ret = HWSEMdrv->TryLock();
|
|
}
|
|
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
printf("\r\n HWSEM lock failed\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
ret = pinmux_setup();
|
|
|
|
if (ret != 0)
|
|
{
|
|
printf("\r\n Error in pinmux_setup.\r\n");
|
|
goto error_unlock;
|
|
}
|
|
|
|
/* Unlock the hw semaphore */
|
|
ret = HWSEMdrv->Unlock();
|
|
|
|
if (ret == ARM_DRIVER_ERROR)
|
|
{
|
|
printf("\r\n HWSEM unlock failed\r\n");
|
|
goto error_uninitialize;
|
|
}
|
|
|
|
/* Uninitialize the HWSEM Driver */
|
|
HWSEMdrv->Uninitialize();
|
|
|
|
/* Print UART messages under hwsem lock */
|
|
uart_hwsem_demo();
|
|
|
|
return 0;
|
|
|
|
error_unlock:
|
|
HWSEMdrv->Unlock();
|
|
error_uninitialize:
|
|
HWSEMdrv->Uninitialize();
|
|
error_exit:
|
|
while (1);
|
|
}
|