lnp-logical.c
Go to the documentation of this file.
1
6/*
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.0 (the "License"); you may not use this file except in
9 * compliance with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
14 * License for the specific language governing rights and limitations
15 * under the License.
16 *
17 * The Original Code is legOS code, released October 17, 1999.
18 *
19 * The Initial Developer of the Original Code is Markus L. Noga.
20 * Portions created by Markus L. Noga are Copyright (C) 1999
21 * Markus L. Noga. All Rights Reserved.
22 *
23 * Contributor(s): Markus L. Noga <markus@noga.de>
24 * Chris Dearman <chris@algor.co.uk>
25 * Martin Cornelius <Martin.Cornelius@t-online.de>
26 */
27
28#include <sys/lnp-logical.h>
29
30#ifdef CONF_LNP
31
32#include <sys/lnp.h>
33
34#include <sys/h8.h>
35#include <sys/irq.h>
36
37#ifdef CONF_AUTOSHUTOFF
38#include <sys/timeout.h>
39#endif
40
41#include <time.h>
42#include <mem.h>
43#include <semaphore.h>
44#include <unistd.h>
45
46#include <rom/registers.h>
47
49//
50// Variables
51//
53
54static const unsigned char *tx_ptr;
55static const unsigned char *tx_verify;
56static const unsigned char *tx_end;
57
58volatile signed char tx_state;
59
61
66static time_t allow_tx;
67
68#ifdef CONF_TM
69static sem_t tx_sem;
70#endif
71
73//
74// Functions
75//
77
78#ifdef CONF_RCX_COMPILER
79static void rx_handler(void) __attribute__ ((rcx_interrupt));
80static void rxerror_handler(void) __attribute__ ((rcx_interrupt));
81static void tx_handler(void) __attribute__ ((rcx_interrupt));
82 void txend_handler(void) __attribute__ ((rcx_interrupt));
83#else
84void rx_handler(void);
85void rxerror_handler(void);
86void tx_handler(void);
87void txend_handler(void);
88#endif
89
90
92extern inline void carrier_init(void) {
93 T1_CR =0x9;
94 T1_CSR =0x13;
95 T1_CORA=0x1a;
96}
97
99extern inline void carrier_shutdown(void) {
100 T1_CR =0;
101 T1_CSR =0;
102}
103
105//
106#ifdef CONF_RCX_COMPILER
107static void rx_handler(void) {
108#else
109HANDLER_WRAPPER("rx_handler","rx_core");
110void rx_core(void) {
111#endif
112 time_t new_tx;
114 if(tx_state<TX_ACTIVE) {
115 // foreign bytes
116 //
118 if (new_tx > allow_tx) allow_tx = new_tx;
120 } else {
121 // echos of own bytes -> collision detection
122 //
123 if(S_RDR!=*tx_verify) {
126 } else if( tx_end <= ++tx_verify ) {
127 // let transmission end handler handle things
128 //
130 }
131 }
132
133 // suppress volatile modifier to generate bit instruction.
134 //
135 *((char*) &S_SR) &=~SSR_RECV_FULL;
136}
137
139//
140#ifdef CONF_RCX_COMPILER
141static void rxerror_handler(void) {
142#else
143HANDLER_WRAPPER("rxerror_handler","rxerror_core");
144void rxerror_core(void) {
145#endif
146 time_t new_tx;
147 if(tx_state<TX_ACTIVE) {
150 if (new_tx > allow_tx) allow_tx = new_tx;
151 } else {
154 }
155
156 S_SR&=~SSR_ERRORS;
157}
158
160//
161#ifdef CONF_RCX_COMPILER
162void txend_handler(void) {
163#else
164HANDLER_WRAPPER("txend_handler","txend_core");
165void txend_core(void) {
166#endif
167 // shutdown transmit and irqs, clear status flags
168 //
171}
172
174
176#ifdef CONF_RCX_COMPILER
177static void tx_handler(void) {
178#else
179HANDLER_WRAPPER("tx_handler","tx_core");
180void tx_core(void) {
181#endif
182 if(tx_ptr<tx_end) {
183 // transmit next byte
184 //
185 S_TDR = *(tx_ptr++);
186 *((char*) &S_SR)&=~SSR_TRANS_EMPTY;
187 } else {
188 // disable transmission interrupt
189 //
190 S_CR&=~SCR_TX_IRQ;
191 }
192}
193
195void lnp_logical_shutdown(void) {
196 S_CR =0; // everything off
197 carrier_shutdown();
199
201 allow_tx=0;
202
203#ifdef CONF_TM
204 sem_destroy(&tx_sem);
205#endif
206}
207
209
211void lnp_logical_init(void) {
212 // safe initial state.
213 //
215
216#ifdef CONF_TM
217 sem_init(&tx_sem,0,1);
218#endif
219
220 // serial setup according to CONF_LNP_FAST / lnp_logical.h
221 // was 8N1 fixed, now parity is also set.
222 //
225 S_SR =0;
226
227 // carrier setup
228 //
229 rom_port4_ddr |= 1; // port 4 bit 0 output
231 carrier_init();
232 rom_port5_ddr = 4; // init p5ddr, for now
234
235 // IRQ handler setup
236 //
237 eri_vector=&rxerror_handler;
238 rxi_vector=&rx_handler;
239 txi_vector=&tx_handler;
241
242 // enable receiver and IRQs
243 //
245}
246
247
248static wakeup_t write_allow(wakeup_t data) {
249 return get_system_up_time() >= *((volatile time_t*)&allow_tx);
250}
251
252static wakeup_t write_complete(wakeup_t data) {
253 return *((volatile signed char*)&tx_state)<TX_ACTIVE;
254}
255
257
261int lnp_logical_write(const void* buf,size_t len) {
262 unsigned char tmp;
263
264#ifdef CONF_TM
265 if (sem_wait(&tx_sem) == -1)
266 return tx_state;
267#endif
268
269#ifdef CONF_AUTOSHUTOFF
271#endif
272
273 if (wait_event(write_allow,0) != 0)
274 {
276
277 tx_verify=tx_ptr=buf; // what to transmit
278 tx_end=buf+len;
279
281 S_SR&=~(SSR_TRANS_EMPTY | SSR_TRANS_END); // clear flags
282 S_CR|=SCR_TRANSMIT | SCR_TX_IRQ | SCR_TE_IRQ; // enable transmit & irqs
283
284 wait_event(write_complete,0);
285
286 // determine delay before next transmission
287 //
288 if(tx_state==TX_IDLE)
289 tmp=LNP_WAIT_TXOK;
290 else
291 tmp=LNP_WAIT_COLL + ( ((unsigned char) 0x0f) &
292 ( ((unsigned char) len)+
293 ((unsigned char*)buf)[len-1]+
294 ((unsigned char) get_system_up_time()) ) );
295 allow_tx=get_system_up_time()+tmp;
296 }
297
298#ifdef CONF_TM
299 sem_post(&tx_sem);
300#endif
301
302 return tx_state;
303}
304
305#endif // CONF_LNP
Internal Interface: H8/3297 processor registers.
unsigned char T1_CORA
timer 1 constant A register
#define SCR_TX_IRQ
Definition h8.h:237
unsigned char PORT4_DDR
port 4 data direction register
#define SCR_RECEIVE
Definition h8.h:240
#define SCR_RX_IRQ
Definition h8.h:238
unsigned char S_TDR
serial transmit data register
#define SSR_TRANS_EMPTY
Definition h8.h:248
unsigned char S_BRR
serial baud rate register
unsigned char PORT5_DDR
port 5 data direction register
#define SCR_TE_IRQ
Definition h8.h:242
unsigned char S_CR
serial control register
volatile unsigned char T1_CSR
timer 1 control / status register
volatile unsigned char S_RDR
serial receive data register
#define SSR_TRANS_END
Definition h8.h:254
unsigned char T1_CR
timer 1 control register
volatile unsigned char S_SR
serial status register
unsigned char S_MR
serial mode register
#define SCR_TRANSMIT
Definition h8.h:239
Internal LNP Interface: RCX redirected IRQ vectors.
void * tei_vector
TEI interrupt vector.
void * eri_vector
ERI interrupt vector.
void * rxi_vector
RXI interrupt vector.
void * txi_vector
TXI interrupt vector.
#define HANDLER_WRAPPER(wrapstring, handstring)
Definition irq.h:48
void lnp_logical_range(int far)
Set the IR transmitter range.
Definition lnp-logical.h:62
int lnp_logical_write(const void *buf, size_t len)
Write buffer to IR port.
Interface: memory data types.
ROM Interface: RCX registers cached by ROM functions.
unsigned char rom_port5_ddr
ROM shadow of port 5 DDR.
unsigned char rom_port4_ddr
ROM shadow of port 4 DDR.
Interface: POSIX 1003.1b semaphores for task synchronization.
int sem_post(sem_t *sem)
Post a semaphore.
Definition semaphore.h:123
int sem_init(sem_t *sem, int pshared, unsigned int value)
Initialize a semaphore.
Definition semaphore.h:64
int sem_destroy(sem_t *sem)
We're done with the semaphore, destroy it.
Definition semaphore.h:147
int sem_wait(sem_t *sem)
Wait for semaphore (blocking)
atomic_t sem_t
the semaphore data-type
Definition semaphore.h:46
Internal LNP Interface: link networking protocol logical layer.
#define LNP_WAIT_TXOK
delay after good transmit
Definition lnp-logical.h:62
#define LNP_BYTE_SAFE
delay before transmitting a byte
Definition lnp-logical.h:60
volatile signed char tx_state
transmit status
#define TX_ACTIVE
currently transmitting
Definition lnp-logical.h:68
#define LNP_WAIT_COLL
delay after collision
Definition lnp-logical.h:63
#define TX_IDLE
not transmitting, last xmit OK
Definition lnp-logical.h:67
#define TX_COLL
not transmitting, last xmit was collision
Definition lnp-logical.h:66
void txend_handler(void)
Callback: end of transmission.
#define LNP_LOGICAL_PARITY
parity
Definition lnp-logical.h:55
void lnp_logical_shutdown(void)
Shutdown the logical layer (IR port)
void lnp_logical_init(void)
Initialize the logical layer (IR port)
#define LNP_LOGICAL_BAUD_RATE
baud rate
Definition lnp-logical.h:54
Internal LNP Interface: link networking protocol.
void lnp_integrity_byte(unsigned char b)
receive a byte from the physical layer, decoding integrity layer packets.
void lnp_integrity_reset(void)
reset the integrity layer on error or timeout.
void lnp_timeout_reset(void)
reset the inter-byte timeout counter.
time_t get_system_up_time(void)
retrieve the current system time
unsigned long time_t
time type
Definition time.h:50
Internal Interface: Powerdown Timer Routines.
void shutoff_restart(void)
unsigned long wakeup_t
wakeup data area type
Definition tm.h:57
Interface: reduced UNIX standard library.
wakeup_t wait_event(wakeup_t(*wakeup)(wakeup_t), wakeup_t data)
Definition unistd.h:112

brickOS is released under the Mozilla Public License.
Original code copyright 1998-2005 by the authors.

Generated for brickOS Kernel Developer by doxygen 1.9.8