I am learning about deep sleep mode so I downloaded the following project to see an examples of deep sleep. The code was written for PIC18F46J50 however I have PIC18F87J11. I was looking at the code and I noticed the following configuration settings relating that PIC.
Deep Sleep BOR:
DSBOREN = OFF
Disabled
DSBOREN = ON
Enabled
Deep Sleep Watchdog Timer:
DSWDTEN = OFF
Disabled
DSWDTEN = ON
Enabled
Deep Sleep Watchdog Postscaler:
DSWDTPS = 2
1:2 (2.1 ms)
DSWDTPS = 8
1:8 (8.3 ms)
DSWDTPS = 32
1:32 (33 ms)
DSWDTPS = 128
1:128 (132 ms)
DSWDTPS = 512
1:512 (528 ms)
DSWDTPS = 2048
1:2,048 (2.1 seconds)
DSWDTPS = 8192
1:8,192 (8.5 seconds)
DSWDTPS = K32
1:32,768 (34 seconds)
DSWDTPS = K131
1:131,072 (135 seconds)
DSWDTPS = K524
1:524,288 (9 minutes)
DSWDTPS = M2
1:2,097,152 (36 minutes)
DSWDTPS = M8
1:8,388,608 (2.4 hours)
DSWDTPS = M33
1:33,554,432 (9.6 hours)
DSWDTPS = M134
1:134,217,728 (38.5 hours)
DSWDTPS = M536
1:536,870,912 (6.4 days)
DSWDTPS = G2
1:2,147,483,648 (25.7 days)
However, on PIC18F87J11 I do not see similar configurations. Does that mean I can not put the PIC into deep sleep?
/*
** Author: Dan1138
** Date: 2011-AUGUST-14
** File: main.c
** Target: PIC18F46J50
** OS: Win7, 64-bit
** MPLAB: 8.73a
** Compiler: C18v3.40
** Description:
** Sleep mode example that toggles RA0
** output bit on wake up from sleep.
**
** If deep sleep mode is working RA0 changes every 8.5 seconds.
** If sleep mode is working RA0 changes every 1.024 seconds.
*/
#include <p18cxxx.h>
#pragma config WDTEN = OFF /* Disabled - Controlled by SWDTEN bit */
#pragma config PLLDIV = 2 /* Divide by 2 (8 MHz oscillator input) */
#pragma config STVREN = ON /* Reset on stack overflow/underflow enabled */
#pragma config XINST = OFF /* Instruction set extension and Indexed Addressing mode disabled (Legacy mode) */
#pragma config CPUDIV = OSC1 /* No CPU system clock divide */
#pragma config CP0 = OFF /* Program memory is not code-protected */
#pragma config OSC = INTOSCPLL /* INTOSC with PLL enabled(S/W control), port function on RA6 and RA7, INTOSCPLL used by USB */
#pragma config T1DIG = OFF /* Secondary Oscillator clock source may not be selected */
#pragma config LPT1OSC = OFF /* Timer1 oscillator configured for higher power operation */
#pragma config FCMEN = OFF /* Fail-Safe Clock Monitor disabled */
#pragma config IESO = OFF /* Two-Speed Start-up disabled */
#pragma config WDTPS = 1 /* 1:1 */
#pragma config DSWDTOSC = INTOSCREF /* DSWDT uses INTOSC/INTRC as reference clock */
#pragma config RTCOSC = T1OSCREF /* RTCC uses T1OSC/T1CKI as reference clock */
#pragma config DSBOREN = OFF /* Zero-Power BOR disabled in Deep Sleep (does not affect operation in non-Deep Sleep modes) */
#pragma config DSWDTEN = ON /* Deep Sleep Watchdog Timer Enabled */
#pragma config DSWDTPS = 8192 /* 1:8,192 (8.5 seconds) */
#pragma config IOL1WAY = OFF /* The IOLOCK bit (PPSCON<0>) can be set and cleared as needed */
#pragma config MSSP7B_EN = MSK7 /* 7 Bit address masking */
#pragma config WPFP = PAGE_31 /* Write Protect Program Flash Page 31 */
#pragma config WPEND = PAGE_WPFP /* Write/Erase protect Flash Memory pages starting at page WPFP[5:0] */
#pragma config WPCFG = OFF /* Write/Erase Protection of last page Disabled */
#pragma config WPDIS = OFF /* WPFP[5:0], WPEND, and WPCFG bits ignored */
void
InterruptHandlerHigh (
void
);
void
InterruptHandlerLow (
void
);
/*
** High priority interrupt vector
*/
#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
_asm goto InterruptHandlerHigh _endasm
}
/*
** Low priority interrupt vector
*/
#pragma code InterruptVectorLow=0x18
void
InterruptVectorLow (void)
{
_asm goto InterruptHandlerLow _endasm
}
/* return to the default code section */
#pragma code
/*
** High priority interrupt handlers
*/
#pragma interrupt InterruptHandlerHigh
void
InterruptHandlerHigh (
void
)
{
/* hang here if we get an unhandled interrupt */
for( ; ; );
}
/*
** Low priority interrupt handlers
*/
#pragma interruptlow InterruptHandlerLow
void
InterruptHandlerLow (
void
)
{
/* hang here if we get an unhandled interrupt */
for( ; ; );
}
/*
** Initialize this PIC hardware
*/
void
PICInit(
void
)
{
OSCCON = 0x70; /* Use Primary clock source selected by config bits */
OSCTUNEbits.PLLEN = 1; /* Use PLL to make Fosc clock run at 48MHz */
ANCON0 = 0xFF; /* Turn off all analog inputs */
ANCON1 = 0x1F;
CM1CON = 0x00;
CM2CON = 0x00;
/* UnLock Registers */
EECON2 = 0x55;
EECON2 = 0xAA;
PPSCONbits.IOLOCK = 0;
/* Unlock ends */
RPINR1 = 0x1F; /* INT1 <= Not mapped */
RPINR2 = 0x1F; /* INT2 <= Not mapped */
RPINR3 = 0x1F; /* INT3 <= Not mapped */
RPINR4 = 0x1F; /* T0CLKI <= Not mapped */
RPINR6 = 0x1F; /* T3CKI <= Not mapped */
RPINR7 = 0x1F; /* CCP1 <= Not mapped */
RPINR8 = 0x1F; /* CCP2 <= Not mapped */
RPINR12 = 0x1F; /* T1G <= Not mapped */
RPINR13 = 0x1F; /* T3G <= Not mapped */
RPINR16 = 0x1F; /* RX2/DT2 <= Not mapped */
RPINR17 = 0x1F; /* CK2 <= Not mapped */
RPINR21 = 0x1F; /* SDI2 <= Not mapped */
RPINR22 = 0x1F; /* SCK2IN <= Not mapped */
RPINR23 = 0x1F; /* SS2IN <= Not mapped */
RPINR24 = 0x1F; /* FLT0 <= Not mapped */
RPOR0 = 0x00; /* unmap all outputs */
RPOR1 = 0x00;
RPOR2 = 0x00;
RPOR3 = 0x00;
RPOR4 = 0x00;
RPOR5 = 0x00;
RPOR6 = 0x00;
RPOR7 = 0x00;
RPOR8 = 0x00;
RPOR9 = 0x00;
RPOR10 = 0x00;
RPOR11 = 0x00;
RPOR12 = 0x00;
RPOR13 = 0x00;
RPOR17 = 0x00;
RPOR18 = 0x00;
RPOR19 = 0x00;
RPOR20 = 0x00;
RPOR21 = 0x00;
RPOR22 = 0x00;
RPOR23 = 0x00;
RPOR24 = 0x00;
/* Lock Registers */
EECON2 = 0x55;
EECON2 = 0xAA;
PPSCONbits.IOLOCK = 1;
/* Lock Registers ends */
TRISA = 0xFF; /*RA0-7 are digital inputs */
TRISB = 0xFF; /*RB0-7 are digital inputs */
TRISC = 0xFF; /*RC0-7 are digital inputs */
TRISD = 0xFF; /*RD0-7 are digital inputs */
TRISE = 0xFF; /*RE0-2 are digital inputs */
RCONbits.IPEN = 1; /* Enable High/Low interrupt priority model. */
if(WDTCONbits.DS)
{
/* handle stuff specific to wake up from deep sleep */
/* Make RA0 an out bit */
TRISA &= ~0x01;
LATA &= ~0x01;
}
WDTCONbits.DS = 0;
if(DSCONLbits.RELEASE)
{
/* restore LATA state from before deep sleep wakup */
TRISA &= ~0x01;
LATA = PORTA;
/* clear deep sleep I/O config lock out */
DSCONLbits.RELEASE = 0;
}
else
{
/* Make RA0 an out bit */
TRISA &= ~0x01;
LATA &= ~0x01;
}
}
void
main(
void
)
{
/* Disable interrupts */
INTCONbits.GIEH = 0;
/* Initial this hardware */
PICInit();
ClrWdt();
/* toggle output bit RA0 on wake from deep sleep */
LATA ^= 0x01;
/* prepare to enter deep sleep */
INTCONbits.GIEH = 0; /* disable interrupts */
WDTCONbits.SWDTEN = 1; /* turn on the watch dog timer */
DSCONLbits.ULPWDIS = 1; /* disable ULP wake up */
DSCONLbits.DSBOR = 0; /* disable Brownout wake up */
DSCONHbits.DSULPEN = 0; /* disable ULP pull up */
DSCONHbits.RTCWDIS = 1; /* disable RTCC wake up */
WDTCONbits.REGSLP = 1; /* turn off core regulator for deep sleep */
OSCCONbits.IDLEN = 0; /* enter sleep mode, not idle */
/* Check the generated code, the SLEEP instruction
** must be the next instruction after the DSEN bit
** is set in the DSCONH register.
** If not you must use inline assembly or call
** an assembly function to enter deep sleep
*/
/* go to deep sleep, DSWDT or reset is the only way out in this demo */
DSCONHbits.DSEN = 1;
Sleep();
/* wait here forever */
/* do a conventional sleep mode if we did not enter deep sleep */
for( ; ; )
{
if(!DSCONHbits.DSEN)
{
Sleep(); /* go to sleep */
Nop(); /* in general it's best to do nothing for one or */
Nop(); /* two instruction cycles after a WDT wake up */
/* toggle output bit RA0 on wake from sleep */
LATA ^= 0x01;
}
}
}
Related
I just started programming a STM32 and generated a code with CubeMX for an SPI communcation with a gyroscope (L3GD20)
I have a problem with the HAL_SPI commands.
I first try to read the WHO_AM_I register which return a good response (0xD4)
Then I tried to do the same with CTRL_REG1 register and it was still good by returning (0x07).
But if I try to get both of them one after the other, the HAL_SPI_Receive keeps sending the data of the first HAL_SPI_Transmit of the code...
Tried to give it other buffers but still didn't work.
Here is the part of the code I'm intersted in :
uint8_t txData[8],rxData[8]; //Buffers for the first read.
uint8_t rBuffer[8]; //Buffer for the second read.
/*...............................................................
*...............................................................
*...............................................................
*/...............................................................
txData[0] = ADDR_WHO_AM_I | 0x80;
HAL_SPI_Transmit(&hspi2, txData, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, rxData, 1, HAL_MAX_DELAY); //Returns the right value
HAL_Delay(1000);
txData[0] = ADDR_CTRL_REG1 | 0x80;
HAL_Delay(500);
HAL_SPI_Transmit(&hspi2, txData, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, rBuffer, 1, HAL_MAX_DELAY); //Returns the same value...
HAL_Delay(1000);
PS : I also would like to know more about HAL_SPI_TransmitReceive if possible, how should I use it to perform the same task ? (Reading 1 byte from different registers).
There is the full code too :
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// Gyro Definitions
#define ADDR_WHO_AM_I 0x0f
#define ADDR_CTRL_REG1 0x20
#define ADDR_CTRL_REG2 0x21
#define ADDR_CTRL_REG3 0x22
#define ADDR_CTRL_REG4 0x23
#define ADDR_CTRL_REG5 0x24
#define ADDR_OUT_TEMP 0x26
#define ADDR_STATUS_REG 0x27
#define ADDR_OUT_X_L 0x28
#define ADDR_OUT_X_H 0x29
#define ADDR_OUT_Y_L 0x2A
#define ADDR_OUT_Y_H 0x2B
#define ADDR_OUT_Z_L 0x2C
#define ADDR_OUT_Z_H 0x2D
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c3;
SD_HandleTypeDef hsd1;
SPI_HandleTypeDef hspi2;
/* USER CODE BEGIN PV */
HAL_SD_CardInfoTypeDef pCardInfo;
char datar[1024];
HAL_StatusTypeDef retstat;
//HAL_MMC_CardInfoTypeDef pCardInfo;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDMMC1_SD_Init(void);
static void MX_I2C3_Init(void);
static void MX_SPI2_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
int ret;
uint8_t txData[8],rxData[8]; //Buffers for the first read.
uint8_t rBuffer[8]; //Buffer for the second read.
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SDMMC1_SD_Init();
MX_I2C3_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
txData[0] = ADDR_WHO_AM_I | 0x80;
HAL_SPI_Transmit(&hspi2, txData, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, rxData, 1, HAL_MAX_DELAY);
HAL_Delay(1000);
txData[0] = ADDR_CTRL_REG1 | 0x80;
HAL_Delay(500);
HAL_SPI_Transmit(&hspi2, txData, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, rBuffer, 1, HAL_MAX_DELAY);
HAL_Delay(1000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 10;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C3|RCC_PERIPHCLK_SDMMC1;
PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief I2C3 Initialization Function
* #param None
* #retval None
*/
static void MX_I2C3_Init(void)
{
/* USER CODE BEGIN I2C3_Init 0 */
/* USER CODE END I2C3_Init 0 */
/* USER CODE BEGIN I2C3_Init 1 */
/* USER CODE END I2C3_Init 1 */
hi2c3.Instance = I2C3;
hi2c3.Init.Timing = 0x10909CEC;
hi2c3.Init.OwnAddress1 = 0;
hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c3.Init.OwnAddress2 = 0;
hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c3) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C3_Init 2 */
/* USER CODE END I2C3_Init 2 */
}
/**
* #brief SDMMC1 Initialization Function
* #param None
* #retval None
*/
static void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
hsd1.Init.ClockDiv = 0;
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SDMMC1_Init 2 */
//HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
/* USER CODE END SDMMC1_Init 2 */
}
/**
* #brief SPI2 Initialization Function
* #param None
* #retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1|GPIO_PIN_0, GPIO_PIN_RESET);
/*Configure GPIO pins : PE1 PE0 */
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
I can't explain the behavior you described for the separate HAL_SPI_Transmit() and HAL_SPI_Receive() calls. But regardless, you should be using HAL_SPI_TransmitReceive(). Here is an example.
HAL_StatusTypeDef ReadRegister(uint8_t addr, uint8_t *byte)
{
HAL_StatusTypeDef hal_status;
uint8_t tx_data[2];
uint8_t rx_data[2];
tx_data[0] = addr | 0x80; // read operation
tx_data[1] = 0; // dummy byte for response
hal_status = HAL_SPI_TransmitReceive(&hspi2, tx_data, rx_data, 2, SPI_TIMEOUT);
if (hal_status == HAL_OK)
{
*byte = rx_data[1]; // response is in the second byte
}
return hal_status;
}
The master SPI controller clocks out bytes and both the master and slave transmit and receive during each byte. For the first byte, the master transmits the register addr and the slave transmits a dummy byte because the slave doesn't know what register you're trying to read yet. (Some slave devices send a status in the first byte.) For the second byte, the master transmits a dummy byte for the purpose of generating more clocks on which the slave can respond. After receiving the register address during the first byte, the slave knows which register value to transmit during the second byte. Notice in the example code that the received byte you're interested in is the second byte of the response buffer.
Since HAL_SPI_Receive is already using HAL_SPI_TransmitReceive (github stm32f4 spi driver) to send dummy data to generate clock, you can use that fact and ditch the HAL_SPI_Transmit, and use the receive function like this:
rxData[0] = ADDR_WHO_AM_I | 0x80;
HAL_SPI_Receive(&hspi2, rxData, 1, HAL_MAX_DELAY);
Note that we provide the address and operation using rxData but it will effectively be overwritten by the read data.
or you can simply use HAL_SPI_TransmitReceive :
txData[0] = ADDR_WHO_AM_I | 0x80;
HAL_SPI_TransmitReceive(&hspi2, txData, rxData, 1, HAL_MAX_DELAY);
HAL_Delay(500);
txData[0] = ADDR_CTRL_REG1 | 0x80;
HAL_SPI_TransmitReceive(&hspi2, txData, rxData, 1, HAL_MAX_DELAY);
Good afternoon, I am using stm32 Blue Pill on USB (CDC) com port, "IAR" development environment.
I have connected a library 1, 2 for stm32 to work with W25Qxx SPI flash drives ...
I ran the tests in the main.c file as follows:
Write byte, read byte, write page, read page,
sector write, sector read, block write, block read.
All checks were successful, the flash drive is working and there are no problems with the library.
The problem is as follows, when I connect via app or terminal to port and try to send data
in "HEX" format 1E 01 0A 02 00 00 09 C4 03, and then write them into memory by the microcontroller (W25Qxx) then USB CDC freezes (crashes) when receiving data packets on stm32 and when reconnecting
a message "USB device not recognized" appears on the computer.
3.3v power did not turn off!
In order for you to check this, I will give an example:
The project was created via STM32CubeMX.
Main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h" // это для функции strlen()
#include "stdio.h"
#include "w25qxx.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USB_DEVICE_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
W25qxx_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief ADC1 Initialization Function
* #param None
* #retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/**
* #brief ADC2 Initialization Function
* #param None
* #retval None
*/
static void MX_ADC2_Init(void)
{
/* USER CODE BEGIN ADC2_Init 0 */
/* USER CODE END ADC2_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC2_Init 1 */
/* USER CODE END ADC2_Init 1 */
/** Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC2_Init 2 */
/* USER CODE END ADC2_Init 2 */
}
/**
* #brief SPI2 Initialization Function
* #param None
* #retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
/**
* #brief USART1 Initialization Function
* #param None
* #retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : LED_Pin */
GPIO_InitStruct.Pin = LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : FLASH_CS_Pin */
GPIO_InitStruct.Pin = FLASH_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(FLASH_CS_GPIO_Port, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Add to the usbd_cdc_if.c file:
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if.h"
#include "w25qxx.h"
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
if(Buf !=NULL)
{
//Identifier
if(Buf[0] == 30)
{
W25qxx_EraseSector(0); // 4096 byte
//W25qxx_WritePage (Buf,0,0,9);
W25qxx_WriteByte(Buf[1], 0); //checkbox 0-1
W25qxx_WriteByte(Buf[2], 1); //button_min 0-60
W25qxx_WriteByte(Buf[3], 2); //radioButton 2-3
W25qxx_WriteByte(Buf[4], 3); //voltage
W25qxx_WriteByte(Buf[5], 4); //voltage
W25qxx_WriteByte(Buf[6], 5); //voltage
W25qxx_WriteByte(Buf[7], 6); //voltage
W25qxx_WriteByte(Buf[8], 7); //pul 0-199
}
}
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
For verification, a buffer reception test was invented (successfully) does not hang.
Add to the usbd_cdc_if.c file:
uint8_t checkBox;
uint8_t button_min;
uint8_t radioButton;
int voltage;
uint8_t pul;
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
if(Buf !=NULL)
{
//Identifier
if(Buf[0] == 30)
{
checkBox = Buf[1];
button_min = Buf[2];
radioButton = Buf[3];
voltage = (Buf[4] << 24) | (Buf[5] << 16) | (Buf[6] << 28) | (Buf[7] << 0);
pul = Buf[8];
}
}
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
To check, a test with an LED was invented (successfully).
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
if(Buf !=NULL)
{
//Identifier
if(Buf[0] == 30)
{
if(Buf[1] == 1)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
else if (Buf[1] == 0)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
}
}
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
As far as I remember the function `CDC_Receive_FS()´ is a call back from the USB Interrupt.
So writing to the memory directly from the IRQ is not good since it will block other interrupts.
A better solution would be to copy the receive buffer to a local structure and and set a flag. In you main loop you could monitor the flag and start the write.
I'm sampling an analog audio signal with STM32F767ZIT6 processor, I'm trying to use DMA double buffer combined with ADC, in debug mode all seems works well until the half CpltCallback interrupt, when it's fired I can see half of buffer full, but when the full CpltCallback is called the buffer still half full, half empty, and the old samples are overwritten, this is doesn't depend from buffer dimension, I've tried with 10 or 2048 samples and the result is always the same.
In debug mode I see that half CpltCallback is fired two times before full CpltCallback call.
Here is the little program:
Main:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "defines.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
volatile uint32_t adc_samples[2*ADC_BUFF_DIM];
volatile uint32_t adc_buff[2][ADC_BUFF_DIM];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 96;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
ADC conversions start:
void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
if((GPIOC -> IDR & BUTTON_PIN) || (GPIOB -> IDR & ANLG_IN_CTRL_PIN)) //RISING EDGE
{
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &adc_buff, 2*ADC_BUFF_DIM);
GPIOB -> ODR |= GREEN_LED_PIN;
}
else //FALLING EDGE
{
HAL_ADC_Stop_DMA(&hadc1);
GPIOB -> ODR &= ~GREEN_LED_PIN;
}
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END EXTI15_10_IRQn 1 */
}
DMA call back:
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
}
Disable D and I Cache and then try.
THIS IS THE LINK OF THE DATASHEET
https://www.mouser.in/datasheet/2/256/MAX11135-MAX11143-220131.pdf
HERE IS MY CODE
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2019 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint16_t adc_config_reg=0b1000000000000100;
uint16_t unipolar_reg = 0b1000100000000000;
uint16_t bipolar_reg = 0b1001000000000000;
uint16_t adc_mode_reg = 0b0000100010000100;
uint16_t rx_adc_config_reg;
uint16_t rx_unipolar_reg;
uint16_t rx_bipolar_reg;
uint16_t rx_adc_mode_reg;
//uint16_t rx_adc_mode_reg1[16];
uint16_t rx[16];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
*
* #retval None
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,&adc_config_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Receive(&hspi1,&rx_adc_config_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
//
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
//
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,&unipolar_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Receive(&hspi1,&rx_unipolar_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,&bipolar_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Receive(&hspi1,&rx_bipolar_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,&adc_mode_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
// HAL_SPI_Receive(&hspi1,&rx_adc_mode_reg,1,100);
// HAL_SPI_Transmit(&hspi1,&adc_mode_reg1,1,100);
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
//
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
// HAL_SPI_Receive(&hspi1,&rx_adc_mode_reg,1,100);
// HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_SPI_Receive(&hspi1,&rx_adc_mode_reg,1,100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_Delay(2);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
/*Configure GPIO pin : PB6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #param file: The file name as string.
* #param line: The line in file as a number.
* #retval None
*/
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/**
* #}
*/
/**
* #}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
I have configured With Cubmx
Data Size 16 bit
CPOL=CPHA= 1
first bit = MSB
MY SPI COMMUNICATION IS COMPLETE
I AM HAVING TROUBLE RECEIVING OUTPUT DATA AFTER CONVERSION
I am using dsPic33EP512GM604. I have designed a test circuit to test UART Communication.
I have downloaded a sample code from Microchip website and modified accordingly for my device and circuit designed.
I am facing two issues while debugging.
PLL settings not working. Everytime it gets stuck at " while( OSCCONbits.COSC != 0b011 ); ". Hence I commented the clock configuration and Using simple Internal Oscillator FRC.
UART communication is not working. I m using RPI25 as an RX while RP20 as TX on my circuit.
Here is the final code I am using :
/*******************************************************************************/
#include <xc.h>
#include <stdint.h>
#if __XC16_VERSION < 1011
#warning "Please upgrade to XC16 v1.11 or newer."
#endif
//-----------------------------------------------------------------------------
#pragma config ICS = PGD3 // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
// FPOR
#pragma config BOREN = ON // Brown-out Reset (BOR) Detection Enable bit (BOR is enabled)
#pragma config ALTI2C1 = OFF // Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF // Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
#pragma config WDTWIN = WIN25 // Watchdog Window Select bits (WDT Window is 25% of WDT period)
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
#pragma config PLLKEN = OFF // PLL Lock Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
// FOSC
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (XT Crystal Oscillator Mode)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = OFF // Peripheral pin select configuration (Allow multiple reconfigurations)
#pragma config FCKSM = CSDCMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
// FOSCSEL
#pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config PWMLOCK = ON // PWM Lock Enable bit (Certain PWM registers may only be written after key sequence)
#pragma config IESO = ON // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
// FGS
#pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
#pragma config GCP = OFF // General Segment Code-Protect bit (General Segment Code protect is Disabled)
// *****************************************************************************
#define TRUE 1
#define FALSE 0
#define DELAY_105uS asm volatile ("REPEAT, #4201"); Nop();// 105uS delay
// *****************************************************************************
#define FCY 60000000
#define BAUDRATE 9600
#define BRGVAL ( (FCY / BAUDRATE) / 16 ) - 1
uint8_t s3flag, s4flag, s5flag, S6Flag;
/*****************************************************************************/
void __attribute__ ( (interrupt, no_auto_psv) ) _U1RXInterrupt( void )
{
LATA = U1RXREG;
U1TXREG = LATA;
IFS0bits.U1RXIF = 0;
}
/******************************************************************************/
void __attribute__ ( (interrupt, no_auto_psv) ) _U1TXInterrupt( void )
{
IFS0bits.U1TXIF = 0;
}
/******************************************************************************/
void InitClock( void )
{
PLLFBD = 58; // M = 60
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2
OSCTUN = 0;
RCONbits.SWDTEN = 0;
// Clock switch to incorporate PLL
__builtin_write_OSCCONH( 0x03 ); // Initiate Clock Switch to
// External oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL( OSCCON || 0x01 ); // Start clock switching
while( OSCCONbits.COSC != 0b011 );
// Wait for Clock switch to occur
while( OSCCONbits.LOCK != 1 )
{ };
}
/******************************************************************************/
void InitUART2( void )
{
// configure U1MODE
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented;// Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0; // Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U1MODEbits.notimplemented;// Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U1MODEbits.LPBACK = 0; // Bit6 No Loop Back
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
U1BRG = BRGVAL; // 60Mhz osc, 9600 Baud
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
//U1STAbits.notimplemented = 0;//Bit12
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U1STAbits.TRMT = 0; //Bit8 *Read Only bit*
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U1STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U1STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U1STAbits.PERR = 0; //Bit3 *Read Only Bit*
U1STAbits.FERR = 0; //Bit2 *Read Only Bit*
U1STAbits.OERR = 0; //Bit1 *Read Only Bit*
U1STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC7 = 0x4400; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 1; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts
// RPOR1bits.RP36R = 1; //RB4 as U1TX
// RPINR18bits.U1RXR = 24; //RA8 as U1RX
RPOR0bits.RP20R = 1; // dsPic33EP512GM604 => RP20 as U1TX
_U1RXR = 19; // dsPic33EP512GM604 => RPI25 as U1RX
U1MODEbits.UARTEN = 1; // And turn the peripheral on
U1STAbits.UTXEN = 1;
}
/******************************************************************************/
void InitPorts( void )
{
ANSELA = 0;
// TRISAbits.TRISA9 = 1;
// TRISAbits.TRISA4 = 0;
TRISAbits.TRISA10 = 0; //Output
}
/******************************************************************************
int main( void )
{
char recChar = 'a';
int i = 0;
// int count = 0;
// InitClock(); // This is the PLL settings
InitUART2(); // Initialize UART2 for 9600,8,N,1 TX/RX
InitPorts(); // LEDs outputs, Switches Inputs
/* Wait at least 105 microseconds (1/9600) before sending first char */
DELAY_105uS;
while( 1 )
{
PORTAbits.RA10 = 0;
for (i = 0; i < 1000; i++){
DELAY_105uS;
}
U1TXREG = recChar;
recChar++;
if (recChar == 122){
recChar = 48;
}
if (U1STAbits.OERR == 1){
U1STAbits.OERR = 0;
continue;
}
PORTAbits.RA10 = 0;
for (i = 0; i < 1000; i++){
DELAY_105uS;
}
}
}
/*******************************************************************************
I have tested the Circuit by adding LED at RA10 and its working. So, I guess there might be error in my code.
Got the Issues. Now its working
Edit the Test Code as follow :
void InitClock( void )
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD = 63; // M=65
CLKDIVbits.PLLPOST = 0; // N2=2
CLKDIVbits.PLLPRE = 0; // N1=2
// Initiate Clock Switch to FRC oscillator with PLL (NOSC=0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(OSCCON | 0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while (OSCCONbits.LOCK!= 1);
}
void InitUART2( void )
{
// configure U1MODE
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented;// Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
// Load a value into Baud Rate Generator.
U1BRG = BRGVAL; // 60Mhz osc, 9600 Baud
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
IPC7 = 0x4400; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 1; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts
RPOR0bits.RP20R = 1; // dsPic33EP512GM604 => RP20 as U1TX
_U1RXR = 0x19; // dsPic33EP512GM604 => RPI25 as U1RX
U1MODEbits.UARTEN = 1; // And turn the peripheral on
U1STAbits.UTXEN = 1;
}
Applying these changes made my code working.