2016-06-09 05:20 AM
I am working with the Discovery Development Board and I would like to receive data over a software UART. In the code below I would expect to receive 8 timer interrupts if only 1 byte is transmitted, but 100 microseconds after the last bit I receive an extra timer interrupt. Does anybody know why? Other than that, the UART seems to works fine.
000 #define TEST_PIN GPIO_PIN_15
001 #define TEST_PORT GPIOC
002 #define TOGGLE_TEST_PIN_AT_SAMPLING() SET_PIN_HIGH(TEST_PORT, TEST_PIN); SET_PIN_LOW(TEST_PORT, TEST_PIN); \
003 SET_PIN_HIGH(TEST_PORT, TEST_PIN); SET_PIN_LOW(TEST_PORT, TEST_PIN)
004
005 #define Rx_PIN GPIO_PIN_11
006 #define Rx_PORT GPIOC
007 #define Rx_PIN_FLAG 0x0800
008 #define RECEIVE_EVENT_ARG LOW_LEVEL_EVENT__UART2_SW_BYTE_RECEIVED
009 #define EXTERNAL_INT EXTI15_10_IRQn
010 #define EXTERNAL_INT_HANDLER EXTI15_10_IRQHandler
011 #define TIMER_INSTANCE TIM4
012 #define TIMER_INT TIM4_IRQn
013 #define TIMER_INT_HANDLER TIM4_IRQHandler
014
015
016 #define CLEAR_EXT_INT_FLAG_ON_Rx() __HAL_GPIO_EXTI_CLEAR_IT(Rx_PIN)
017 #define ENABLE_EXT_INT_ON_Rx() HAL_NVIC_EnableIRQ(EXTERNAL_INT)
018 #define DISABLE_EXT_INT_ON_Rx() HAL_NVIC_DisableIRQ(EXTERNAL_INT)
019
020 #define START_TIMER() (TIMER_INSTANCE->CR1 |= TIM_CR1_CEN)
021 #define STOP_TIMER() (TIMER_INSTANCE->CR1 &= ~TIM_CR1_CEN)
022 #define TIMER_INT_FLAG (TIMER_INSTANCE->SR & 0x0001)
023 #define ENABLE_TIMER_INT()
do
{ TIMER_INSTANCE->DIER |= TIM_DIER_UIE; HAL_NVIC_EnableIRQ(TIMER_INT); }
while
(0)
024 #define DISABLE_TIMER_INT()
do
{ TIMER_INSTANCE->DIER &= ~TIM_DIER_UIE; HAL_NVIC_DisableIRQ(TIMER_INT); }
while
(0)
025 #define CLEAR_TIMER_INT_FLAG() (TIMER_INSTANCE->SR &= ~TIM_SR_UIF)
026 #define SET_TIMER_PERIOD(period) (TIMER_INSTANCE->ARR = period)
027 #define SET_COUNTER_VALUE(value) (TIMER_INSTANCE->CNT = value)
028 #define SET_PRE_SCALAR_1()
do
{ TIMER_INSTANCE->PSC = 0; TIMER_INSTANCE->EGR = TIM_EGR_UG; }
while
(0)
029
030 #define DUMMY_INT CAN2_RX1_IRQn
031 #define DUMMY_INT_HANDLER CAN2_RX1_IRQHandler
032 #define ENABLE_DUMMY_INT() (HAL_NVIC_EnableIRQ(DUMMY_INT))
033 #define CLEAR_DUMMY_INT_FLAG() (HAL_NVIC_ClearPendingIRQ(DUMMY_INT))
034 #define ISSUE_DUMMY_INT() NVIC->STIR = DUMMY_INT
035
036
037
static
EventCallback_t ByteReceivedCallback_ = (EventCallback_t)NULL;
038
static
uint32_t timerPeriod;
039
static
uint32_t timerPeriodTimesOnePointFive;
040
static
uint8_t idleState_;
041
042
043
void
UART2_SW_Configuration(uint8_t idleState)
044 {
045 idleState_ = idleState;
046
047 GPIO_InitTypeDef GPIO_InitStructure;
048 GPIO_InitStructure.Pin = Rx_PIN;
049
if
(idleState_ == 0)
050 {
051 GPIO_InitStructure.Pull = GPIO_PULLDOWN;
052 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
053 }
054
else
055 {
056 GPIO_InitStructure.Pull = GPIO_PULLUP;
057 GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
058 }
059 GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
060 GPIO_InitStructure.Alternate = 0;
061 HAL_GPIO_Init(Rx_PORT, &GPIO_InitStructure);
062
063 SET_PRE_SCALAR_1();
064 SET_TIMER_PERIOD(0xFFFFFFFF);
065
066 HAL_NVIC_SetPriority(DUMMY_INT, 2, 0);
067 HAL_NVIC_SetPriority(EXTERNAL_INT, 1, 0);
068 HAL_NVIC_SetPriority(TIMER_INT, 0, 0);
069
070 GPIO_InitStructure.Pin = TEST_PIN;
071 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
072 GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
073 GPIO_InitStructure.Pull = GPIO_NOPULL;
074 GPIO_InitStructure.Alternate = 0;
075 HAL_GPIO_Init(TEST_PORT, &GPIO_InitStructure);
076 SET_PIN_LOW(TEST_PORT, TEST_PIN);
077
078 ENABLE_DUMMY_INT();
079 CLEAR_EXT_INT_FLAG_ON_Rx();
080 ENABLE_EXT_INT_ON_Rx();
081 }
082
083
084
void
UART2_SW_SetCallback(EventCallback_t ByteReceivedCallback)
085 {
086
if
(ByteReceivedCallback == (EventCallback_t)NULL)
087 {
088 ByteReceivedCallback_ = (EventCallback_t)NULL;
089 DISABLE_EXT_INT_ON_Rx();
090 }
091
else
092 {
093 ByteReceivedCallback_ = ByteReceivedCallback;
094 ENABLE_EXT_INT_ON_Rx();
095 }
096 }
097
098
099
void
UART2_SW_SetBaudRate(uint32_t baudRate)
100 {
101 timerPeriod = GET_TIMER_FREQ(TIMER_INSTANCE)/baudRate;
102 timerPeriodTimesOnePointFive = (3 * ((uint32_t)timerPeriod)) >> 1;
103 }
104
105
106
static
volatile
uint8_t bitCount = 0;
107
static
volatile
uint8_t receivedByte = 0;
108
static
volatile
uint8_t finishedReceivedByte = 0;
109
static
uint8_t sampledValue;
110
111
void
EXTERNAL_INT_HANDLER(
void
)
112 {
113 SET_COUNTER_VALUE(0);
114 START_TIMER();
115 DISABLE_EXT_INT_ON_Rx();
116 SET_TIMER_PERIOD(timerPeriodTimesOnePointFive);
117 CLEAR_TIMER_INT_FLAG();
118 ENABLE_TIMER_INT();
119 bitCount = 0;
120 }
121
122
123
void
TIMER_INT_HANDLER(
void
)
124 {
125 TOGGLE_TEST_PIN_AT_SAMPLING();
126 sampledValue = READ_PIN(Rx_PORT, Rx_PIN);
127 CLEAR_TIMER_INT_FLAG();
128
if
(bitCount == 0)
129 {
130 SET_TIMER_PERIOD(timerPeriod);
131 receivedByte = sampledValue;
132 bitCount++;
133 }
134
else
if
((1 <= bitCount) && (bitCount <= 6))
135 {
136 receivedByte |= (sampledValue << bitCount);
137 bitCount++;
138 }
139
else
140 {
141 STOP_TIMER();
142 DISABLE_TIMER_INT();
143 SET_TIMER_PERIOD(0xFFFFFFFF);
144 finishedReceivedByte = receivedByte | (sampledValue << 7);
145
if
(idleState_ == 0)
146 {
147 finishedReceivedByte = ~finishedReceivedByte;
148 }
149
if
(bitCount == 7)
150 {
151 ISSUE_DUMMY_INT();
152 }
153
if
(ByteReceivedCallback_ != (EventCallback_t)NULL)
154 {
155 CLEAR_EXT_INT_FLAG_ON_Rx();
156 ENABLE_EXT_INT_ON_Rx();
157 }
158 }
159 }
160
161
162
void
DUMMY_INT_HANDLER(
void
)
163 {
164
if
(ByteReceivedCallback_ != (EventCallback_t)NULL)
165 {
166 (
void
)ByteReceivedCallback_((uint32_t)RECEIVE_EVENT_ARG, (uint32_t)finishedReceivedByte);
167 }
168 }
2016-06-14 05:32 AM
Doesn't the F4 have enough real USARTs?