Skip to content

Commit f7e3c57

Browse files
committed
Fixes
Add pll_switch, some uart fixes, watchdog feed interrupt store/restore, drop 'hasdata' in ringbuffer code in an attempt to make it work with read and write from a different context
1 parent b5a50fd commit f7e3c57

12 files changed

+122
-109
lines changed

config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Configuration and general defines
129129

130130
/*! This defines the watchdog counter value. This is calculated with
131131
tPCLK x interval x 4, which results in the timeout in seconds.
132-
Use a value of '0' to disable the watchdog. */
132+
Range 256 - 2^32, use a value of '0' to disable the watchdog. */
133133
#define WATCHDOG_TIMEOUT 0
134134

135135
/*! Some drivers contain wait-loops, used to wait for an interrupt-based event to

crt0.S

-11
Original file line numberDiff line numberDiff line change
@@ -218,17 +218,6 @@ FIQHandler:
218218
FIQ_unhandled @ Call macro in config_crt0.S
219219
.endfunc
220220

221-
#if CODEPROTECTION
222-
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
223-
@ Code protection
224-
@ By writing a special value to a special location (...) all ISP code
225-
@ reading functions AND the complete JTAG interface are disabled.
226-
.section .codeprotection,"ax"
227-
.arm
228-
.align 2
229-
.word 0x87654321
230-
#endif
231-
232221
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
233222
@ Exception-table.
234223
@ The ARM CPU always starts in the exception (or vector) table. Therefore

drivers/backtrace_ARM.su

-1
This file was deleted.

drivers/init.c

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ ALDS initialization code
3232

3333
static char resetcause;
3434

35+
#if CODEPROTECTION
36+
/* By writing a special value to a special location (...) all ISP code
37+
reading functions AND the complete JTAG interface are disabled. */
38+
const unsigned int codeprotection __attribute__ ((section(".codeprotection"))) = 0x87654321;
39+
#endif
3540

3641
error_t init(bool enableirq)
3742
/*!

drivers/irqstatus_ARM.su

-1
This file was deleted.

drivers/pll.c

+39
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ PLL, MAM & VPB initialisation
2323
#include <pll.h>
2424
#include <irq.h>
2525
#include "registers.h"
26+
#include <debug.h>
2627

2728
void pll_init(void)
2829
/*!
@@ -69,3 +70,41 @@ void pll_init(void)
6970

7071
__restore_interrupts(&__interrupt_status);
7172
}
73+
74+
void pll_switch(unsigned char multiplier)
75+
/*!
76+
Change PLL settings at runtime. Tricky stuff, use with care.
77+
A lot of clock-base stuff won't work after the switch (think baudrates, delays, ...)
78+
*/
79+
{
80+
__store_interrupts(&__interrupt_status);
81+
82+
/* Disable the Memory Accelerator Module */
83+
MAMCR = MAMCR_OFF;
84+
85+
// PLLCFG = PLLCFG_MSEL | PLLCFG_PSEL;
86+
//
87+
// PLLCFG_MSEL = ((PLL_MUL - 1) << 0)
88+
// PLL_MUL = set in config.h, 'multiplier' here
89+
//
90+
// PLLCFG_PSEL = ((PLL_DIV - 1) << 5)
91+
// PLL_DIV = (FCCO_MAX / (2 * CCLK))
92+
// FCCO_MAX = set in mcu_select.h
93+
// CCLK = (FOSC * PLL_MUL)
94+
// FOSC = set in mcu_select.h
95+
PLLCFG = ((multiplier - 1) << 0) | (((FCCO_MAX / (2 * (FOSC * multiplier))) - 1) << 5);
96+
/* PLL enable */
97+
PLLCON = PLLCON_PLLE;
98+
/* PLL feed sequence */
99+
PLLFEED = 0x000000AA;
100+
PLLFEED = 0x00000055;
101+
/* Wait until the PLL has locked */
102+
while(!(PLLSTAT & PLLSTAT_LOCK)) { dprint(".");};
103+
/* PLL enable and connect */
104+
PLLCON = PLLCON_PLLE | PLLCON_PLLC;
105+
/* PLL feed sequence */
106+
PLLFEED = 0x000000AA;
107+
PLLFEED = 0x00000055;
108+
109+
__restore_interrupts(&__interrupt_status);
110+
}

drivers/ringbuffer.c

+46-79
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ void ringbuffer_init(ringbufferctrl_t *ringbuffer, unsigned char *buffer, unsign
3535
ringbuffer->length=bufferlength;
3636
ringbuffer->readpos=0;
3737
ringbuffer->writepos=0;
38-
ringbuffer->hasdata=0;
3938
}
4039

4140
size_t ringbuffer_write(ringbufferctrl_t *ringbuffer, const void *pointer, const size_t size, const size_t length)
@@ -73,9 +72,6 @@ size_t ringbuffer_write(ringbufferctrl_t *ringbuffer, const void *pointer, const
7372
}
7473
}
7574

76-
/* There's data in the buffer */
77-
ringbuffer->hasdata = 1;
78-
7975
return written / size;
8076
}
8177

@@ -92,16 +88,13 @@ signed short ringbuffer_peek(ringbufferctrl_t *ringbuffer, const size_t offset)
9288
dprint("ringbuffer_peek(): offset = %i, readpos = %i, writepos = %i, free = %i\n\r", offset, ringbuffer->readpos, ringbuffer->writepos, ringbuffer_getfreebytes(ringbuffer));
9389
#endif
9490

95-
if(offset < 0 || offset >= ringbuffer->length) {
96-
/* This will never fit */
91+
if(offset < 0 || offset >= ringbuffer->length || ringbuffer_isempty(ringbuffer)) {
92+
/* Invalid offset, or no data at all */
9793
return -1;
9894
}
9995

10096
/* Figure out what position to read from */
101-
peekpos = ringbuffer->readpos + offset;
102-
if(peekpos >= ringbuffer->length) {
103-
peekpos -= ringbuffer->length;
104-
}
97+
peekpos = (ringbuffer->readpos + offset) % ringbuffer->length;
10598

10699
if(ringbuffer->writepos > ringbuffer->readpos && peekpos >= ringbuffer->writepos) {
107100
/* Readpointer is before writepointer, thus peekpos must also be before writepointer */
@@ -135,31 +128,17 @@ size_t ringbuffer_read(ringbufferctrl_t *ringbuffer, void *pointer, const size_t
135128
dprint("ringbuffer_read(): toread = %i, readpos = %i, writepos = %i, free = %i\n\r", toread, ringbuffer->readpos, ringbuffer->writepos, ringbuffer_getfreebytes(ringbuffer));
136129
#endif
137130

138-
if(toread > ringbuffer->length - ringbuffer_getfreebytes(ringbuffer)) {
139-
#if RINGBUFFER_WHENREADOVERFLOW_SHRINK
140-
/* Oops.. trying to read more than available */
141-
#ifdef DEBUG_RINGBUFFER
142-
dprint("ringbuffer_read(): Too much data, shrink! (was %i, is now %i)\n\r",toread,ringbuffer->length - ringbuffer_getfreebytes());
143-
#endif
144-
toread = ringbuffer->length - ringbuffer_getfreebytes(ringbuffer);
145-
/* Ringbuffer will be empty when we're done here */
146-
ringbuffer->hasdata = 0;
147-
#else
131+
if(toread > ringbuffer_getusedbytes(ringbuffer)) {
148132
/* Do nothing */
149133
#ifdef ringbufferdebug
150134
DEBUG("ringbuffer_read(): too much data, leave\n\r");
151135
#endif
152136
return 0;
153-
#endif
154-
}
155-
else if(toread == ringbuffer->length - ringbuffer_getfreebytes(ringbuffer)) {
156-
/* Ringbuffer will be empty when we're done here */
157-
ringbuffer->hasdata = 0;
158137
}
159138

160139
while(read < toread) {
161140
/* Read byte.. */
162-
buffer[read]=ringbuffer->data[ringbuffer->readpos];
141+
buffer[read] = ringbuffer->data[ringbuffer->readpos];
163142
read++;
164143
/* And advance ringbuffer pointer */
165144
ringbuffer->readpos++;
@@ -171,34 +150,6 @@ size_t ringbuffer_read(ringbufferctrl_t *ringbuffer, void *pointer, const size_t
171150
return read / size;
172151
}
173152

174-
static unsigned int ringbuffer_toskip(ringbufferctrl_t *ringbuffer, const size_t size, const size_t length)
175-
{
176-
unsigned int toskip;
177-
178-
/* Figure out how much bytes we have to skip */
179-
toskip = length * size;
180-
181-
#ifdef DEBUG_RINGBUFFER
182-
dprint("ringbuffer_toskip(): toskip=%i, readpos = %i, writepos = %i, free = %i\n\r",toskip, ringbuffer->readpos, ringbuffer->writepos, ringbuffer_getfreebytes(ringbuffer));
183-
#endif
184-
185-
if(toskip > ringbuffer->length - ringbuffer_getfreebytes(ringbuffer)) {
186-
/* Oops.. trying to skip more than available */
187-
#ifdef DEBUG_RINGBUFFER
188-
dprint("ringbuffer_toskip(): too much data, shrink! (was %i, is now %i)\n\r",toskip,ringbuffer->length - ringbuffer_getfreebytes(ringbuffer));
189-
#endif
190-
toskip = ringbuffer->length - ringbuffer_getfreebytes(ringbuffer);
191-
/* Ringbuffer will be empty when we're done here */
192-
ringbuffer->hasdata = 0;
193-
}
194-
else if(toskip == ringbuffer->length - ringbuffer_getfreebytes(ringbuffer)) {
195-
/* Ringbuffer will be empty when we're done here */
196-
ringbuffer->hasdata = 0;
197-
}
198-
199-
return toskip;
200-
}
201-
202153
size_t ringbuffer_skip(ringbufferctrl_t *ringbuffer, const size_t size, const size_t length)
203154
/**
204155
Skip 'length' entries of 'size' size (iow, advance the read-pointer).
@@ -207,9 +158,15 @@ size_t ringbuffer_skip(ringbufferctrl_t *ringbuffer, const size_t size, const si
207158
{
208159
unsigned int toskip;
209160

210-
toskip = ringbuffer_toskip(ringbuffer, size, length);
161+
/* Figure out how much bytes we have to skip */
162+
toskip = length * size;
211163

212-
if(ringbuffer->readpos + toskip >= ringbuffer->length) {
164+
if(toskip > ringbuffer_getusedbytes(ringbuffer)) {
165+
/* Oops.. trying to skip more than available. We skip as much as possible, or iow empty the ringbuffer */
166+
toskip = ringbuffer_getusedbytes(ringbuffer);
167+
ringbuffer->readpos = ringbuffer->writepos;
168+
}
169+
else if(ringbuffer->readpos + toskip >= ringbuffer->length) {
213170
ringbuffer->readpos = toskip - (ringbuffer->length - ringbuffer->readpos);
214171
}
215172
else {
@@ -227,9 +184,15 @@ size_t ringbuffer_revert(ringbufferctrl_t *ringbuffer, const size_t size, const
227184
{
228185
unsigned int toskip;
229186

230-
toskip = ringbuffer_toskip(ringbuffer, size, length);
187+
/* Figure out how much bytes we have to skip */
188+
toskip = length * size;
231189

232-
if(toskip > ringbuffer->writepos) {
190+
if(toskip > ringbuffer_getusedbytes(ringbuffer)) {
191+
/* Oops.. trying to skip more than available. We skip as much as possible, or iow empty the ringbuffer */
192+
toskip = ringbuffer_getusedbytes(ringbuffer);
193+
ringbuffer->writepos = ringbuffer->readpos;
194+
}
195+
else if(toskip > ringbuffer->writepos) {
233196
ringbuffer->writepos = ringbuffer->length - (toskip - ringbuffer->writepos);
234197
}
235198
else {
@@ -244,9 +207,15 @@ unsigned int ringbuffer_getfreebytes(const ringbufferctrl_t *ringbuffer)
244207
Return amount of free bytes in ringbuffer
245208
*/
246209
{
247-
/* Data from readpos to writepos is unhandled. No data should be written there.
248-
So there are two cases possible; readpos is before or after writepos: */
249-
if(ringbuffer->writepos > ringbuffer->readpos) {
210+
if(ringbuffer->readpos == ringbuffer->writepos) {
211+
/* Ringbuffer is empty */
212+
return ringbuffer->length-1;
213+
}
214+
else if((ringbuffer->writepos+1)%ringbuffer->length == ringbuffer->readpos) {
215+
/* One byte remaining between readpos and writepos: ringbuffer is full */
216+
return 0;
217+
}
218+
else if(ringbuffer->writepos > ringbuffer->readpos) {
250219
/* [ start ]
251220
[ ]
252221
[ readpos ] -\
@@ -255,22 +224,7 @@ unsigned int ringbuffer_getfreebytes(const ringbufferctrl_t *ringbuffer)
255224
[ ]
256225
[ length ]
257226
*/
258-
return ringbuffer->readpos + (ringbuffer->length - ringbuffer->writepos);
259-
}
260-
else if(ringbuffer->writepos == ringbuffer->readpos) {
261-
/* This is a tricky one; is the buffer completely empty or completely full? */
262-
if(ringbuffer->hasdata) {
263-
#ifdef DEBUG_RINGBUFFER
264-
dprint("ringbuffer_getfreebytes(): Pointer clash, hasdata is SET: buffer full\n\r");
265-
#endif
266-
return 0;
267-
}
268-
else {
269-
#ifdef DEBUG_RINGBUFFER
270-
dprint("ringbuffer_getfreebytes(): Pointer clash, hasdata is NOT SET: buffer empty\n\r");
271-
#endif
272-
return ringbuffer->length;
273-
}
227+
return (ringbuffer->readpos + (ringbuffer->length - ringbuffer->writepos)) - 1;
274228
}
275229
else {
276230
/* [ start ] |
@@ -281,7 +235,7 @@ unsigned int ringbuffer_getfreebytes(const ringbufferctrl_t *ringbuffer)
281235
[ ] | -> used, unread data
282236
[ length ] |
283237
*/
284-
return ringbuffer->readpos-ringbuffer->writepos;
238+
return (ringbuffer->readpos-ringbuffer->writepos) - 1;
285239
}
286240
}
287241

@@ -290,7 +244,20 @@ bool ringbuffer_isfull(const ringbufferctrl_t *ringbuffer)
290244
Return TRUE is ringbuffer is full, FALSE otherwise
291245
*/
292246
{
293-
if(ringbuffer->hasdata && ringbuffer->writepos == ringbuffer->readpos) {
247+
if((ringbuffer->writepos+1)%ringbuffer->length == ringbuffer->readpos) {
248+
/* One byte remaining between readpos and writepos: ringbuffer is full */
249+
return TRUE;
250+
}
251+
return FALSE;
252+
}
253+
254+
bool ringbuffer_isempty(const ringbufferctrl_t *ringbuffer)
255+
/**
256+
Return TRUE is ringbuffer is empty, FALSE otherwise
257+
*/
258+
{
259+
if(ringbuffer->readpos == ringbuffer->writepos) {
260+
/* Ringbuffer is empty */
294261
return TRUE;
295262
}
296263
return FALSE;

drivers/uart0.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ void uart0_deinit()
160160
{
161161
/* Make Tx and Rx pins GPIO */
162162
PINSEL0 &= ~((3<<0) | (3<<2));
163+
164+
vic_disablechannel(VIC_CH_UART0);
163165
}
164166

165167
void uart0_setparameters(const signed char stopbits, const signed char parity, const signed char wordlength, const signed char breakcontrol, const signed char rxtriggerlevel)
@@ -239,9 +241,14 @@ void uart0_setbaudrate(const unsigned short baudrate)
239241
/*!
240242
Set baudrate
241243
*/
242-
{
244+
{ /* Set DLAB */
245+
U0LCR |= LCR_DLAB;
246+
243247
U0DLL = (unsigned char)baudrate;
244248
U0DLM = baudrate>>8;
249+
250+
/* Clear DLAB */
251+
U0LCR &= ~LCR_DLAB;
245252
}
246253

247254
void uart0_putchar(const unsigned char c)

drivers/uart1.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ UART1 driver, both poll and interrupt-based versions
6666
UART_PARITY_1 Parity bit is always '1'
6767
UART_PARITY_0 Parity bit is always '0'
6868
UART_PARITY_NONE Parity bit is disabled */
69-
#define UART1_PARITY UART_PARITY_EVEN
69+
#define UART1_PARITY UART_PARITY_NONE
7070

7171
/*! Configure the number of stopbits. Possible values are 1 and 2. */
7272
#define UART1_STOPBITS 1
@@ -86,8 +86,8 @@ UART1 driver, both poll and interrupt-based versions
8686
#define UART1_RXTRIGGERLEVEL UART_RX_TRIGGERLEVEL14
8787

8888
/* PINSEL values for flowcontrol*/
89-
#define VAL_PINSEL0_U1FLOW (0x5<<20)
90-
#define MSK_PINSEL0_U1FLOW (0xf<<20)
89+
#define VAL_PINSEL0_U1FLOW (0x5<<20)
90+
#define MSK_PINSEL0_U1FLOW (0xf<<20)
9191
#define VAL_PINSEL0_U1FLOWRTS (0x1<<20)
9292
#define MSK_PINSEL0_U1FLOWRTS (0x3<<20)
9393
#define VAL_PINSEL0_U1FLOWCTS (0x1<<22)
@@ -173,6 +173,10 @@ void uart1_deinit()
173173
{
174174
/* Make Tx and Rx pins GPIO */
175175
PINSEL0 &= ~((3<<16) | (3<<18));
176+
/* Make RTS and CTS pins GPIO */
177+
PINSEL0 &= ~MSK_PINSEL0_U1FLOW;
178+
179+
vic_disablechannel(VIC_CH_UART1);
176180
}
177181

178182
void uart1_setparameters(const signed char stopbits, const signed char parity, const signed char wordlength, const signed char breakcontrol, const signed char rxtriggerlevel)
@@ -253,8 +257,14 @@ void uart1_setbaudrate(const unsigned short baudrate)
253257
Set baudrate
254258
*/
255259
{
260+
/* Set DLAB */
261+
U1LCR |= LCR_DLAB;
262+
256263
U1DLL = (unsigned char)baudrate;
257264
U1DLM = baudrate>>8;
265+
266+
/* Clear DLAB */
267+
U1LCR &= ~LCR_DLAB;
258268
}
259269

260270
void uart1_putchar(const unsigned char c)
@@ -432,7 +442,7 @@ static void uart1_intHandler(void)
432442
UART1 interrupt handling
433443
*/
434444
{
435-
switch(U1IIR & IIR_ID_MASK) {
445+
switch(U1IIR & IIR_ID_MASK) {
436446
case IIR_ID_RDA:
437447
case IIR_ID_CTI:
438448
/* Data has been received */

0 commit comments

Comments
 (0)