aboutsummaryrefslogtreecommitdiff
path: root/example-fs-bb48/sample.c
diff options
context:
space:
mode:
Diffstat (limited to 'example-fs-bb48/sample.c')
-rw-r--r--example-fs-bb48/sample.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/example-fs-bb48/sample.c b/example-fs-bb48/sample.c
new file mode 100644
index 0000000..92ecc9b
--- /dev/null
+++ b/example-fs-bb48/sample.c
@@ -0,0 +1,228 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <chopstx.h>
+
+#include "usb_lld.h"
+#include "stream.h"
+#include "board.h"
+
+struct GPIO {
+ volatile uint32_t PDOR; /* Port Data Output Register */
+ volatile uint32_t PSOR; /* Port Set Output Register */
+ volatile uint32_t PCOR; /* Port Clear Output Register */
+ volatile uint32_t PTOR; /* Port Toggle Output Register */
+ volatile uint32_t PDIR; /* Port Data Input Register */
+ volatile uint32_t PDDR; /* Port Data Direction Register */
+};
+static struct GPIO *const GPIOB = (struct GPIO *const)0x400FF040;
+static struct GPIO *const GPIOD = (struct GPIO *const)0x400FF0C0;
+static struct GPIO *const GPIOE = (struct GPIO *const)0x400FF100;
+
+static void
+set_led (int on)
+{
+ if (on)
+ GPIOB->PCOR = (1 << 0); /* PTB0: Clear: Light on */
+ else
+ GPIOB->PSOR = (1 << 0); /* PTB0: Set : Light off */
+}
+
+static chopstx_mutex_t mtx;
+static chopstx_cond_t cnd0;
+static chopstx_cond_t cnd1;
+
+uint8_t u;
+static uint8_t v;
+static uint8_t m; /* 0..100 */
+
+static void
+wait_for (uint32_t usec)
+{
+#if defined(BUSY_LOOP)
+ uint32_t count = usec * 6;
+ uint32_t i;
+
+ for (i = 0; i < count; i++)
+ asm volatile ("" : : "r" (i) : "memory");
+#else
+ chopstx_usec_wait (usec);
+#endif
+}
+
+static void *
+pwm (void *arg)
+{
+ (void)arg;
+
+ chopstx_mutex_lock (&mtx);
+ chopstx_cond_wait (&cnd0, &mtx);
+ chopstx_mutex_unlock (&mtx);
+
+ while (1)
+ {
+ set_led (u&v);
+ wait_for (m);
+ set_led (0);
+ wait_for (100-m);
+ }
+
+ return NULL;
+}
+
+static void *
+blk (void *arg)
+{
+ (void)arg;
+
+ chopstx_mutex_lock (&mtx);
+ chopstx_cond_wait (&cnd1, &mtx);
+ chopstx_mutex_unlock (&mtx);
+
+ while (1)
+ {
+ v = 0;
+ wait_for (200*1000);
+ v = 1;
+ wait_for (200*1000);
+ }
+
+ return NULL;
+}
+
+#define INTR_REQ_USB 24
+
+static void *
+usb_intr (void *arg)
+{
+ extern void usb_lld_init (uint8_t feature);
+ extern void usb_interrupt_handler (void);
+
+ chopstx_intr_t interrupt;
+
+ (void)arg;
+ chopstx_claim_irq (&interrupt, INTR_REQ_USB);
+ usb_lld_init (0x80); /* Bus powered. */
+
+ while (1)
+ {
+ chopstx_intr_wait (&interrupt);
+
+ /* Process interrupt. */
+ usb_interrupt_handler ();
+ }
+
+ chopstx_release_irq (&interrupt);
+ return NULL;
+}
+
+#if defined(BUSY_LOOP)
+#define PRIO_PWM (CHOPSTX_SCHED_RR|1)
+#define PRIO_BLK (CHOPSTX_SCHED_RR|1)
+#else
+#define PRIO_PWM 3
+#define PRIO_BLK 2
+#endif
+#define PRIO_INTR 4
+
+extern uint8_t __process1_stack_base__, __process1_stack_size__;
+extern uint8_t __process2_stack_base__, __process2_stack_size__;
+extern uint8_t __process3_stack_base__, __process3_stack_size__;
+
+const uint32_t __stackaddr_pwm = (uint32_t)&__process1_stack_base__;
+const size_t __stacksize_pwm = (size_t)&__process1_stack_size__;
+
+const uint32_t __stackaddr_blk = (uint32_t)&__process2_stack_base__;
+const size_t __stacksize_blk = (size_t)&__process2_stack_size__;
+
+const uint32_t __stackaddr_intr = (uint32_t)&__process3_stack_base__;
+const size_t __stacksize_intr = (size_t)&__process3_stack_size__;
+
+
+static char hexchar (uint8_t x)
+{
+ if (x <= 0x09)
+ return '0' + x;
+ else if (x <= 0x0f)
+ return 'a' + x - 10;
+ else
+ return '?';
+}
+
+int
+main (int argc, const char *argv[])
+{
+ struct stream *st;
+ uint8_t count;
+ extern uint32_t bDeviceState;
+
+ (void)argc;
+ (void)argv;
+
+ chopstx_mutex_init (&mtx);
+ chopstx_cond_init (&cnd0);
+ chopstx_cond_init (&cnd1);
+
+ st = stream_open ();
+
+ m = 10;
+
+ chopstx_create (PRIO_PWM, __stackaddr_pwm, __stacksize_pwm, pwm, NULL);
+ chopstx_create (PRIO_BLK, __stackaddr_blk, __stacksize_blk, blk, NULL);
+ chopstx_create (PRIO_INTR, __stackaddr_intr, __stacksize_intr,
+ usb_intr, NULL);
+
+ chopstx_usec_wait (200*1000);
+
+ chopstx_mutex_lock (&mtx);
+ chopstx_cond_signal (&cnd0);
+ chopstx_cond_signal (&cnd1);
+ chopstx_mutex_unlock (&mtx);
+
+ u = 1;
+ while (bDeviceState != CONFIGURED)
+ chopstx_usec_wait (500*1000);
+
+ count = 0;
+ while (1)
+ {
+ uint8_t s[64];
+
+ if (stream_wait_connection (st) < 0)
+ {
+ chopstx_usec_wait (1000*1000);
+ continue;
+ }
+
+ chopstx_usec_wait (500*1000);
+
+ /* Send ZLP at the beginning. */
+ stream_send (st, s, 0);
+
+ memcpy (s, "xx: Hello, World with Chopstx!\r\n\000", 32);
+ s[0] = hexchar (count >> 4);
+ s[1] = hexchar (count & 0x0f);
+ count++;
+
+ if (stream_send (st, s, 32) < 0)
+ continue;
+
+ while (1)
+ {
+ int size = stream_recv (st, s);
+
+ if (size < 0)
+ break;
+
+ if (size >= 0)
+ {
+ if (stream_send (st, s, size) < 0)
+ break;
+ }
+
+ u ^= 1;
+ }
+ }
+
+ return 0;
+}